Skip to content

pytype hangs on alias from another module inside class #612

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
srittau opened this issue Jun 26, 2020 · 8 comments
Closed

pytype hangs on alias from another module inside class #612

srittau opened this issue Jun 26, 2020 · 8 comments
Assignees
Labels

Comments

@srittau
Copy link
Contributor

srittau commented Jun 26, 2020

Please consider the following stub file:

import unittest.mock

class MockFixture:
    Mock = unittest.mock.Mock

When checking this with pytype (2020.06.01), pytype hangs indefinitely, while consuming 100% CPU time.

@rchen152
Copy link
Contributor

I believe we currently only allow aliases inside a class to another member of the same class, due to some parser limitations. But the parser usually prints a sensible error message instead of hanging forever, so at the least that should be fixed.

@srittau
Copy link
Contributor Author

srittau commented Jun 26, 2020

I discovered this limitation while working on python/typeshed#4275. One temporary solution would be if pytype would just treating those aliases as Any. This would allow type stubs with those aliases to work at least. But I am not sure how complex this would be to implement. This discussion is probably out of scope for this issue, though.

@rchen152
Copy link
Contributor

Rewriting

class Foo:
  Alias = SomeType

as

from typing import Type
class Foo:
  Alias: Type[SomeType]

seems to work. (which leads to the question: could pytype just automatically do this rewrite behind the scenes?)

@JelleZijlstra
Copy link
Contributor

Not sure if pytype has more permissive rules around Type, but I don't think that would fix all issues in pytest_mock. MockFixture.mock_open is a function, for example (an alias of unittest.mock.mock_open), and I don't think you're allowed to Type[] a function.

@Akuli
Copy link

Akuli commented Jul 24, 2020

I ran into possibly the same problem with a class from the same module. Minimal repro (.pyi file)

class Foo:
    def meth(self) -> None: ...

class Bar:
    meth = Foo.meth

When trying to resolve this aliasing, pytype gets stuck into this infinite while loop in pytype/pyi/parser.py:

        while isinstance(val, pytd.Alias):
          if isinstance(val.type, pytd.NamedType):
            _, _, base_name = val.type.name.rpartition(".")
            if base_name in vals_dict:
              val = vals_dict[base_name]
              continue
          raise ParseError(
              "Illegal value for alias %r. Value must be an attribute "
              "on the same class." % val.name)

I haven't tried to figure out what this loop is supposed to do yet so I don't know how to fix this.

Being able to do this kind of aliasing would allow me to get rid of some copy/pasta in stub files that I'm currently working on.

@rchen152
Copy link
Contributor

Thanks for tracking that down! I think I'll try just putting in a type of Any when a loop is detected - beats hanging forever.

@Akuli
Copy link

Akuli commented Jul 24, 2020

What is currently the preferred way to say "Bar.meth has the same arguments and return types as Foo.meth"? This doesn't seem to work:

class Foo:
    def meth(self) -> None: ...

class Bar:
    meth: Type[Foo.meth]

Edit: If the Any workaround will be released in a few days then nevermind.

rchen152 added a commit that referenced this issue Jul 24, 2020
We can't resolve these properly, but for some reason people have been trying to
use them a lot in typeshed recently, so let's set these aliases to Any for now.

For #612.

PiperOrigin-RevId: 323060647
@rchen152
Copy link
Contributor

pytype 2020.07.24 contains a workaround that allows arbitrary aliases as class attributes; let me know if something isn't working.

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