Skip to content

AttributeError: 'UnionType' object has no attribute 'type' when overloaded arithmetic operation has Union[float, Fraction] type #4581

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
elias6 opened this issue Feb 16, 2018 · 3 comments
Labels

Comments

@elias6
Copy link
Contributor

elias6 commented Feb 16, 2018

I have a file with the following code:

from fractions import Fraction
from typing import Union

class Thing:
    def __radd__(self, other: Union[float, Fraction]) -> int:
        return 0

I ran it through Mypy and got an error message saying to run it with --show-traceback. I did that and got the following output:

fraction_test.py:5: error: INTERNAL ERROR -- please report a bug at https://github.com/python/mypy/issues version: 0.570-dev-c25dd085a78047a9d5e0909261e8261506505d35
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.6/bin/mypy", line 11, in <module>
    load_entry_point('mypy===0.570-dev-c25dd085a78047a9d5e0909261e8261506505d35', 'console_scripts', 'mypy')()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/__main__.py", line 7, in console_entry
    main(None)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/main.py", line 80, in main
    type_check_only(sources, bin_dir, options, flush_errors)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/main.py", line 129, in type_check_only
    flush_errors=flush_errors)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/build.py", line 180, in build
    result = _build(sources, options, alt_lib_path, bin_dir, saved_cache, flush_errors)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/build.py", line 266, in _build
    graph = dispatch(sources, manager)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/build.py", line 2112, in dispatch
    process_graph(graph, manager)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/build.py", line 2413, in process_graph
    process_stale_scc(graph, scc, manager)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/build.py", line 2597, in process_stale_scc
    graph[id].type_check_first_pass()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/build.py", line 1969, in type_check_first_pass
    self.type_checker().check_first_pass()
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 229, in check_first_pass
    self.accept(d)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 324, in accept
    stmt.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/nodes.py", line 704, in accept
    return visitor.visit_class_def(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 1252, in visit_class_def
    self.accept(defn.defs)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 324, in accept
    stmt.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/nodes.py", line 766, in accept
    return visitor.visit_block(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 1395, in visit_block
    self.accept(s)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 324, in accept
    stmt.accept(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/nodes.py", line 501, in accept
    return visitor.visit_func_def(self)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 576, in visit_func_def
    self.check_func_item(defn, name=defn.name())
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 641, in check_func_item
    self.check_func_def(defn, typ, name)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 691, in check_func_def
    self.check_reverse_op_method(item, typ, name, defn)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 926, in check_reverse_op_method
    defn)
  File "/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/site-packages/mypy/checker.py", line 996, in check_overlapping_op_methods
    forward_base.type.name(), forward_name, context)
AttributeError: 'UnionType' object has no attribute 'type'
fraction_test.py:5: : note: use --pdb to drop into pdb

This seems to have something to do with overloading the swapped binary arithmetic operations. If I change the method name to __rsub__ or __rmul__, I get a similar error, but with __add__ or __sub__ or nonsense names like __foo__, I don't get any errors.

If I change the type hint for other to simply float or Fraction, I get no errors.

If I change the return type hint to str or List (and make the method return something that matches that type), I get similar errors. But if I remove the return type hint, I get no errors.

If I move the method outside of the class (making it a regular function), I get a similar error. Such a thing may be silly, but I don't see why it should be invalid.

@JelleZijlstra
Copy link
Member

Confirmed on master (0.570-dev-c25dd085a78047a9d5e0909261e8261506505d35). This is definitely a bug; mypy shouldn't crash on any code.

@gvanrossum
Copy link
Member

Hm, it's easy enough to avoid the crash by checking various things for None before using them, but it feels like there is something more fundamentally wrong.

Also it's weird that the reverse operator code is still invoked if the method is moved out of a class.

@ilevkivskyi
Copy link
Member

I think this is a duplicate of #3468

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