@@ -14,7 +14,7 @@ use crate::{
14
14
bytecode,
15
15
class:: PyClassImpl ,
16
16
frame:: Frame ,
17
- function:: { FuncArgs , OptionalArg , PyComparisonValue } ,
17
+ function:: { FuncArgs , OptionalArg , PyComparisonValue , PySetterValue } ,
18
18
scope:: Scope ,
19
19
types:: { Callable , Comparable , Constructor , GetAttr , GetDescriptor , PyComparisonOp } ,
20
20
AsObject , Context , Py , PyObject , PyObjectRef , PyPayload , PyRef , PyResult , VirtualMachine ,
@@ -31,6 +31,7 @@ pub struct PyFunction {
31
31
closure : Option < PyTupleTyped < PyCellRef > > ,
32
32
defaults_and_kwdefaults : PyMutex < ( Option < PyTupleRef > , Option < PyDictRef > ) > ,
33
33
name : PyMutex < PyStrRef > ,
34
+ qualname : PyMutex < PyStrRef > ,
34
35
#[ cfg( feature = "jit" ) ]
35
36
jitted_code : OnceCell < CompiledCode > ,
36
37
}
@@ -42,6 +43,7 @@ impl PyFunction {
42
43
closure : Option < PyTupleTyped < PyCellRef > > ,
43
44
defaults : Option < PyTupleRef > ,
44
45
kw_only_defaults : Option < PyDictRef > ,
46
+ qualname : PyMutex < PyStrRef > ,
45
47
) -> Self {
46
48
let name = PyMutex :: new ( code. obj_name . to_owned ( ) ) ;
47
49
PyFunction {
@@ -50,6 +52,7 @@ impl PyFunction {
50
52
closure,
51
53
defaults_and_kwdefaults : PyMutex :: new ( ( defaults, kw_only_defaults) ) ,
52
54
name,
55
+ qualname,
53
56
#[ cfg( feature = "jit" ) ]
54
57
jitted_code : OnceCell :: new ( ) ,
55
58
}
@@ -380,6 +383,32 @@ impl PyFunction {
380
383
* self . name . lock ( ) = name;
381
384
}
382
385
386
+ #[ pygetset( magic) ]
387
+ fn qualname ( & self ) -> PyStrRef {
388
+ self . qualname . lock ( ) . clone ( )
389
+ }
390
+
391
+ #[ pygetset( magic, setter) ]
392
+ fn set_qualname ( & self , value : PySetterValue , vm : & VirtualMachine ) -> PyResult < ( ) > {
393
+ match value {
394
+ PySetterValue :: Assign ( value) => {
395
+ if let Ok ( qualname) = value. downcast :: < PyStr > ( ) {
396
+ * self . qualname . lock ( ) = qualname;
397
+ } else {
398
+ return Err ( vm. new_type_error (
399
+ "__qualname__ must be set to a string object" . to_string ( ) ,
400
+ ) ) ;
401
+ }
402
+ }
403
+ PySetterValue :: Delete => {
404
+ return Err (
405
+ vm. new_type_error ( "__qualname__ must be set to a string object" . to_string ( ) )
406
+ ) ;
407
+ }
408
+ }
409
+ Ok ( ( ) )
410
+ }
411
+
383
412
#[ pymethod( magic) ]
384
413
fn repr ( zelf : PyRef < Self > , vm : & VirtualMachine ) -> String {
385
414
let qualname = zelf
0 commit comments