Skip to content
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

Metaclass related internal error #28

Closed
arnimarj opened this issue Jan 26, 2021 · 11 comments · Fixed by #29
Closed

Metaclass related internal error #28

arnimarj opened this issue Jan 26, 2021 · 11 comments · Fixed by #29

Comments

@arnimarj
Copy link
Contributor

arnimarj commented Jan 26, 2021

Hi,

We just ran into this stacktrace:

https://mypy.rtfd.io/en/latest/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.800
Traceback (most recent call last):
  File "mypy/semanal.py", line 4835, in accept
  File "mypy/nodes.py", line 950, in accept
  File "mypy/semanal.py", line 1048, in visit_class_def
  File "mypy/semanal.py", line 1125, in analyze_class
  File "mypy/semanal.py", line 1134, in analyze_class_body_common
  File "mypy/semanal.py", line 1187, in apply_class_plugin_hooks
  File "/home/travis/virtualenv/python3.8.1/lib/python3.8/site-packages/mypy_zope/plugin.py", line 266, in analyze_metaclass
    if info and any(node.fullname == expected for node in info.mro):
AttributeError: 'Var' object has no attribute 'mro'

I haven't had time find exactly which piece of code is causing this, but will do so as soon as I can.

EDIT: this was tested on mypy 0.800. The line which hit this was something like this:

@attr.s(slots=True, frozen=True)
class Leg(metaclass=CustomMetaclass):
	a: str = attr.ib()
	b: str = attr.ib()
	c: str = attr.ib()
@arnimarj
Copy link
Contributor Author

arnimarj commented Jan 26, 2021

I modified get_metaclass_hook to be:

    def get_metaclass_hook(
        self, fullname: str
    ) -> Optional[Callable[[ClassDefContext], None]]:
        def analyze_metaclass(ctx: ClassDefContext) -> None:
            metaclass = cast(NameExpr, ctx.cls.metaclass)

            if isinstance(metaclass.node, Var):
                return

            info = cast(TypeInfo, metaclass.node)
            expected = "zope.interface.interface.InterfaceClass"
            if info and any(node.fullname == expected for node in info.mro):
                self.log(f"Found zope interface: {ctx.cls.fullname}")
                md = self._get_metadata(ctx.cls.info)
                md["is_interface"] = True

        return analyze_metaclass

...after looking at analyze_metaclass in MyPy. There is a short-circuit along the lines of:

            if isinstance(sym.node, Var) and isinstance(get_proper_type(sym.node.type), AnyType):
                # 'Any' metaclass -- just ignore it.
                #
                # TODO: A better approach would be to record this information
                #       and assume that the type object supports arbitrary
                #       attributes, similar to an 'Any' base class.
                return

That made the error go away

@kedder
Copy link
Member

kedder commented Jan 26, 2021

Yeah, these casts in front of analyze_metaclass are not right. I'll try a more correct approach there, let me make a branch to test it.

@arnimarj
Copy link
Contributor Author

I've got a small test-case:

from i.dont.exist import MetaKlass


class Leg(metaclass=MetaKlass):
	pass

I believe mypy gives you a Var node when the metaclass has not been resolved

@kedder
Copy link
Member

kedder commented Jan 26, 2021

Oh, thanks, I can add a test too then!

@arnimarj
Copy link
Contributor Author

my mypy.ini:

[mypy]
scripts_are_modules = True
show_traceback = True
disallow_any_generics = True
warn_no_return = True
no_implicit_optional = True
ignore_missing_imports = True
namespace_packages = True
plugins = mypy_zope:plugin

And the run:

$ PYTHONPATH=$(pwd) mypy --show-traceback --show-error-codes --config mypy.ini z.py 
z.py:4: error: INTERNAL ERROR -- Please try using mypy master on Github:
https://mypy.rtfd.io/en/latest/common_issues.html#using-a-development-mypy-build
Please report a bug at https://github.com/python/mypy/issues
version: 0.800
Traceback (most recent call last):
  File "mypy/semanal.py", line 4835, in accept
  File "mypy/nodes.py", line 950, in accept
  File "mypy/semanal.py", line 1048, in visit_class_def
  File "mypy/semanal.py", line 1125, in analyze_class
  File "mypy/semanal.py", line 1134, in analyze_class_body_common
  File "mypy/semanal.py", line 1187, in apply_class_plugin_hooks
  File "/home/arni/.config/dohop/tools_venv3/lib/python3.8/site-packages/mypy_zope/plugin.py", line 270, in analyze_metaclass
    if info and any(node.fullname == expected for node in info.mro):
AttributeError: 'Var' object has no attribute 'mro'
z.py:4: : note: use --pdb to drop into pdb

kedder added a commit that referenced this issue Jan 26, 2021
@kedder
Copy link
Member

kedder commented Jan 26, 2021

@arnimarj, the fix is in #29. I think it should solve this issue.

kedder added a commit that referenced this issue Jan 26, 2021
@arnimarj
Copy link
Contributor Author

@arnimarj, the fix is in #29. I think it should solve this issue.

The issue seems to be gone. Thanks for the great turnaround speed.

kedder added a commit that referenced this issue Jan 26, 2021
@kedder
Copy link
Member

kedder commented Jan 26, 2021

Do you want a new release with this fix?

@arnimarj
Copy link
Contributor Author

Do you want a new release with this fix?

Yes please :)

@kedder
Copy link
Member

kedder commented Jan 27, 2021

0.2.10 is released

@arnimarj
Copy link
Contributor Author

0.2.10 is released

Thanks. We hit this bug in our regression tests, so a new release helps.

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

Successfully merging a pull request may close this issue.

2 participants