@@ -2642,6 +2642,7 @@ def static_func(arg: int) -> str:
26422642 """My function docstring"""
26432643 return str (arg )
26442644
2645+ prefix = A .__qualname__ + '.'
26452646 for meth in (
26462647 A .func ,
26472648 A ().func ,
@@ -2651,6 +2652,7 @@ def static_func(arg: int) -> str:
26512652 A ().static_func
26522653 ):
26532654 with self .subTest (meth = meth ):
2655+ self .assertEqual (meth .__qualname__ , prefix + meth .__name__ )
26542656 self .assertEqual (meth .__doc__ ,
26552657 ('My function docstring'
26562658 if support .HAVE_DOCSTRINGS
@@ -2946,6 +2948,115 @@ def _(arg: typing.List[float] | bytes):
29462948 self .assertEqual (f ("" ), "default" )
29472949 self .assertEqual (f (b"" ), "default" )
29482950
2951+ def test_method_equal_instances (self ):
2952+ # gh-127750: Reference to self was cached
2953+ class A :
2954+ def __eq__ (self , other ):
2955+ return True
2956+ def __hash__ (self ):
2957+ return 1
2958+ @functools .singledispatchmethod
2959+ def t (self , arg ):
2960+ return self
2961+
2962+ a = A ()
2963+ b = A ()
2964+ self .assertIs (a .t (1 ), a )
2965+ self .assertIs (b .t (2 ), b )
2966+
2967+ def test_method_bad_hash (self ):
2968+ class A :
2969+ def __eq__ (self , other ):
2970+ raise AssertionError
2971+ def __hash__ (self ):
2972+ raise AssertionError
2973+ @functools .singledispatchmethod
2974+ def t (self , arg ):
2975+ pass
2976+
2977+ # Should not raise
2978+ A ().t (1 )
2979+ hash (A ().t )
2980+ A ().t == A ().t
2981+
2982+ def test_method_no_reference_loops (self ):
2983+ # gh-127750: Created a strong reference to self
2984+ class A :
2985+ @functools .singledispatchmethod
2986+ def t (self , arg ):
2987+ return weakref .ref (self )
2988+
2989+ a = A ()
2990+ r = a .t (1 )
2991+ self .assertIsNotNone (r ())
2992+ del a # delete a after a.t
2993+ if not support .check_impl_detail (cpython = True ):
2994+ support .gc_collect ()
2995+ self .assertIsNone (r ())
2996+
2997+ a = A ()
2998+ t = a .t
2999+ del a # delete a before a.t
3000+ support .gc_collect ()
3001+ r = t (1 )
3002+ self .assertIsNotNone (r ())
3003+ del t
3004+ if not support .check_impl_detail (cpython = True ):
3005+ support .gc_collect ()
3006+ self .assertIsNone (r ())
3007+
3008+ def test_signatures (self ):
3009+ @functools .singledispatch
3010+ def func (item , arg : int ) -> str :
3011+ return str (item )
3012+ @func .register
3013+ def _ (item : int , arg : bytes ) -> str :
3014+ return str (item )
3015+
3016+ self .assertEqual (str (Signature .from_callable (func )),
3017+ '(item, arg: int) -> str' )
3018+
3019+ def test_method_signatures (self ):
3020+ class A :
3021+ def m (self , item , arg : int ) -> str :
3022+ return str (item )
3023+ @classmethod
3024+ def cm (cls , item , arg : int ) -> str :
3025+ return str (item )
3026+ @functools .singledispatchmethod
3027+ def func (self , item , arg : int ) -> str :
3028+ return str (item )
3029+ @func .register
3030+ def _ (self , item , arg : bytes ) -> str :
3031+ return str (item )
3032+
3033+ @functools .singledispatchmethod
3034+ @classmethod
3035+ def cls_func (cls , item , arg : int ) -> str :
3036+ return str (arg )
3037+ @func .register
3038+ @classmethod
3039+ def _ (cls , item , arg : bytes ) -> str :
3040+ return str (item )
3041+
3042+ @functools .singledispatchmethod
3043+ @staticmethod
3044+ def static_func (item , arg : int ) -> str :
3045+ return str (arg )
3046+ @func .register
3047+ @staticmethod
3048+ def _ (item , arg : bytes ) -> str :
3049+ return str (item )
3050+
3051+ self .assertEqual (str (Signature .from_callable (A .func )),
3052+ '(self, item, arg: int) -> str' )
3053+ self .assertEqual (str (Signature .from_callable (A ().func )),
3054+ '(self, item, arg: int) -> str' )
3055+ self .assertEqual (str (Signature .from_callable (A .cls_func )),
3056+ '(cls, item, arg: int) -> str' )
3057+ self .assertEqual (str (Signature .from_callable (A .static_func )),
3058+ '(item, arg: int) -> str' )
3059+
29493060
29503061class CachedCostItem :
29513062 _cost = 1
0 commit comments