Skip to content

Fix type inference on get_dataframe#69

Closed
damonbayer wants to merge 8 commits into
CDCgov:mainfrom
damonbayer:dmb_type_check
Closed

Fix type inference on get_dataframe#69
damonbayer wants to merge 8 commits into
CDCgov:mainfrom
damonbayer:dmb_type_check

Conversation

@damonbayer

@damonbayer damonbayer commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Closes #68.

This is appears to work, but is entirely llm-authored in an area where I lack expertise. Merge with caution.

LLM Explanation

The changes in catalog.py are only about giving the dynamic datacat tree a usable static type, without changing how it behaves at runtime.

First, I added CatalogNamespace in catalog.py (line 90). Before this, every intermediate node in datacat was just a SimpleNamespace, which static analyzers treat as basically unstructured. CatalogNamespace still inherits from SimpleNamespace, so runtime behavior stays the same, but inside TYPE_CHECKING it declares that names like load, extract, data, and _ledger_endpoint are BlobEndpoint, and that arbitrary deeper attributes are more CatalogNamespace via getattr. That is what lets a chain like datacat.public.stf.nhsn_hrd_prelim.load stay typed instead of collapsing to Any.

Second, I added type-only endpoint attributes on DatasetEndpoint in catalog.py (line 117). At runtime the class was already attaching .load, .extract, and similar attributes in init, but statically those attributes did not exist on the class definition. Declaring them under TYPE_CHECKING tells editors that a dataset endpoint really does have those stage attributes and that each one is a BlobEndpoint.

Third, I changed dict_to_sn() to return CatalogNamespace instead of SimpleNamespace in catalog.py (line 744), and changed the implementation to instantiate CatalogNamespace in catalog.py (line 757). That matters because this helper is what recursively builds the whole exported namespace tree. If it returned SimpleNamespace, the typing information would still be lost immediately.

Finally, I annotated the exported datacat and reportcat objects as CatalogNamespace in catalog.py (line 800). That makes the public export itself typed at the point where it is created, so when users import datacat, the checker sees a recursive typed namespace rather than an untyped SimpleNamespace.

So the net effect is:

intermediate namespace nodes are statically typed
dataset nodes are statically typed as having .load/.extract
.load resolves to BlobEndpoint
once .load is known to be BlobEndpoint, the existing get_dataframe() overloads work as intended for "lazy" and "pl_lazy" as polars.LazyFrame
Runtime API shape is unchanged; this is purely a static typing improvement layered onto the existing dynamic construction.

@ryanraaschCDC

Copy link
Copy Markdown
Collaborator

I'll check this out!

Comment thread cfa/dataops/catalog.py Outdated
@ryanraaschCDC

Copy link
Copy Markdown
Collaborator

this seems to be working for me. It should be good to merge after pulling in the current main branch of cfa-dataops

@ryanraaschCDC

Copy link
Copy Markdown
Collaborator

this problem was fixed in the related PR: #98

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.

Type hints aren't resolved correctly

3 participants