artiq: Update to pyo3 v0.21

With the extensive use of as_gil_ref. Will have to refactor those away
as well.
This commit is contained in:
David Mak 2024-07-05 12:54:15 +08:00
parent 5e2e77a500
commit 19d183ed84
4 changed files with 108 additions and 84 deletions

View File

@ -10,7 +10,7 @@ crate-type = ["cdylib"]
[dependencies] [dependencies]
itertools = "0.13" itertools = "0.13"
pyo3 = { version = "0.21", features = ["extension-module", "gil-refs"] } pyo3 = { version = "0.21", features = ["extension-module"] }
parking_lot = "0.12" parking_lot = "0.12"
tempfile = "3.10" tempfile = "3.10"
nac3core = { path = "../nac3core" } nac3core = { path = "../nac3core" }

View File

@ -26,8 +26,8 @@ use nac3core::inkwell::{
}; };
use pyo3::{ use pyo3::{
prelude::*,
types::{PyDict, PyList}, types::{PyDict, PyList},
PyObject, PyResult, Python,
}; };
use crate::{symbol_resolver::InnerResolver, timeline::TimeFns}; use crate::{symbol_resolver::InnerResolver, timeline::TimeFns};
@ -970,7 +970,7 @@ pub fn attributes_writeback(
host_attributes: &PyObject, host_attributes: &PyObject,
) -> Result<(), String> { ) -> Result<(), String> {
Python::with_gil(|py| -> PyResult<Result<(), String>> { Python::with_gil(|py| -> PyResult<Result<(), String>> {
let host_attributes: &PyList = host_attributes.downcast(py)?; let host_attributes = host_attributes.downcast_bound::<PyList>(py)?;
let top_levels = ctx.top_level.definitions.read(); let top_levels = ctx.top_level.definitions.read();
let globals = inner_resolver.global_value_ids.read(); let globals = inner_resolver.global_value_ids.read();
let int32 = ctx.ctx.i32_type(); let int32 = ctx.ctx.i32_type();
@ -978,10 +978,10 @@ pub fn attributes_writeback(
let mut values = Vec::new(); let mut values = Vec::new();
let mut scratch_buffer = Vec::new(); let mut scratch_buffer = Vec::new();
for val in (*globals).values() { for val in (*globals).values() {
let val = val.as_ref(py); let val = val.bind_borrowed(py);
let ty = inner_resolver.get_obj_type( let ty = inner_resolver.get_obj_type(
py, py,
val, val.as_gil_ref(),
&mut ctx.unifier, &mut ctx.unifier,
&top_levels, &top_levels,
&ctx.primitives, &ctx.primitives,
@ -997,7 +997,9 @@ pub fn attributes_writeback(
// we only care about primitive attributes // we only care about primitive attributes
// for non-primitive attributes, they should be in another global // for non-primitive attributes, they should be in another global
let mut attributes = Vec::new(); let mut attributes = Vec::new();
let obj = inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap(); let obj = inner_resolver
.get_obj_value(py, val.as_gil_ref(), ctx, generator, ty)?
.unwrap();
for (name, (field_ty, is_mutable)) in fields { for (name, (field_ty, is_mutable)) in fields {
if !is_mutable { if !is_mutable {
continue; continue;
@ -1016,7 +1018,7 @@ pub fn attributes_writeback(
} }
} }
if !attributes.is_empty() { if !attributes.is_empty() {
let pydict = PyDict::new(py); let pydict = PyDict::new_bound(py);
pydict.set_item("obj", val)?; pydict.set_item("obj", val)?;
pydict.set_item("fields", attributes)?; pydict.set_item("fields", attributes)?;
host_attributes.append(pydict)?; host_attributes.append(pydict)?;
@ -1026,12 +1028,14 @@ pub fn attributes_writeback(
let elem_ty = iter_type_vars(params).next().unwrap().ty; let elem_ty = iter_type_vars(params).next().unwrap().ty;
if gen_rpc_tag(ctx, elem_ty, &mut scratch_buffer).is_ok() { if gen_rpc_tag(ctx, elem_ty, &mut scratch_buffer).is_ok() {
let pydict = PyDict::new(py); let pydict = PyDict::new_bound(py);
pydict.set_item("obj", val)?; pydict.set_item("obj", val)?;
host_attributes.append(pydict)?; host_attributes.append(pydict)?;
values.push(( values.push((
ty, ty,
inner_resolver.get_obj_value(py, val, ctx, generator, ty)?.unwrap(), inner_resolver
.get_obj_value(py, val.as_gil_ref(), ctx, generator, ty)?
.unwrap(),
)); ));
} }
} }

View File

@ -40,9 +40,11 @@ use nac3core::nac3parser::{
}; };
use nac3core::toplevel::builtins::get_exn_constructor; use nac3core::toplevel::builtins::get_exn_constructor;
use nac3core::typecheck::typedef::{into_var_map, TypeEnum, Unifier, VarMap}; use nac3core::typecheck::typedef::{into_var_map, TypeEnum, Unifier, VarMap};
use pyo3::create_exception; use pyo3::{
use pyo3::prelude::*; create_exception, exceptions,
use pyo3::{exceptions, types::PyBytes, types::PyDict, types::PySet}; prelude::*,
types::{PyBytes, PyDict, PySet},
};
use parking_lot::{Mutex, RwLock}; use parking_lot::{Mutex, RwLock};
@ -174,7 +176,7 @@ impl Nac3 {
// Drop unregistered (i.e. host-only) base classes. // Drop unregistered (i.e. host-only) base classes.
bases.retain(|base| { bases.retain(|base| {
Python::with_gil(|py| -> PyResult<bool> { Python::with_gil(|py| -> PyResult<bool> {
let id_fn = PyModule::import(py, "builtins")?.getattr("id")?; let id_fn = PyModule::import_bound(py, "builtins")?.getattr("id")?;
match &base.node { match &base.node {
ExprKind::Name { id, .. } => { ExprKind::Name { id, .. } => {
if *id == "Exception".into() { if *id == "Exception".into() {
@ -361,10 +363,10 @@ impl Nac3 {
fn compile_method<T>( fn compile_method<T>(
&self, &self,
obj: &PyAny, obj: &Bound<PyAny>,
method_name: &str, method_name: &str,
args: Vec<&PyAny>, args: Vec<&PyAny>,
embedding_map: &PyAny, embedding_map: &Bound<PyAny>,
py: Python, py: Python,
link_fn: &dyn Fn(&Module) -> PyResult<T>, link_fn: &dyn Fn(&Module) -> PyResult<T>,
) -> PyResult<T> { ) -> PyResult<T> {
@ -376,8 +378,8 @@ impl Nac3 {
size_t, size_t,
); );
let builtins = PyModule::import(py, "builtins")?; let builtins = PyModule::import_bound(py, "builtins")?;
let typings = PyModule::import(py, "typing")?; let typings = PyModule::import_bound(py, "typing")?;
let id_fn = builtins.getattr("id")?; let id_fn = builtins.getattr("id")?;
let issubclass = builtins.getattr("issubclass")?; let issubclass = builtins.getattr("issubclass")?;
let exn_class = builtins.getattr("Exception")?; let exn_class = builtins.getattr("Exception")?;
@ -421,7 +423,7 @@ impl Nac3 {
let class_obj; let class_obj;
if let StmtKind::ClassDef { name, .. } = &stmt.node { if let StmtKind::ClassDef { name, .. } = &stmt.node {
let class = py_module.getattr(name.to_string().as_str()).unwrap(); let class = py_module.getattr(name.to_string().as_str()).unwrap();
if issubclass.call1((class, exn_class)).unwrap().extract().unwrap() if issubclass.call1((class, exn_class.as_gil_ref())).unwrap().extract().unwrap()
&& class.getattr("artiq_builtin").is_err() && class.getattr("artiq_builtin").is_err()
{ {
class_obj = Some(class); class_obj = Some(class);
@ -513,15 +515,15 @@ impl Nac3 {
} }
} }
let id_fun = PyModule::import(py, "builtins")?.getattr("id")?; let id_fun = PyModule::import_bound(py, "builtins")?.getattr("id")?;
let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new(); let mut name_to_pyid: HashMap<StrRef, u64> = HashMap::new();
let module = PyModule::new(py, "tmp")?; let module = PyModule::new_bound(py, "tmp")?;
module.add("base", obj)?; module.add("base", obj)?;
name_to_pyid.insert("base".into(), id_fun.call1((obj,))?.extract()?); name_to_pyid.insert("base".into(), id_fun.call1((obj,))?.extract()?);
let mut arg_names = vec![]; let mut arg_names = vec![];
for (i, arg) in args.into_iter().enumerate() { for (i, arg) in args.into_iter().enumerate() {
let name = format!("tmp{i}"); let name = format!("tmp{i}");
module.add(&name, arg)?; module.add(&*name, arg)?;
name_to_pyid.insert(name.clone().into(), id_fun.call1((arg,))?.extract()?); name_to_pyid.insert(name.clone().into(), id_fun.call1((arg,))?.extract()?);
arg_names.push(name); arg_names.push(name);
} }
@ -900,7 +902,7 @@ fn add_exceptions(
#[pymethods] #[pymethods]
impl Nac3 { impl Nac3 {
#[new] #[new]
fn new(isa: &str, artiq_builtins: &PyDict, py: Python) -> PyResult<Self> { fn new(isa: &str, artiq_builtins: &Bound<PyDict>, py: Python) -> PyResult<Self> {
let isa = match isa { let isa = match isa {
"host" => Isa::Host, "host" => Isa::Host,
"rv32g" => Isa::RiscV32G, "rv32g" => Isa::RiscV32G,
@ -964,43 +966,45 @@ impl Nac3 {
), ),
]; ];
let builtins_mod = PyModule::import(py, "builtins").unwrap(); let builtins_mod = PyModule::import_bound(py, "builtins").unwrap();
let id_fn = builtins_mod.getattr("id").unwrap(); let id_fn = builtins_mod.getattr("id").unwrap();
let numpy_mod = PyModule::import(py, "numpy").unwrap(); let numpy_mod = PyModule::import_bound(py, "numpy").unwrap();
let typing_mod = PyModule::import(py, "typing").unwrap(); let typing_mod = PyModule::import_bound(py, "typing").unwrap();
let types_mod = PyModule::import(py, "types").unwrap(); let types_mod = PyModule::import_bound(py, "types").unwrap();
let get_id = |x: &PyAny| id_fn.call1((x,)).and_then(PyAny::extract).unwrap(); let get_id = |x: &PyAny| id_fn.call1((x,)).and_then(|id| id.extract()).unwrap();
let get_attr_id = |obj: &PyModule, attr| { let get_attr_id = |obj: &PyModule, attr| {
id_fn.call1((obj.getattr(attr).unwrap(),)).unwrap().extract().unwrap() id_fn.call1((obj.getattr(attr).unwrap(),)).unwrap().extract().unwrap()
}; };
let primitive_ids = PrimitivePythonId { let primitive_ids = PrimitivePythonId {
virtual_id: get_id(artiq_builtins.get_item("virtual").ok().flatten().unwrap()), virtual_id: get_id(
artiq_builtins.get_item("virtual").ok().flatten().unwrap().as_gil_ref(),
),
generic_alias: ( generic_alias: (
get_attr_id(typing_mod, "_GenericAlias"), get_attr_id(typing_mod.as_gil_ref(), "_GenericAlias"),
get_attr_id(types_mod, "GenericAlias"), get_attr_id(types_mod.as_gil_ref(), "GenericAlias"),
), ),
none: get_id(artiq_builtins.get_item("none").ok().flatten().unwrap()), none: get_id(artiq_builtins.get_item("none").ok().flatten().unwrap().as_gil_ref()),
typevar: get_attr_id(typing_mod, "TypeVar"), typevar: get_attr_id(typing_mod.as_gil_ref(), "TypeVar"),
const_generic_marker: get_id( const_generic_marker: get_id(
artiq_builtins.get_item("_ConstGenericMarker").ok().flatten().unwrap(), artiq_builtins.get_item("_ConstGenericMarker").ok().flatten().unwrap().as_gil_ref(),
), ),
int: get_attr_id(builtins_mod, "int"), int: get_attr_id(builtins_mod.as_gil_ref(), "int"),
int32: get_attr_id(numpy_mod, "int32"), int32: get_attr_id(numpy_mod.as_gil_ref(), "int32"),
int64: get_attr_id(numpy_mod, "int64"), int64: get_attr_id(numpy_mod.as_gil_ref(), "int64"),
uint32: get_attr_id(numpy_mod, "uint32"), uint32: get_attr_id(numpy_mod.as_gil_ref(), "uint32"),
uint64: get_attr_id(numpy_mod, "uint64"), uint64: get_attr_id(numpy_mod.as_gil_ref(), "uint64"),
bool: get_attr_id(builtins_mod, "bool"), bool: get_attr_id(builtins_mod.as_gil_ref(), "bool"),
np_bool_: get_attr_id(numpy_mod, "bool_"), np_bool_: get_attr_id(numpy_mod.as_gil_ref(), "bool_"),
string: get_attr_id(builtins_mod, "str"), string: get_attr_id(builtins_mod.as_gil_ref(), "str"),
np_str_: get_attr_id(numpy_mod, "str_"), np_str_: get_attr_id(numpy_mod.as_gil_ref(), "str_"),
float: get_attr_id(builtins_mod, "float"), float: get_attr_id(builtins_mod.as_gil_ref(), "float"),
float64: get_attr_id(numpy_mod, "float64"), float64: get_attr_id(numpy_mod.as_gil_ref(), "float64"),
list: get_attr_id(builtins_mod, "list"), list: get_attr_id(builtins_mod.as_gil_ref(), "list"),
ndarray: get_attr_id(numpy_mod, "ndarray"), ndarray: get_attr_id(numpy_mod.as_gil_ref(), "ndarray"),
tuple: get_attr_id(builtins_mod, "tuple"), tuple: get_attr_id(builtins_mod.as_gil_ref(), "tuple"),
exception: get_attr_id(builtins_mod, "Exception"), exception: get_attr_id(builtins_mod.as_gil_ref(), "Exception"),
option: get_id(artiq_builtins.get_item("Option").ok().flatten().unwrap()), option: get_id(artiq_builtins.get_item("Option").ok().flatten().unwrap().as_gil_ref()),
}; };
let working_directory = tempfile::Builder::new().prefix("nac3-").tempdir().unwrap(); let working_directory = tempfile::Builder::new().prefix("nac3-").tempdir().unwrap();
@ -1025,23 +1029,23 @@ impl Nac3 {
}) })
} }
fn analyze(&mut self, functions: &PySet, classes: &PySet) -> PyResult<()> { fn analyze(&mut self, functions: &Bound<PySet>, classes: &Bound<PySet>) -> PyResult<()> {
let (modules, class_ids) = let (modules, class_ids) =
Python::with_gil(|py| -> PyResult<(HashMap<u64, PyObject>, HashSet<u64>)> { Python::with_gil(|py| -> PyResult<(HashMap<u64, PyObject>, HashSet<u64>)> {
let mut modules: HashMap<u64, PyObject> = HashMap::new(); let mut modules: HashMap<u64, PyObject> = HashMap::new();
let mut class_ids: HashSet<u64> = HashSet::new(); let mut class_ids: HashSet<u64> = HashSet::new();
let id_fn = PyModule::import(py, "builtins")?.getattr("id")?; let id_fn = PyModule::import_bound(py, "builtins")?.getattr("id")?;
let getmodule_fn = PyModule::import(py, "inspect")?.getattr("getmodule")?; let getmodule_fn = PyModule::import_bound(py, "inspect")?.getattr("getmodule")?;
for function in functions { for function in functions {
let module = getmodule_fn.call1((function,))?.extract()?; let module = getmodule_fn.call1((function,))?.extract()?;
modules.insert(id_fn.call1((&module,))?.extract()?, module); modules.insert(id_fn.call1((&module,))?.extract()?, module);
} }
for class in classes { for class in classes {
let module = getmodule_fn.call1((class,))?.extract()?; let module = getmodule_fn.call1((class.as_gil_ref(),))?.extract()?;
modules.insert(id_fn.call1((&module,))?.extract()?, module); modules.insert(id_fn.call1((&module,))?.extract()?, module);
class_ids.insert(id_fn.call1((class,))?.extract()?); class_ids.insert(id_fn.call1((class.as_gil_ref(),))?.extract()?);
} }
Ok((modules, class_ids)) Ok((modules, class_ids))
})?; })?;
@ -1054,11 +1058,11 @@ impl Nac3 {
fn compile_method_to_file( fn compile_method_to_file(
&mut self, &mut self,
obj: &PyAny, obj: &Bound<PyAny>,
method_name: &str, method_name: &str,
args: Vec<&PyAny>, args: Vec<&PyAny>,
filename: &str, filename: &str,
embedding_map: &PyAny, embedding_map: &Bound<PyAny>,
py: Python, py: Python,
) -> PyResult<()> { ) -> PyResult<()> {
let target_machine = self.get_llvm_target_machine(); let target_machine = self.get_llvm_target_machine();
@ -1100,10 +1104,10 @@ impl Nac3 {
fn compile_method_to_mem( fn compile_method_to_mem(
&mut self, &mut self,
obj: &PyAny, obj: &Bound<PyAny>,
method_name: &str, method_name: &str,
args: Vec<&PyAny>, args: Vec<&PyAny>,
embedding_map: &PyAny, embedding_map: &Bound<PyAny>,
py: Python, py: Python,
) -> PyResult<PyObject> { ) -> PyResult<PyObject> {
let target_machine = self.get_llvm_target_machine(); let target_machine = self.get_llvm_target_machine();
@ -1122,7 +1126,7 @@ impl Nac3 {
working_directory.join("module.o").to_string_lossy().to_string(), working_directory.join("module.o").to_string_lossy().to_string(),
)?; )?;
Ok(PyBytes::new(py, &fs::read(filename).unwrap()).into()) Ok(PyBytes::new_bound(py, &fs::read(filename).unwrap()).into())
}; };
self.compile_method(obj, method_name, args, embedding_map, py, &link_fn) self.compile_method(obj, method_name, args, embedding_map, py, &link_fn)
@ -1132,7 +1136,7 @@ impl Nac3 {
.write_to_memory_buffer(module, FileType::Object) .write_to_memory_buffer(module, FileType::Object)
.expect("couldn't write module to object file buffer"); .expect("couldn't write module to object file buffer");
if let Ok(dyn_lib) = Linker::ld(object_mem.as_slice()) { if let Ok(dyn_lib) = Linker::ld(object_mem.as_slice()) {
Ok(PyBytes::new(py, &dyn_lib).into()) Ok(PyBytes::new_bound(py, &dyn_lib).into())
} else { } else {
Err(CompileError::new_err("linker failed to process object file")) Err(CompileError::new_err("linker failed to process object file"))
} }
@ -1149,14 +1153,14 @@ extern "C" {
} }
#[pymodule] #[pymodule]
fn nac3artiq(py: Python, m: &PyModule) -> PyResult<()> { fn nac3artiq(py: Python, m: &Bound<PyModule>) -> PyResult<()> {
#[cfg(feature = "init-llvm-profile")] #[cfg(feature = "init-llvm-profile")]
unsafe { unsafe {
__llvm_profile_initialize(); __llvm_profile_initialize();
} }
Target::initialize_all(&InitializationConfig::default()); Target::initialize_all(&InitializationConfig::default());
m.add("CompileError", py.get_type::<CompileError>())?; m.add("CompileError", py.get_type_bound::<CompileError>())?;
m.add_class::<Nac3>()?; m.add_class::<Nac3>()?;
Ok(()) Ok(())
} }

View File

@ -25,8 +25,8 @@ use nac3core::{
}; };
use parking_lot::RwLock; use parking_lot::RwLock;
use pyo3::{ use pyo3::{
prelude::*,
types::{PyDict, PyTuple}, types::{PyDict, PyTuple},
PyAny, PyObject, PyResult, Python,
}; };
use std::{ use std::{
collections::{HashMap, HashSet}, collections::{HashMap, HashSet},
@ -173,7 +173,7 @@ impl StaticValue for PythonValue {
Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> { Python::with_gil(|py| -> PyResult<BasicValueEnum<'ctx>> {
self.resolver self.resolver
.get_obj_value(py, self.value.as_ref(py), ctx, generator, expected_ty) .get_obj_value(py, self.value.bind(py).as_gil_ref(), ctx, generator, expected_ty)
.map(Option::unwrap) .map(Option::unwrap)
}) })
.map_err(|e| e.to_string()) .map_err(|e| e.to_string())
@ -461,9 +461,14 @@ impl InnerResolver {
{ {
let origin = self.helper.origin_ty_fn.call1(py, (pyty,))?; let origin = self.helper.origin_ty_fn.call1(py, (pyty,))?;
let args = self.helper.args_ty_fn.call1(py, (pyty,))?; let args = self.helper.args_ty_fn.call1(py, (pyty,))?;
let args: &PyTuple = args.downcast(py)?; let args = args.downcast_bound::<PyTuple>(py)?;
let origin_ty = let origin_ty = match self.get_pyty_obj_type(
match self.get_pyty_obj_type(py, origin.as_ref(py), unifier, defs, primitives)? { py,
origin.bind(py).as_gil_ref(),
unifier,
defs,
primitives,
)? {
Ok((ty, false)) => ty, Ok((ty, false)) => ty,
Ok((_, true)) => { Ok((_, true)) => {
return Ok(Err("instantiated type does not take type parameters".into())) return Ok(Err("instantiated type does not take type parameters".into()))
@ -476,7 +481,7 @@ impl InnerResolver {
if args.len() == 1 { if args.len() == 1 {
let ty = match self.get_pyty_obj_type( let ty = match self.get_pyty_obj_type(
py, py,
args.get_item(0)?, args.get_item(0)?.as_gil_ref(),
unifier, unifier,
defs, defs,
primitives, primitives,
@ -522,9 +527,15 @@ impl InnerResolver {
// npt.NDArray[T] == np.ndarray[Any, np.dtype[T]] // npt.NDArray[T] == np.ndarray[Any, np.dtype[T]]
let ndarray_dtype_pyty = let ndarray_dtype_pyty =
self.helper.args_ty_fn.call1(py, (args.get_item(1)?,))?; self.helper.args_ty_fn.call1(py, (args.get_item(1)?,))?;
let dtype = ndarray_dtype_pyty.downcast::<PyTuple>(py)?.get_item(0)?; let dtype = ndarray_dtype_pyty.downcast_bound::<PyTuple>(py)?.get_item(0)?;
let ty = match self.get_pyty_obj_type(py, dtype, unifier, defs, primitives)? { let ty = match self.get_pyty_obj_type(
py,
dtype.as_gil_ref(),
unifier,
defs,
primitives,
)? {
Ok(ty) => ty, Ok(ty) => ty,
Err(err) => return Ok(Err(err)), Err(err) => return Ok(Err(err)),
}; };
@ -540,7 +551,7 @@ impl InnerResolver {
TypeEnum::TTuple { .. } => { TypeEnum::TTuple { .. } => {
let args = match args let args = match args
.iter() .iter()
.map(|x| self.get_pyty_obj_type(py, x, unifier, defs, primitives)) .map(|x| self.get_pyty_obj_type(py, x.as_gil_ref(), unifier, defs, primitives))
.collect::<Result<Vec<_>, _>>()? .collect::<Result<Vec<_>, _>>()?
.into_iter() .into_iter()
.collect::<Result<Vec<_>, _>>() { .collect::<Result<Vec<_>, _>>() {
@ -573,7 +584,7 @@ impl InnerResolver {
} }
let args = match args let args = match args
.iter() .iter()
.map(|x| self.get_pyty_obj_type(py, x, unifier, defs, primitives)) .map(|x| self.get_pyty_obj_type(py, x.as_gil_ref(), unifier, defs, primitives))
.collect::<Result<Vec<_>, _>>()? .collect::<Result<Vec<_>, _>>()?
.into_iter() .into_iter()
.collect::<Result<Vec<_>, _>>() { .collect::<Result<Vec<_>, _>>() {
@ -600,7 +611,7 @@ impl InnerResolver {
if args.len() == 1 { if args.len() == 1 {
let ty = match self.get_pyty_obj_type( let ty = match self.get_pyty_obj_type(
py, py,
args.get_item(0)?, args.get_item(0)?.as_gil_ref(),
unifier, unifier,
defs, defs,
primitives, primitives,
@ -631,8 +642,7 @@ impl InnerResolver {
false, false,
))) )))
} else { } else {
let str_fn = let str_fn = PyModule::import_bound(py, "builtins").unwrap().getattr("repr").unwrap();
pyo3::types::PyModule::import(py, "builtins").unwrap().getattr("repr").unwrap();
let str_repr: String = str_fn.call1((pyty,)).unwrap().extract().unwrap(); let str_repr: String = str_fn.call1((pyty,)).unwrap().extract().unwrap();
Ok(Err(format!("{str_repr} is not registered with NAC3 (@nac3 decorator missing?)"))) Ok(Err(format!("{str_repr} is not registered with NAC3 (@nac3 decorator missing?)")))
} }
@ -688,7 +698,7 @@ impl InnerResolver {
{ {
obj obj
} else { } else {
ty.as_ref(py) ty.bind(py).as_gil_ref()
} }
}, },
unifier, unifier,
@ -1549,10 +1559,16 @@ impl SymbolResolver for Resolver {
let store = self.0.deferred_eval_store.store.read(); let store = self.0.deferred_eval_store.store.read();
Python::with_gil(|py| -> PyResult<Result<(), String>> { Python::with_gil(|py| -> PyResult<Result<(), String>> {
for (variables, constraints, name) in store.iter() { for (variables, constraints, name) in store.iter() {
let constraints: &PyAny = constraints.as_ref(py); let constraints = constraints.bind(py);
for (i, var) in variables.iter().enumerate() { for (i, var) in variables.iter().enumerate() {
if let Ok(constr) = constraints.get_item(i) { if let Ok(constr) = constraints.get_item(i) {
match self.0.get_pyty_obj_type(py, constr, unifier, defs, primitives)? { match self.0.get_pyty_obj_type(
py,
constr.as_gil_ref(),
unifier,
defs,
primitives,
)? {
Ok((ty, _)) => { Ok((ty, _)) => {
if !unifier.is_concrete(ty, &[]) { if !unifier.is_concrete(ty, &[]) {
return Ok(Err(format!( return Ok(Err(format!(