-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Stub for fractions #94
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
Done, thank you @matthiaskramm |
Hmm, I don't really know how to deal with the first error:
Perhaps it is necessary to change the stub of Regarding the second error:
It is pretty obvious that the stub for the |
Yes, that's a good place for it. The Python 2 and Python 3 versions don't seem to differ much. Feel free to just mark the Python 3 specific sections with comments. Once mypy has support for version conditionals we can do the proper
|
I don't quite get your comment. Do you mean that I should comment out the following code? if sys.version_info[0] >= 3:
def floor(self) -> int: ...
def ceil(self) -> int: ...
@overload
def __round__(self) -> int: ...
@overload
def __round__(self, ndigits: int) -> Fraction: ... If that is the case, the stub would not be checked at all, am I wrong? |
Re: the signature of
Regarding the |
I've merged your decimal backport; can you rebase and clean up? |
Yeah, just waiting for that. |
Please, don't merge. There are missing properties of |
OK, I'm waiting. |
Should the stub also declare types for methods like |
Regarding def __add__(self, other: Fraction) -> Fraction: ... Because it actually supports other numbers too. So you'll have to write something like
This is unfortunate because it means that type-checking expressions involving Fractions is not very precise. We could add overloads but it would get pretty verbose... E.g.
but I'm not even sure if mypy currently support that -- please try it out with some real code. Thanks for bringing it up! |
What about something like: NumberType = TypeVar('T', Fraction, numbers.Real, numbers.Complex)
class Fraction(numbers.Rational):
...
def __add__(self, other: NumberType) -> NumberType: ... The rationale is that |
Yes, that sounds right!
|
I don't quite get why mypy complains. |
I think you're running into something that's unsupported currently by mypy. @JukkaL can you shed your light on this issue? The key problem seems to be that the base class defines e.g.
and in a subclass we'd like to override this so that mypy understands that adding two Fractions returns a Fraction, but that adding a Fraction to a Number returns a Number (which is a superclass of Fraction). Maybe also connected to #1237? |
Hmm... mypy may be confused by the type variable in an operator method signature. Anyway, mypy is probably too eager in the overlapping check, as it guards against a pretty theoretical source of unsafety. I'll need to look into the code to figure out what's going on. Other comments: Should |
Probably yes, but I preferred to keep the numbers hierarchy ( However, I think that the most accurate solution would be to have two types: ForwardOpNumberT = TypeVar('ForwardOpNumberT', int, Fraction, float, complex)
ReverseOpNumberT = TypeVar('ReverseOpNumberT', numbers.Rational, numbers.Real, numbers.Complex) for the forward and reverse operations like Should I just go with |
If |
Tried with the following: class Fraction(numbers.Rational):
...
@overload
def __add__(self, other: Union[int, Fraction]) -> Fraction: ...
@overload
def __add__(self, other: float) -> float: ...
@overload
def __add__(self, other: complex) -> complex: ...
@overload
def __radd__(self, other: numbers.Rational) -> Fraction: ...
@overload
def __radd__(self, other: numbers.Real) -> float: ...
@overload
def __radd__(self, other: numbers.Complex) -> complex: ... Mypy still complains:
Therefore no, |
I looked in to this. This simplified fragment reproduces the issue:
Mypy is complaining about this because the base classes don't have function annotations, though it perhaps shouldn't complain. However, simply adding annotations may not be sufficient. I'll see if I can give these reasonable types without generating errors. |
@JukkaL Is there a bug in the mypy tracker for this yet? If so could you link to it? If not could you create one? (I feel out of my depth here myself.) |
Because of the current overlapping checks mypy probably can't represent this without giving errors. We'll probably have to make the overlapping checks more lenient, but I'm not sure what's the best way to do it yet. Operator overloading is a tricky area and requires careful thought. I'll create an issue for this in the mypy issue tracker. |
Create issue python/mypy#1264. |
I was trying to create the stub for the Python 3.4
statistics
module, but it depends on thefractions
module.So here is my attempt for the
fractions
module, any suggestion accepted.