plum icon indicating copy to clipboard operation
plum copied to clipboard

Crash When Method Argument Type Contains "Self"

Open Talbe1 opened this issue 10 months ago • 0 comments

I have to note that the code crashes also for a method that has List[Self] as the type of one of its arguments, but it doesn't when specifying a type say a List. But my testing is not thorough.

I would like to know why this happens, is this due to a mistake in my code?

Python version:

Python 3.9.13 (tags/v3.9.13:6de2ca5, May 17 2022, 16:36:42) [MSC v.1929 64 bit (AMD64)] on win32

This is my code in which I experience the crash:

from typing_extensions import Self
from plum import dispatch

class Test:
    def __init__(self, val: str):
        self._test_val = val

    @dispatch
    def test(self, val: int):
        print(val)

    @dispatch
    def test(self, val: str):
        print("Overloaded! As str:", val)

    @dispatch
    def test(self, val: Self, val_two: int):
        print(f"Overloaded! {val}, {val_two}")


if __name__ == "__main__":
    obj = Test("1")

    obj.test(1)
    obj.test(obj, 2) # Crash
    obj.test("1")

The exception that was raised:

Traceback (most recent call last):
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\function.py", line 405, in _resolve_method_with_cache
    return self._cache[types]
KeyError: (<class '__main__.Test'>, <class '__main__.Test'>, <class 'int'>)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\main.py", line 25, in <module>
    obj.test(obj, 2) # Crash
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\function.py", line 509, in __call__
    return self._f(self._instance, *args, **kw_args)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\function.py", line 382, in __call__
    method, return_type = self._resolve_method_with_cache(args=args)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\function.py", line 413, in _resolve_method_with_cache
    method, return_type = self.resolve_method(args)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\function.py", line 315, in resolve_method
    method = self._resolver.resolve(target)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\resolver.py", line 355, in resolve
    for method in [m for m in self.methods if check(m)]:
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\resolver.py", line 355, in <listcomp>
    for method in [m for m in self.methods if check(m)]:
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\resolver.py", line 346, in check
    return m.signature.match(target)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\signature.py", line 251, in match
    return all(_is_bearable(v, t) for v, t in zip(values, types))
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\plum\signature.py", line 251, in <genexpr>
    return all(_is_bearable(v, t) for v, t in zip(values, types))
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\door\_func\doorcheck.py", line 236, in is_bearable
    func_tester = make_func_tester(hint, conf)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_util\cache\utilcachecall.py", line 249, in _callable_cached
    raise exception
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_util\cache\utilcachecall.py", line 241, in _callable_cached
    return_value = args_flat_to_return_value[args_flat] = func(
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\checkmake.py", line 189, in make_func_tester
    return _make_func_checker(  # type: ignore[return-value]
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\checkmake.py", line 807, in _make_func_checker
    reraise_exception_placeholder(
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_util\error\utilerrraise.py", line 137, in reraise_exception_placeholder
    raise exception.with_traceback(exception.__traceback__)
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\checkmake.py", line 659, in _make_func_checker
    hint_or_sane = sanify_hint_root_statement(
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\convert\convsanify.py", line 294, in sanify_hint_root_statement
    hint_or_sane = reduce_hint(
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\convert\_reduce\redhint.py", line 376, in reduce_hint
    hint = _reduce_hint_uncached(
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\convert\_reduce\redhint.py", line 620, in _reduce_hint_uncached
    hint = hint_reducer(
  File "C:\Users\talba\Documents\Coding_Projects\Python\My Own\testing\.venv\lib\site-packages\beartype\_check\convert\_reduce\_pep\redpep673.py", line 84, in reduce_hint_pep673
    raise BeartypeDecorHintPep673Exception(
beartype.roar.BeartypeDecorHintPep673Exception: Is_bearable() PEP 673 type hint "typing_extensions.Self" invalid outside @beartype-decorated class. PEP 673 type hints are valid only inside classes decorated by @beartype. If this hint annotates a method decorated by @beartype, instead decorate the class declaring this method by @beartype: e.g.,

    # Instead of decorating methods by @beartype like this...
    class BadClassIsBad(object):
        @beartype
        def awful_method_is_awful(self: Self) -> Self:
            return self

    # ...decorate classes by @beartype instead - like this!
    @beartype
    class GoodClassIsGood(object):
        def wonderful_method_is_wonderful(self: Self) -> Self:
            return self

This has been a message of the Bearhugger Broadcasting Service.

Talbe1 avatar Apr 17 '25 12:04 Talbe1