You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
ex.py:7: note: Revealed type is "builtins.dict[Any, Any]"
ex.py:7: note: Revealed type is "ex.<subclass of "dict" and "str">"
ex.py:8: error: Incompatible return value type (got "Dict[<nothing>, <nothing>]", expected "str") [return-value]
ex.py:10: note: Revealed type is "builtins.str"
Looks like Revealed type is "ex.<subclass of "dict" and "str">" should not ever happen.
» mypy ex.py --show-traceback
ex.py:7: note: Revealed type is "builtins.dict[Any, Any]"
ex.py:10: note: Revealed type is "builtins.int"
Success: no issues found in 1 source file
So, let's find why the intersection of two instances is created in the first place 🤔
.intersect_instances
This happens, because self.intersect_instances((v, t), ctx) works this way:
Intersecting: builtins.int builtins.dict[Any, Any]
Result: None
Intersecting: builtins.str builtins.dict[Any, Any]
Result: ex.<subclass of "dict" and "str">
I am not sure if this is related but I wanted to add another data point on 0.991
@classmethoddeffrom_df(cls, df: pd.DataFrame|pd.Series) ->"Sites":
ifisinstance(df, pd.Series):
returncls.from_sitemap(cast(SiteDict, df.to_dict()))
assertisinstance(df, pd.DataFrame) # for mypy type failuredf.rename({df.columns[0]: "name"}, axis=1, inplace=True)
Error:
error: No overload variant of "rename" of "Series" matches argument types "Dict[Union[str, bytes, date, timedelta, int, float, complex, Any], str]", "int", "bool" [call-overload]
df.rename({df.columns[0]: "name"}, axis=1, inplace=True)
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Without the assert isinstance(df, pd.DataFrame) # for mypy type failure Mypy falsely warns that Series.rename does not have the proper overload, but df should already be narrowed to a pd.DataFrame by that point. Pylance/pyright gets it right.
Are we sure the initial report reveals a bug or is this behaviour by design? If I am right, we can consider it only a bug if the order of the type variable constraints matters. Then Mypy should behave as follows:
fromtypingimportTypeVarclassA: ...
classB: v=1classC(A, B): ...
T1=TypeVar("T1", A, B)
deff1(x: T1) ->T1:
ifisinstance(x, A):
returnA() # no errorreturnB()
T2=TypeVar("T2", B, A)
deff2(x: T2) ->T2:
ifisinstance(x, A):
returnA() # error: Incompatible return value type (got "A", expected "B") [return-value]returnB()
f1(C()).v# error: "A" has no attribute "v" [attr-defined]f2(C()).v
Are there any promises that Mypy or other type checkers prioritise the first over the second type variable constraint when estimating return types in the context of multiple inheritance?
If we agree that order matters (and if I do not miss other potential problems here), adjusting Mypy should be manageable with reasonable effort.
It seems to be a known issue. I found the following test case (added by @Michael0x2a):
[casetestIsInstanceAdHocIntersectionGenericsWithValuesDirectReturn]
# flags: --warn-unreachablefromtypingimportTypeVarclassA:
attr: intclassB:
attr: intclassC:
attr: strT1=TypeVar('T1', A, B)
deff1(x: T1) ->T1:
ifisinstance(x, A):
# The error message is confusing, but we indeed do run into problems if# 'x' is a subclass of A and BreturnA() # E: Incompatible return value type (got "A", expected "B")else:
returnB()
T2=TypeVar('T2', B, C)
deff2(x: T2) ->T2:
ifisinstance(x, B):
# In contrast, it's impossible for a subclass of "B" and "C" to# exist, so this is finereturnB()
else:
returnC()
[builtinsfixtures/isinstance.pyi]
Activity
hauntsaninja commentedon Oct 3, 2022
Interesting,
mypy_primer -p ~/dev/mypy_primer/test.py --bisect --new v0.981 --old v0.971 --debugbisects this to #13386hauntsaninja commentedon Oct 3, 2022
Looks like it's from python/typeshed#8465, cc @sobolevn
sobolevn commentedon Oct 3, 2022
Very strange 😨
How can
__hash__affect this?hauntsaninja commentedon Oct 3, 2022
Yeah, it's pretty strange, but it's true. Fixes itself on master if you add
__hash__back to float. These dunders...sobolevn commentedon Oct 3, 2022
It does not feel right. It looks like it exposes some other bug. I will have a look.
sobolevn commentedon Oct 4, 2022
So, I am diving into it.
First of all, I was able to reproduce this problem.
Secondly, this works:
Also,
setandlistwork.But,
floatandstrdoes not work.At this point I am sure that this is a bug.
Revealed types
Let's reveal types:
Output:
Looks like
Revealed type is "ex.<subclass of "dict" and "str">"should not ever happen.What about types that do work?
Outputs:
So, let's find why the intersection of two instances is created in the first place 🤔
.intersect_instancesThis happens, because
self.intersect_instances((v, t), ctx)works this way:headtr1ck commentedon Oct 29, 2022
Possibly related: #13956
Even though this fails also for previous mypy versions.
emirkmo commentedon Nov 24, 2022
I am not sure if this is related but I wanted to add another data point on 0.991
Error:
Without the
assert isinstance(df, pd.DataFrame) # for mypy type failureMypy falsely warns thatSeries.renamedoes not have the proper overload, butdfshould already be narrowed to apd.DataFrameby that point. Pylance/pyright gets it right.Environment:
mypy 0.991 (compiled: yes)
Python 3.10.6
Options:
--allow-redefinition --allow-untyped-globals --ignore-missing-imports --implicit-reexport --enable-incomplete-feature=Unpacktyralla commentedon Jan 3, 2023
Are we sure the initial report reveals a bug or is this behaviour by design? If I am right, we can consider it only a bug if the order of the type variable constraints matters. Then Mypy should behave as follows:
Are there any promises that Mypy or other type checkers prioritise the first over the second type variable constraint when estimating return types in the context of multiple inheritance?
If we agree that order matters (and if I do not miss other potential problems here), adjusting Mypy should be manageable with reasonable effort.
tyralla commentedon Jan 4, 2023
It seems to be a known issue. I found the following test case (added by @Michael0x2a):
Avoid false "Incompatible return value type" errors when dealing with…
Revert "Remove un-needed `__hash__` methods from `stdlib` (#8465)" (#…