@@ -2758,6 +2758,7 @@ def static_func(arg: int) -> str:
27582758 """My function docstring"""
27592759 return str (arg )
27602760
2761+ prefix = A .__qualname__ + '.'
27612762 for meth in (
27622763 A .func ,
27632764 A ().func ,
@@ -2767,6 +2768,7 @@ def static_func(arg: int) -> str:
27672768 A ().static_func
27682769 ):
27692770 with self .subTest (meth = meth ):
2771+ self .assertEqual (meth .__qualname__ , prefix + meth .__name__ )
27702772 self .assertEqual (meth .__doc__ ,
27712773 ('My function docstring'
27722774 if support .HAVE_DOCSTRINGS
@@ -3077,6 +3079,115 @@ def _(arg: typing.List[float] | bytes):
30773079 self .assertEqual (f ("" ), "default" )
30783080 self .assertEqual (f (b"" ), "default" )
30793081
3082+ def test_method_equal_instances (self ):
3083+ # gh-127750: Reference to self was cached
3084+ class A :
3085+ def __eq__ (self , other ):
3086+ return True
3087+ def __hash__ (self ):
3088+ return 1
3089+ @functools .singledispatchmethod
3090+ def t (self , arg ):
3091+ return self
3092+
3093+ a = A ()
3094+ b = A ()
3095+ self .assertIs (a .t (1 ), a )
3096+ self .assertIs (b .t (2 ), b )
3097+
3098+ def test_method_bad_hash (self ):
3099+ class A :
3100+ def __eq__ (self , other ):
3101+ raise AssertionError
3102+ def __hash__ (self ):
3103+ raise AssertionError
3104+ @functools .singledispatchmethod
3105+ def t (self , arg ):
3106+ pass
3107+
3108+ # Should not raise
3109+ A ().t (1 )
3110+ hash (A ().t )
3111+ A ().t == A ().t
3112+
3113+ def test_method_no_reference_loops (self ):
3114+ # gh-127750: Created a strong reference to self
3115+ class A :
3116+ @functools .singledispatchmethod
3117+ def t (self , arg ):
3118+ return weakref .ref (self )
3119+
3120+ a = A ()
3121+ r = a .t (1 )
3122+ self .assertIsNotNone (r ())
3123+ del a # delete a after a.t
3124+ if not support .check_impl_detail (cpython = True ):
3125+ support .gc_collect ()
3126+ self .assertIsNone (r ())
3127+
3128+ a = A ()
3129+ t = a .t
3130+ del a # delete a before a.t
3131+ support .gc_collect ()
3132+ r = t (1 )
3133+ self .assertIsNotNone (r ())
3134+ del t
3135+ if not support .check_impl_detail (cpython = True ):
3136+ support .gc_collect ()
3137+ self .assertIsNone (r ())
3138+
3139+ def test_signatures (self ):
3140+ @functools .singledispatch
3141+ def func (item , arg : int ) -> str :
3142+ return str (item )
3143+ @func .register
3144+ def _ (item : int , arg : bytes ) -> str :
3145+ return str (item )
3146+
3147+ self .assertEqual (str (Signature .from_callable (func )),
3148+ '(item, arg: int) -> str' )
3149+
3150+ def test_method_signatures (self ):
3151+ class A :
3152+ def m (self , item , arg : int ) -> str :
3153+ return str (item )
3154+ @classmethod
3155+ def cm (cls , item , arg : int ) -> str :
3156+ return str (item )
3157+ @functools .singledispatchmethod
3158+ def func (self , item , arg : int ) -> str :
3159+ return str (item )
3160+ @func .register
3161+ def _ (self , item , arg : bytes ) -> str :
3162+ return str (item )
3163+
3164+ @functools .singledispatchmethod
3165+ @classmethod
3166+ def cls_func (cls , item , arg : int ) -> str :
3167+ return str (arg )
3168+ @func .register
3169+ @classmethod
3170+ def _ (cls , item , arg : bytes ) -> str :
3171+ return str (item )
3172+
3173+ @functools .singledispatchmethod
3174+ @staticmethod
3175+ def static_func (item , arg : int ) -> str :
3176+ return str (arg )
3177+ @func .register
3178+ @staticmethod
3179+ def _ (item , arg : bytes ) -> str :
3180+ return str (item )
3181+
3182+ self .assertEqual (str (Signature .from_callable (A .func )),
3183+ '(self, item, arg: int) -> str' )
3184+ self .assertEqual (str (Signature .from_callable (A ().func )),
3185+ '(self, item, arg: int) -> str' )
3186+ self .assertEqual (str (Signature .from_callable (A .cls_func )),
3187+ '(cls, item, arg: int) -> str' )
3188+ self .assertEqual (str (Signature .from_callable (A .static_func )),
3189+ '(item, arg: int) -> str' )
3190+
30803191
30813192class CachedCostItem :
30823193 _cost = 1
0 commit comments