-
-
Notifications
You must be signed in to change notification settings - Fork 397
Description
Problem description
For context, some passthrough methods on SolutionArray are only available for specific phases. The way I devised to constrain this was to make SolutionArray generic in the underlying phase object type, and then restrict those methods to only be valid when the type of self matches the specific phase type. For example:
@property
def net_production_rates(self: SolutionArray[Kinetics]) -> Array: ...However, this doesn't seem to properly match against subclasses as I expected:
This error was picked up by my type checkers, as well.
Behavior
My expectation was that the type SolutionArray[Solution] would match against self: SolutionArray[Kinetics] as Solution is a subclass of Kinetics. I thought this worked as expected during my testing while implementing it (see this comment), although it's possible I only tested the negative case (SolutionArray[Solution] does not match against SolutionArray[Interface]) and not the positive case.
System information
- Cantera version: 3.2.0
- OS: RHEL 9
- Python/MATLAB/other software versions: Python 3.13, mypy 1.18.2, basedpyright 1.33.0, pyright 1.1.407
Additional context
I believe the mistake is that, by default, generics are invariant. The fix may thus be as simple as changing
# Generic representing a valid "phase" input
_P = TypeVar("_P", bound=_SolutionBase)to
# Generic representing a valid "phase" input
_P = TypeVar("_P", bound=_SolutionBase, covariant=True)in composite.pyi, but I haven't tested this yet.
See: https://typing.python.org/en/latest/reference/generics.html#variance-of-generic-types