bintoro / overloading.py

Function overloading for Python 3
MIT License
112 stars 10 forks source link

Failed to overload instance method in Python 3.6 #7

Open kylemart opened 7 years ago

kylemart commented 7 years ago

EDIT: Just realized your test suite doesn't cover Python 3.6.X.

I don't have this issue when using Python 3.4.3, but when using Python 3.6.3 I receive OverloadErrors when providing overrides for class instance methods.

Here's a case that gives me an error in the newer version of Python:

Python 3.6.3 (default, Oct  5 2017, 19:38:03) 
[GCC 4.2.1 Compatible Apple LLVM 7.0.0 (clang-700.0.72)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> from overloading import overload
>>> class Test:
...     @overload
...     def m(self, n : int):
...         return n + 1
...     @overload
...     def m(self, n1 : int, n2 : int):
...         return n1 + n2
... 
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/overloading.py", line 63, in overload
    return register(__registry[fname], func)
KeyError: '__main__.Test.m'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 3, in Test
  File "/usr/local/lib/python3.6/site-packages/overloading.py", line 65, in overload
    __registry[fname] = overloaded(func)
  File "/usr/local/lib/python3.6/site-packages/overloading.py", line 151, in overloaded
    return register(dispatcher, func)
  File "/usr/local/lib/python3.6/site-packages/overloading.py", line 205, in register
    .format(dp.__name__, signature.parameters[i]))
overloading.OverloadingError: Failed to overload function 'm': parameter 'self' has an annotation that is not a type.

What's going on?

thouger commented 6 years ago

I have same question like this.The version is python3.6.3.

from typing import Iterable

from overloading import overload

@overload
def biggest(items: Iterable[int]):
    return max(items)

@overload
def biggest(items: Iterable[str]):
    return max(items, key=len)

print(biggest(['a', 'abc', 'bc']))

Then i got:

Traceback (most recent call last):
  File "C:/Users/Ryan/Desktop/thouger/code_python/test.py", line 10, in <module>
    def biggest(items: int):
  File "C:\Users\Ryan\Desktop\thouger\Anaconda3\lib\site-packages\overloading.py", line 63, in overload
    return register(__registry[fname], func)
  File "C:\Users\Ryan\Desktop\thouger\Anaconda3\lib\site-packages\overloading.py", line 211, in register
    .format(dp.__name__, str.join(', ', (_repr(t) for t in dup_sig))))
overloading.OverloadingError: Failed to overload function 'biggest': non-unique signature (<class 'int'>).

When i put:

from collections import Iterable

from overloading import overload

@overload
def biggest(items: Iterable[int]):
    return max(items)

@overload
def biggest(items: Iterable[str]):
    return max(items, key=len)

print(biggest(['a', 'abc', 'bc']))

I got:

Traceback (most recent call last):
  File "C:/Users/Ryan/Desktop/thouger/code_python/test.py", line 6, in <module>
    def biggest(items: Iterable[int]):
TypeError: 'ABCMeta' object is not subscriptable

I think it is useless in python 3.6 and above.

pcko1 commented 4 years ago

Same problem here, python 3.6.

Is there a fix?