Skip to content

Conversation

@ducky64
Copy link
Collaborator

@ducky64 ducky64 commented Nov 28, 2025

Adds default type parameters to generics to allow most code to work while the "default" generic class is a base class of sorts. This makes a lot of type parameters covariant.

The exception is Vector, which allows mutable elements, and remains invariant. BaseVector (non-parameterized) serves as the base class.

This also properly parameterizes the StandardFootprint type, so the block type in the lambdas are checked. HasStandardFootprint also now requires a StandardFootprint type-parameterzed on Self. To avoid circular dependencies, the _STANDARD_FOOTPRINT can be a lambda.

This uses typing_extensions for TypeVar defaults and Self for earlier version of Python.

Also removes OrderedDict and ABCMeta and the IR type parameter for Block.

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR enables stricter type checking by adding default type parameters to generic classes and making appropriate type parameters covariant. The changes improve type safety while maintaining backward compatibility through default parameter values.

Key changes:

  • Adds typing_extensions >= 4.4.0 requirement for TypeVar defaults and Self type support
  • Enables mypy's disallow_any_generics strict type checking
  • Refactors StandardFootprint to use proper generic typing with Self type
  • Removes legacy patterns (OrderedDict, ABCMeta, IR type parameter)

Reviewed changes

Copilot reviewed 50 out of 50 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
pyproject.toml Updates typing_extensions version requirement and enables strict generic typing
edg/core/*.py Adds default type parameters to core generics (TypeVars, BaseBlock, Link, Block)
edg/electronics_model/*.py Parameterizes circuit-related generics and updates type annotations
edg/abstract_parts/StandardFootprint.py Refactors to use Self type and adds lambda wrapper for circular dependencies
edg/abstract_parts/*.py Updates component classes to use lambda wrapper for _STANDARD_FOOTPRINT and moves footprint definitions after component classes
edg/jlcparts/*.py Adds RootModel type parameters for Pydantic models
examples/*.py Adds type parameters to csv.DictWriter
Comments suppressed due to low confidence (1)

edg/abstract_parts/StandardFootprint.py:27

  • Variable name mismatch in assertion message. The f-string references pinning_footprint (singular) but should reference pinning_footprints (plural) which is the actual variable being checked.
          assert pinning_footprints not in footprint_map, f"duplicate footprint entry {pinning_footprint}"

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +144 to +147
PortTransformsType = Mapping[Type[Port], Tuple[Type[Port], Callable[[Port], Port]]]
DefaultPortTransforms: PortTransformsType = {
DigitalSource: (DigitalBidir, DigitalSource.from_bidir),
DigitalSink: (DigitalBidir, DigitalSink.from_bidir),
DigitalSource: (DigitalBidir, DigitalSource.from_bidir), # type: ignore
DigitalSink: (DigitalBidir, DigitalSink.from_bidir), # type: ignore
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

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

The type: ignore comments suggest the type annotation for PortTransformsType may not accurately match the actual values. Consider whether the Callable type parameter should be more general (e.g., Callable[..., Port]) or if the dictionary values need adjustment to match the stricter type definition.

Copilot uses AI. Check for mistakes.
Comment on lines +316 to +323
def map_extract(self, selector: Callable[[VectorType], Union[ConstraintExpr, ExtractPortType]]) -> Union[ArrayExpr, DerivedVector[ExtractPortType]]:
param = selector(self._elt_sample)
if isinstance(param, ConstraintExpr): # TODO check that returned type is child
return ArrayExpr.array_of_elt(param)._bind(MapExtractBinding(self, param))
elif isinstance(param, BasePort):
elif isinstance(param, Port):
return DerivedVector(self, param)
else:
raise EdgTypeError(f"selector return", param, (ConstraintExpr, BasePort))
raise EdgTypeError(f"selector return", param, (ConstraintExpr, Port))
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

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

The type check on line 320 uses Port but the error message on line 323 also mentions Port. However, the union type at line 316 uses BasePort in the EdgTypeError elsewhere (see removed line). The isinstance check should be consistent with the type annotation - if the selector can return BasePort, the check should be isinstance(param, BasePort) not isinstance(param, Port).

Copilot uses AI. Check for mistakes.


@non_library
class TableFerriteBead(PartsTableSelector, FerriteBead):
Copy link

Copilot AI Nov 28, 2025

Choose a reason for hiding this comment

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

The _STANDARD_FOOTPRINT assignment that was previously at line 70 has been removed. This appears to be an unintended deletion rather than a deliberate change, as other similar table classes retain their footprint assignments. Verify if this is intentional or if it should inherit the lambda from the parent FerriteBead class.

Suggested change
class TableFerriteBead(PartsTableSelector, FerriteBead):
class TableFerriteBead(PartsTableSelector, FerriteBead):
_STANDARD_FOOTPRINT = lambda: FerriteBeadStandardFootprint

Copilot uses AI. Check for mistakes.
@ducky64 ducky64 merged commit ddd8f11 into master Nov 28, 2025
12 checks passed
@ducky64 ducky64 deleted the typed-generics branch November 28, 2025 00:30
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