SupportsRound[int] hinted functions work with floats if round is called with no additional args
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 20.6k
- Forks
- 3.3k
- PR merge metrics
- PR metrics pending
Description
Note: if you are reporting a wrong signature of a function or a class in
the standard library, then the typeshed tracker is better suited
for this report: https://github.com/python/typeshed/issues
this genuinely might be a typeshed issue i'm not 100% sure. To be sure some similar issues about __round__ have cropped up both here and in typeshed:
#6211
python/typeshed#2638
If maintainers think this is solely a typeshed issue and would like me to repost over there please just let me know. If it is a typeshed issue and is a regression ( which it may be) then perhaps I could help by adding a test somewhere?
Are you reporting a bug, or opening a feature request?
possible bug
Example:
import typing
def round_it(x: typing.SupportsRound[int]) -> int:
return round(x)
round_it(3.2)
What is the actual behavior/output?
though round is called with no ndigits arg in the example above we still get the following error when running mypy:
scratch.py:11: error: Argument 1 to "round_it" has incompatible type "float"; expected "SupportsRound[int]"
scratch.py:11: note: Following member(s) of "float" have conflicts:
scratch.py:11: note: Expected:
scratch.py:11: note: @overload
scratch.py:11: note: def __round__(self) -> int
scratch.py:11: note: @overload
scratch.py:11: note: def __round__(self, ndigits: int) -> int
scratch.py:11: note: Got:
scratch.py:11: note: @overload
scratch.py:11: note: def __round__(self, ndigits: None = ...) -> int
scratch.py:11: note: @overload
scratch.py:11: note: def __round__(self, ndigits: int) -> float
note that even if I modify this bit of typeshed to include :
@overload
def __round__(self, ndigits: None = ...) -> int: ...
I still have the same issue ( just with <1 more overload not shown>, etc)
What is the behavior/output you expect?
since SupportsRound is parameterised by return type and I have called the round method with no extra args I would expect that the example provided above would pass.
Specifically :
given both float and SupportsRound[int] more or less share a signature for the def __round__(self) and round is called w/ no args. I would expect mypy to be able to interpret that we're using def __round__(self, ndigits: None = ...) -> int and not care about the conflicting overload since it's not called.
What are the versions of mypy and Python you are using?
python: 3.8.0
mypy: 0.761 (and master)
What are the mypy flags you are using?
I have tried running with each of the following flag sets :
- no flags
--strict--no-implicit-optional--no-strict-optional--strict-optional
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the provided scratch.py example with mypy 0.761 or master, then inspect the linked typeshed stdlib/2and3/builtins.pyi definition for round. Determine whether the mismatch belongs in mypy or typeshed, and compare the behavior with the related issues. Done means the ownership is confirmed and the expected round() call is covered by an appropriate test or handoff.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- python
- Domain
- devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100