| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
That looks like the kind of diff I'd expect, given that type checkers don't support these ABCs at all. I think it's a net win:
|
Sorry, something went wrong.
There was a problem hiding this comment.
Thanks, this is a good step forward.
However, we can probably do a bit better by using protocols that support a few more common unary dunder methods that exist on common number classes: __abs__ and others.
Also, I don't think we can realistically annotate the parameters to binary dunder methods on these classes. You'd think that say Integral.__add__ should accept any other Integral, but that's impossible to implement in a concrete class (how would it know to add itself to any other Integral that might exist somewhere?) and inherently an LSP violation, because Integral is a subclass of Complex, and Complex.__add__ should allow any complex numbers. So I endorse keeping parameter annotations out of this PR.
Sorry, something went wrong.
Okay, I've had a go! Let's see what primer says... |
Sorry, something went wrong.
|
That last commit made the typing a lot more complex, didn't change the primer output at all, and broke our test cases for unittest.TestCase.assertAlmostEqual. I'm inclined to just revert it, and merge the PR as it was before that commit? |
Sorry, something went wrong.
This reverts commit 687709c.
Everything I tried locally seemed to break either our test cases for pow or our test cases for unittest.TestCase.assertAlmostEqual. I've gone ahead and reverted the last commit for now, but I'd be happy if somebody managed to find a way to improve the types even more after this PR :) |
Sorry, something went wrong.
|
Diff from mypy_primer, showing the effect of this PR on open source code: steam.py (https://github.com/Gobot1234/steam.py)
- steam/ext/tf2/currency.py:100: note: Superclass:
- steam/ext/tf2/currency.py:100: note: @overload
- steam/ext/tf2/currency.py:100: note: def __sub__(a, int | Fraction, /) -> Fraction
- steam/ext/tf2/currency.py:100: note: @overload
- steam/ext/tf2/currency.py:100: note: def __sub__(a, float, /) -> float
- steam/ext/tf2/currency.py:100: note: @overload
- steam/ext/tf2/currency.py:100: note: def __sub__(a, complex, /) -> complex
- steam/ext/tf2/currency.py:100: note: Subclass:
- steam/ext/tf2/currency.py:100: note: def __sub__(self, int | str | float | Fraction | Decimal, /) -> Metal
pytest (https://github.com/pytest-dev/pytest)
+ src/_pytest/python_api.py:400: error: Unused "type: ignore" comment [unused-ignore]
+ src/_pytest/python_api.py:444: error: Unused "type: ignore" comment [unused-ignore]
+ src/_pytest/python_api.py:445: error: Unused "type: ignore" comment [unused-ignore]
+ src/_pytest/python_api.py:453: error: Unused "type: ignore" comment [unused-ignore]
+ src/_pytest/python_api.py:457: error: Argument 1 to "abs" has incompatible type "SupportsComplex"; expected "SupportsAbs[Never]" [arg-type]
ibis (https://github.com/ibis-project/ibis)
+ ibis/util.py:168: error: Unsupported left operand type for < (Never) [operator]
+ ibis/util.py:168: error: Argument 1 to "abs" has incompatible type "SupportsComplex"; expected "SupportsAbs[Never]" [arg-type]
- ibis/common/temporal.py:184: error: Incompatible return value type (got "int", expected "timedelta") [return-value]
- ibis/common/temporal.py:184: error: Argument 1 to "int" has incompatible type "timedelta | Real"; expected "str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc" [arg-type]
+ ibis/common/temporal.py:184: error: No overload variant of "int" matches argument type "timedelta | Real" [call-overload]
+ ibis/common/temporal.py:184: note: Possible overload variants:
+ ibis/common/temporal.py:184: note: def __new__(cls, str | Buffer | SupportsInt | SupportsIndex | SupportsTrunc = ..., /) -> int
+ ibis/common/temporal.py:184: note: def __new__(cls, str | bytes | bytearray, /, base: SupportsIndex) -> int
|
Sorry, something went wrong.
| Back | FazBrowse Home | New Git URL |
This PR represents a compromise between what the numbers module was supposed to be, and the reality of where we are today with Python's typing system.
This module is supposed to provide a framework of ABCs that would allow for third-party implementations of Complex, Rational, Real and Integral numbers. As such, the annotations we should be giving to the Real class should be something like this:
Unfortunately, that doesn't work! The reason is that fractions.Fraction inherits from numbers.Real, and it overrides these abstract methods to provide concrete implementations. The concrete implementations return concrete types such as int, which type checkers don't recognise as subtypes of Real (because the numbers module has never been supported by static type checkers, and never will be):
typeshed/stdlib/fractions.pyi
Lines 105 to 106 in 547cbc7
As such, for every method I tried adding types to according to the above strategy, mypy emitted an error warning me that fractions.Fraction incompatibly overrode numbers.Real. (There were also similar errors for a numbers.Real subclass in our Pillow stubs.)
Instead of returning Complex from methods that really should be returning Complex, therefore, this PR annotates those methods as returning SupportsComplex. SupportsComplex works pretty well here:
In a similar way, I've annotated methods that should be returning numbers.Integral as returning SupportsIndex, and I've annotated methods that should be returning numbers.Real as returning SupportsFloat.
I haven't attempted to add any new argument annotations as part of this PR. The return annotations were hard enough.