remove arg-type exclusion from mypy rules on schema_branch.py#9343
Conversation
| dependency_map: dict[str, set[str]] = defaultdict(set) | ||
| for name in self.generic_names_without_templates + self.node_names: | ||
| node_schema = self.get(name=name, duplicate=False) | ||
| assert isinstance(node_schema, NodeSchema | GenericSchema) |
There was a problem hiding this comment.
not sure if assert is better or a if not isinstance(...): continue
There was a problem hiding this comment.
I'd avoid assert in production code. We have it in a few places, but it can be excluded/ignored at runtime with environment variables.
There was a problem hiding this comment.
No issues found across 18 files
Confidence score: 5/5
- Automated review surfaced no issues in the provided summaries.
- No files require special attention.
Shadow auto-approve: would auto-approve. This PR primarily tightens types in schema_branch.py and updates test instantiations to pass a required name, with no changes to business logic or runtime behavior, making it a low-risk improvement to type safety.
Re-trigger cubic
Replace assertions with conditional checks for node schema types.
There was a problem hiding this comment.
1 issue found across 1 file (changes from recent commits).
Shadow auto-approve: would not auto-approve because issues were found.
Re-trigger cubic
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Shadow auto-approve: would auto-approve. These type-safety improvements enforce existing invariants and eliminate potential runtime errors, without changing behavior or relying on risky assumptions.
Re-trigger cubic
| return {"nodes": self.nodes, "generics": self.generics, "profiles": self.profiles, "templates": self.templates} | ||
|
|
||
| def to_dict_schema_object(self, duplicate: bool = False) -> dict[str, dict[str, MainSchemaTypes]]: | ||
| def to_dict_schema_object(self, duplicate: bool = False) -> dict[str, Any]: |
There was a problem hiding this comment.
I think this is fine as a way to correct things. But Looking at this method I also think that we could do a bit better. It looks like this should return a TypedDict where "name" is just a string and "nodes" is a dict[str, NodeSchema] etc. Would have to change the method so that we call something other than "self.get" for that to work.
There was a problem hiding this comment.
oh yeah. way better. added it.
| cache[node_hash] = node | ||
|
|
||
| return cls(cache=cache, data=nodes) | ||
| return cls(cache=cache, data=nodes, name=data.get("name", "Unknown")) |
There was a problem hiding this comment.
While I think this should be fine in general there's also the fact that "Unknown" is a perfectly fine name for a branch. I'm assuming that the data dict from here would match the one that's coming from .to_dict_schema_object() if that method returned a typeddict instead we should be fine to just access "name" directly.
| for name in self.generic_names_without_templates + self.node_names: | ||
| node_schema = self.get(name=name, duplicate=False) | ||
| if not isinstance(node_schema, NodeSchema | GenericSchema): | ||
| continue |
There was a problem hiding this comment.
Was this only for typing? Wondering if we should have some other method aside from self.get() which would return the expected types instead.
There was a problem hiding this comment.
yes. I added a get_node_or_generic_schema() method to cover this case and replaced the existing isinstance and asserts for those types with the new method
| for node_name in self.node_names + self.generic_names_without_templates: | ||
| node = self.get(name=node_name, duplicate=False) | ||
| if not isinstance(node, NodeSchema | GenericSchema): | ||
| continue |
There was a problem hiding this comment.
0 issues found across 1 file (changes from recent commits).
Shadow auto-approve: would require human review. This PR refactors critical schema business logic in schema_branch.py, making the name field required, altering to_dict_schema_object output, and adding new type dispatch—these changes affect core data structures and could introduce subtle bugs in schema validation, migration, and...
Re-trigger cubic
Summary
Removes
arg-typefrom the mypy override forinfrahub.core.schema.schema_branchand fixes all 20 hidden type errorsChanges
SchemaBranch.nameis now required__init__signature changed fromname: str | None = Nonetoname: str— every production call site already passed a name; only test fixtures were relying onthe default.
to_dict_schema_object()now carries"name"in the payload;from_dict_schema_object()reads it. This keeps round-tripping honest across the Pydanticvalidator/migration pipelines (
validators/model.py,validators/models/validate_migration.py,migrations/schema/models.py).duplicate(name=None)now falls back toself.nameinstead of producing a nameless copy.name="test".Type narrowing in
SchemaBranchmethodsself.get()calls with the existing typed helpersget_node()/get_generic()at 6 sites where the iteration source guarantees the kind._diff_node_or_generic()helper inSchemaBranch.diff()to dispatch by kind so each subclass'sdiff(other: Self)contract is satisfied withoutcast.assert isinstance(node, NodeSchema | GenericSchema)at two loops that iteratenode_names + generic_names_without_templates— the union return type wasstrictly wider than the iteration source.
generate_profile_from_node(node: NodeSchema)toNodeSchema | GenericSchema. The body only touchesBaseNodeSchemaattributes, and the calling looplegitimately invokes it for both kinds (both have
generate_profile).Guard against
Noneinadd_hierarchy_nodeWrapped the parent- and children-relationship blocks in
if parent_peer is not None:/if children_peer is not None:guards. Schema procession would make reaching this point impossible, but the typing does not make that clear.Summary by cubic
Make
SchemaBranch.namerequired and include it in schema serialization. Tightens typing acrossschema_branch.py, adds safe dispatch indiff(), and removes thearg-typemypy override.Refactors
SchemaBranch.__init__now requiresname: str; tests updated to passname="test".to_dict_schema_object()returnsSchemaBranchDictand writes"name";from_dict_schema_object()now requires it.SchemaBranchDictTypedDict.get_node_or_generic_schema(); replaced broadget()with typed getters (get_node/get_generic/get_profile/get_template) and_diff_node_or_generic()for type-safediff().generate_profile_from_node()acceptsNodeSchema | GenericSchema; replaced assertions with conditional checks.duplicate(name=None)falls back toself.name; removedarg-typefrom mypy overrides inpyproject.toml.Bug Fixes
add_hierarchy_nodeto skip creating parent/children relationships when peers areNone.Written for commit 71b0f01. Summary will update on new commits. Review in cubic