Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Wrong inference of the target of __new__ #9405

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

Closed
Hibou57 opened this issue Sep 3, 2020 · 6 comments
Closed

Wrong inference of the target of __new__ #9405

Hibou57 opened this issue Sep 3, 2020 · 6 comments
Labels

Comments

@Hibou57
Copy link

Hibou57 commented Sep 3, 2020

🐛 Bug Report

The target of an invocation of __new__ is an explicit class, but mypy erroneously believes it is another class.

To Reproduce

Create a file test.py with this content:

from typing import Any
class C(str):
    def __new__(cls, value: str) -> Any:
        return str.__new__(cls, value)

Then run mypy test.py

Side note # 1: this is a stripped down version to reproduce the issue, the original case has more real interest.
Side note # 2: __new__ should return C but the name C is not defined during class creation, so __new__ is declared to return Any, instead.

Expected Behavior

There should be no error, as one can check this way:

>>> import test
>>> s = test.C("abc")
# No exception raised
>>> type(s)
<class 'test.C'>

Actual Behavior

mypy complains:

test.py:4: error: Too many arguments for "__new__" of "object"
Found 1 error in 1 file (checked 1 source file)

It erroneously believes the target of __new__ is object while it is str

Your Environment

  • Mypy version used: mypy 0.782
  • Mypy command-line flags: none (just the file name)
  • Mypy configuration options from mypy.ini (and other config files): none (no config file)
  • Python version used: Python 3.8.2
@Hibou57 Hibou57 added the bug mypy got something wrong label Sep 3, 2020
@Hibou57 Hibou57 changed the title Wrong inference of the type of the target of __new__ Wrong inference of the target of __new__ Sep 3, 2020
@gvanrossum
Copy link
Member

I think this could actually be fixed in typeshed -- the problem seems to be that no __new__ method is declared for class str.

But another interpretation would be that we ought to automatically derive a signature for __new__ if one is given for __init__. That would not be a simple feature to add, and I suspect there's already some other issue open for it. (Maybe #5647 is related?)

@gvanrossum gvanrossum added feature and removed bug mypy got something wrong labels Sep 3, 2020
@Hibou57
Copy link
Author

Hibou57 commented Sep 3, 2020

I’m not good at Python insides, anyway, my understanding is that the two issues are not that much related. The other issue as I understand it, is about __new__ vs __init__ to infer the type returned by a class constructor (I agree __new__ is the reference for that).

I did not knew about typeshed, so just had a look: https://github.com/python/typeshed/blob/master/stdlib/2and3/builtins.pyi#L443

Indeed, no __new__ is defined. But I was believing the arguments to __new__ and __init__, except for cls and self, are typically the same. If I’m not too wrong, when no __new__ is defined, what about relying on __init__ to infer its expected arguments? In that case, __new__(cls, o: object) could be inferred and would match the invocation.

@Hibou57
Copy link
Author

Hibou57 commented Sep 6, 2020

That said, I wonder if the error is finally in typeshed: I believe that’s a __new__ which should be declared for str, not an __init__ (and if so, probably the same for others like int, float, bool). There seems to be no __init__ for str.

@gvanrossum
Copy link
Member

gvanrossum commented Sep 6, 2020 via email

@JelleZijlstra
Copy link
Member

We tried this before in python/typeshed#1352 and terrible things happened (see python/typeshed#1464). Perhaps the enum issue I found back then got solved some other way since then, though.

@AlexWaygood
Copy link
Member

Cannot be reproduced on mypy 0.800+

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants