Skip to content

feat: enforce keys in sources Base class#231

Open
nikbpetrov wants to merge 1 commit into
forecastingresearch:mainfrom
nikbpetrov:metadata-keys
Open

feat: enforce keys in sources Base class#231
nikbpetrov wants to merge 1 commit into
forecastingresearch:mainfrom
nikbpetrov:metadata-keys

Conversation

@nikbpetrov

@nikbpetrov nikbpetrov commented Jun 20, 2026

Copy link
Copy Markdown
Collaborator

while _allow_missing_metadata might seem a tad awkward, it actually helps preserve both tests as well as the ability to validate that a source's name value (e.g. in fred.py) actually exists in _metadata.py

Solves #205

Full pipeline test via the harness - all jobs deploy, run and achieve expected parity.

Summary by CodeRabbit

  • Bug Fixes
    • Strengthened source metadata validation at class-definition time, now requiring nullified_questions plus any source-specific required keys (e.g., ticker_renames).
    • Standardized exported metadata for ACLED, DBnomics, Infer, Manifold, and Metaculus to include nullified_questions.
    • Updated the FRED source to stop exposing nullified_questions as part of its class metadata.
  • Tests
    • Expanded coverage for missing metadata entries and required keys, and verified correct attribute population when requirements are satisfied.
    • Adjusted test stubs to explicitly control strictness where needed.

@houtanb

houtanb commented Jul 8, 2026

Copy link
Copy Markdown
Member

@CodeRabbit full review

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown
✅ Action performed

Full review finished.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

BaseSource now validates required metadata, including nullified_questions and source-specific keys, during subclass creation. Source metadata and declarations were updated, and tests cover missing metadata and successful attribute population.

Changes

Base source metadata validation

Layer / File(s) Summary
BaseSource metadata contract and validation
src/sources/_base.py
nullified_questions no longer has a default; additional_required_metadata_keys and _allow_missing_metadata control subclass validation, which raises TypeError for missing metadata entries or required keys.
Source metadata and declarations
src/sources/_metadata.py, src/sources/fred.py, src/sources/yfinance.py
nullified_questions: [] was added to five source metadata entries; FredSource drops its explicit attribute; YfinanceSource requires ticker_renames.
Validation test coverage
src/tests/test_base_source.py
Stub classes and class-definition tests cover missing metadata entries, missing required keys, and successful metadata attribute population.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Possibly related issues

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 13.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly reflects the main change: stricter key enforcement in the sources base class.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@houtanb
houtanb force-pushed the metadata-keys branch 2 times, most recently from bc49138 to c3a7f88 Compare July 9, 2026 19:41

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/tests/test_base_source.py (1)

132-154: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Mutable default class attributes flagged by Ruff (RUF012).

nullified_questions = [] and required_metadata_keys = {"ticker_renames"} are unannotated mutable class attribute defaults. Ruff's rule notes this can be resolved by explicitly annotating the variable with typing.ClassVar to indicate that it is intended to be shared across all instances, or using an immutable data type (e.g. a tuple instead of a list) for the default value. Since these test stubs won't be instantiated multiple times, the risk is negligible, but annotating (or using frozenset/tuple) would silence the lint warning consistently with how the base class likely declares these as ClassVar.

🧹 Example fix using ClassVar annotations
-            class _BadSpecific(BaseSource):
-                name = "fake_missing_specific"
-                source_type = SourceType.DATASET
-                required_metadata_keys = {"ticker_renames"}
+            class _BadSpecific(BaseSource):
+                name = "fake_missing_specific"
+                source_type = SourceType.DATASET
+                required_metadata_keys: ClassVar[set[str]] = {"ticker_renames"}

Also applies to: 155-180

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tests/test_base_source.py` around lines 132 - 154, The test stub in
test_missing_source_specific_required_key_raises uses mutable class defaults
that Ruff flags as RUF012. Update the inline _BadSpecific class inside the test
to make the shared intent explicit by annotating nullified_questions and
required_metadata_keys as ClassVar, or switch the defaults to immutable types
like tuple/frozenset. Keep the existing BaseSource and SOURCE_METADATA setup
unchanged; only adjust the class attribute declarations in the test stubs that
mirror BaseSource metadata.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/tests/test_base_source.py`:
- Around line 132-154: The test stub in
test_missing_source_specific_required_key_raises uses mutable class defaults
that Ruff flags as RUF012. Update the inline _BadSpecific class inside the test
to make the shared intent explicit by annotating nullified_questions and
required_metadata_keys as ClassVar, or switch the defaults to immutable types
like tuple/frozenset. Keep the existing BaseSource and SOURCE_METADATA setup
unchanged; only adjust the class attribute declarations in the test stubs that
mirror BaseSource metadata.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: f37b6e3a-8da3-46fb-98a8-3edc896a050f

📥 Commits

Reviewing files that changed from the base of the PR and between bc49138 and c3a7f88.

📒 Files selected for processing (5)
  • src/sources/_base.py
  • src/sources/_metadata.py
  • src/sources/fred.py
  • src/sources/yfinance.py
  • src/tests/test_base_source.py
💤 Files with no reviewable changes (1)
  • src/sources/fred.py
🚧 Files skipped from review as they are similar to previous changes (3)
  • src/sources/yfinance.py
  • src/sources/_metadata.py
  • src/sources/_base.py

@houtanb houtanb left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

small rename for clarity.

Also, commit message could be more clear; it looks like it was truncated relative to the PR title which is better

Comment thread src/sources/_base.py Outdated
while `_allow_missing_metadata` might seem a tad awkward, it actually helps preserve both tests as well as the ability to validate that a source's name value (e.g. in `fred.py`) actually exists in `_metadata.py`

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (1)
src/tests/test_base_source.py (1)

24-24: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Annotate intentional mutable class attributes with ClassVar.

Ruff reports RUF012 for these shared class-level list/set values. Add the appropriate ClassVar[...] annotations, or use immutable values where the base-class contract permits it.

Also applies to: 150-150, 173-173

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/tests/test_base_source.py` at line 24, Ruff RUF012 flags the shared
mutable class-level collections in the affected test base classes. Import
ClassVar from typing and annotate each referenced class attribute, including
nullified_questions and the attributes at the other reported locations, with the
appropriate ClassVar[list[...]] or ClassVar[set[...]] type; use immutable values
only where compatible with the base-class contract.

Source: Linters/SAST tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@src/tests/test_base_source.py`:
- Line 24: Ruff RUF012 flags the shared mutable class-level collections in the
affected test base classes. Import ClassVar from typing and annotate each
referenced class attribute, including nullified_questions and the attributes at
the other reported locations, with the appropriate ClassVar[list[...]] or
ClassVar[set[...]] type; use immutable values only where compatible with the
base-class contract.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: d55766d4-644e-466c-8f0c-bbec390d32bb

📥 Commits

Reviewing files that changed from the base of the PR and between c3a7f88 and d9a635f.

📒 Files selected for processing (5)
  • src/sources/_base.py
  • src/sources/_metadata.py
  • src/sources/fred.py
  • src/sources/yfinance.py
  • src/tests/test_base_source.py
💤 Files with no reviewable changes (1)
  • src/sources/fred.py
🚧 Files skipped from review as they are similar to previous changes (1)
  • src/sources/_metadata.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants