nac3artiq: allow class attribute access without init function
This commit is contained in:
parent
3b6a6f560f
commit
ad1b4f1b9b
40
nac3artiq/demo/support_class_attr_issue102.py
Normal file
40
nac3artiq/demo/support_class_attr_issue102.py
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
from min_artiq import *
|
||||||
|
from numpy import int32
|
||||||
|
|
||||||
|
|
||||||
|
@nac3
|
||||||
|
class Demo:
|
||||||
|
attr1: KernelInvariant[int32] = 2
|
||||||
|
attr2: int32 = 4
|
||||||
|
attr3: Kernel[int32]
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def __init__(self):
|
||||||
|
self.attr3 = 8
|
||||||
|
|
||||||
|
|
||||||
|
@nac3
|
||||||
|
class NAC3Devices:
|
||||||
|
core: KernelInvariant[Core]
|
||||||
|
attr4: KernelInvariant[int32] = 16
|
||||||
|
|
||||||
|
def __init__(self):
|
||||||
|
self.core = Core()
|
||||||
|
|
||||||
|
@kernel
|
||||||
|
def run(self):
|
||||||
|
Demo.attr1 # Supported
|
||||||
|
# Demo.attr2 # Field not accessible on Kernel
|
||||||
|
# Demo.attr3 # Only attributes can be accessed in this way
|
||||||
|
# Demo.attr1 = 2 # Attributes are immutable
|
||||||
|
|
||||||
|
self.attr4 # Attributes can be accessed within class
|
||||||
|
|
||||||
|
obj = Demo()
|
||||||
|
obj.attr1 # Attributes can be accessed by class objects
|
||||||
|
|
||||||
|
NAC3Devices.attr4 # Attributes accessible for classes without __init__
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
NAC3Devices().run()
|
@ -627,7 +627,9 @@ impl InnerResolver {
|
|||||||
let pyid_to_def = self.pyid_to_def.read();
|
let pyid_to_def = self.pyid_to_def.read();
|
||||||
let constructor_ty = pyid_to_def.get(&py_obj_id).and_then(|def_id| {
|
let constructor_ty = pyid_to_def.get(&py_obj_id).and_then(|def_id| {
|
||||||
defs.iter().find_map(|def| {
|
defs.iter().find_map(|def| {
|
||||||
if let TopLevelDef::Class { object_id, methods, constructor, .. } = &*def.read() {
|
if let Some(rear_guard) = def.try_read() {
|
||||||
|
if let TopLevelDef::Class { object_id, methods, constructor, .. } = &*rear_guard
|
||||||
|
{
|
||||||
if object_id == def_id
|
if object_id == def_id
|
||||||
&& constructor.is_some()
|
&& constructor.is_some()
|
||||||
&& methods.iter().any(|(s, _, _)| s == &"__init__".into())
|
&& methods.iter().any(|(s, _, _)| s == &"__init__".into())
|
||||||
@ -635,6 +637,7 @@ impl InnerResolver {
|
|||||||
return *constructor;
|
return *constructor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
None
|
None
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -664,7 +667,29 @@ impl InnerResolver {
|
|||||||
primitives,
|
primitives,
|
||||||
)? {
|
)? {
|
||||||
Ok(s) => s,
|
Ok(s) => s,
|
||||||
Err(e) => return Ok(Err(e)),
|
Err(e) => {
|
||||||
|
// Allow access to Class Attributes of Classes without having to initialize Objects
|
||||||
|
if self.pyid_to_def.read().contains_key(&py_obj_id) {
|
||||||
|
if let Some(def_id) = self.pyid_to_def.read().get(&py_obj_id).copied() {
|
||||||
|
let def = defs[def_id.0].read();
|
||||||
|
let TopLevelDef::Class { object_id, .. } = &*def else {
|
||||||
|
// only object is supported, functions are not supported
|
||||||
|
unreachable!("function type is not supported, should not be queried")
|
||||||
|
};
|
||||||
|
|
||||||
|
let ty = TypeEnum::TObj {
|
||||||
|
obj_id: *object_id,
|
||||||
|
params: VarMap::new(),
|
||||||
|
fields: HashMap::new(),
|
||||||
|
};
|
||||||
|
(unifier.add_ty(ty), true)
|
||||||
|
} else {
|
||||||
|
return Ok(Err(e));
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return Ok(Err(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
};
|
};
|
||||||
match (&*unifier.get_ty(extracted_ty), inst_check) {
|
match (&*unifier.get_ty(extracted_ty), inst_check) {
|
||||||
// do the instantiation for these four types
|
// do the instantiation for these four types
|
||||||
|
Loading…
Reference in New Issue
Block a user