Skip to content

Commit

Permalink
Merge branch 'main' into main_cargo_update
Browse files Browse the repository at this point in the history
  • Loading branch information
obi1kenobi authored Jan 16, 2025
2 parents 320ec11 + faa064e commit 25f3f8c
Show file tree
Hide file tree
Showing 8 changed files with 241 additions and 167 deletions.
20 changes: 10 additions & 10 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion pytrustfall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -26,5 +26,5 @@ crate-type = ["cdylib", "rlib"]
[dependencies]
async-graphql-parser = { workspace = true }
async-graphql-value = { workspace = true }
pyo3 = { version = "0.22.0", features = ["extension-module"] }
pyo3 = { version = "0.23.4", features = ["extension-module"] }
trustfall_core = { path = "../trustfall_core" }
275 changes: 168 additions & 107 deletions pytrustfall/poetry.lock

Large diffs are not rendered by default.

5 changes: 2 additions & 3 deletions pytrustfall/pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ classifiers = [
"Topic :: Software Development :: Interpreters",
"Typing :: Typed",
]
dynamic = ["version"]

[project.license]
text = "Apache 2.0"
Expand All @@ -37,12 +38,10 @@ authors = ["Predrag Gruevski <[email protected]>"]
[tool.poetry.dependencies]
python = "^3.9"

[tool.poetry.dev-dependencies]
[tool.poetry.group.dev.dependencies]
maturin = "^1.3.0"
pytest = "^7.4.2"
black = "^23.9.1"

[tool.poetry.group.dev.dependencies]
mypy = "^1.11.1"

[tool.black]
Expand Down
12 changes: 6 additions & 6 deletions pytrustfall/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,11 @@ create_exception!(_trustfall_internal, InvalidIRQueryError, pyo3::exceptions::Py
create_exception!(_trustfall_internal, QueryArgumentsError, pyo3::exceptions::PyException);

pub(crate) fn register(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
m.add("InvalidSchemaError", py.get_type_bound::<InvalidSchemaError>())?;
m.add("ParseError", py.get_type_bound::<ParseError>())?;
m.add("ValidationError", py.get_type_bound::<ValidationError>())?;
m.add("FrontendError", py.get_type_bound::<FrontendError>())?;
m.add("InvalidIRQueryError", py.get_type_bound::<InvalidIRQueryError>())?;
m.add("QueryArgumentsError", py.get_type_bound::<QueryArgumentsError>())?;
m.add("InvalidSchemaError", py.get_type::<InvalidSchemaError>())?;
m.add("ParseError", py.get_type::<ParseError>())?;
m.add("ValidationError", py.get_type::<ValidationError>())?;
m.add("FrontendError", py.get_type::<FrontendError>())?;
m.add("InvalidIRQueryError", py.get_type::<InvalidIRQueryError>())?;
m.add("QueryArgumentsError", py.get_type::<QueryArgumentsError>())?;
Ok(())
}
2 changes: 1 addition & 1 deletion pytrustfall/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ fn _trustfall_internal(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()>

#[pymodule]
fn trustfall(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
let submodule = PyModule::new_bound(py, "_trustfall_internal")?;
let submodule: Bound<'_, PyModule> = PyModule::new(py, "_trustfall_internal")?;
_trustfall_internal(py, &submodule)?;
m.add_submodule(&submodule)
}
64 changes: 36 additions & 28 deletions pytrustfall/src/shim.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,8 @@ pub struct Schema {
impl Schema {
#[new]
pub fn new(schema_text: &str) -> PyResult<Self> {
let inner = trustfall_core::schema::Schema::parse(schema_text).map_err(|e| {
Python::with_gil(|py| {
crate::errors::InvalidSchemaError::new_err(format!("{e}").into_py(py))
})
})?;
let inner = trustfall_core::schema::Schema::parse(schema_text)
.map_err(|e| crate::errors::InvalidSchemaError::new_err(format!("{e}")))?;

Ok(Self { inner })
}
Expand All @@ -66,28 +63,23 @@ pub fn interpret_query(
let wrapped_adapter = Arc::from(adapter);

let indexed_query = parse(&schema.inner, query).map_err(|err| match err {
FrontendError::ParseError(parse_err) => Python::with_gil(|py| {
crate::errors::ParseError::new_err(format!("{parse_err}").into_py(py))
}),
FrontendError::ValidationError(val_err) => Python::with_gil(|py| {
crate::errors::ValidationError::new_err(format!("{val_err}").into_py(py))
}),
_ => Python::with_gil(|py| {
crate::errors::FrontendError::new_err(format!("{err}").into_py(py))
}),
FrontendError::ParseError(parse_err) => {
crate::errors::ParseError::new_err(format!("{parse_err}"))
}
FrontendError::ValidationError(val_err) => {
crate::errors::ValidationError::new_err(format!("{val_err}"))
}
_ => crate::errors::FrontendError::new_err(format!("{err}")),
})?;

let execution = interpret_ir(wrapped_adapter, indexed_query, arguments).map_err(|err| {
Python::with_gil(|py| {
crate::errors::QueryArgumentsError::new_err(format!("{err}").into_py(py))
})
})?;
let execution = interpret_ir(wrapped_adapter, indexed_query, arguments)
.map_err(|err| crate::errors::QueryArgumentsError::new_err(format!("{err}")))?;
let owned_iter: Box<dyn Iterator<Item = BTreeMap<String, Py<PyAny>>>> =
Box::new(execution.map(|res| {
res.iter()
.map(|(k, v)| {
let py_value: FieldValue = v.clone().into();
Python::with_gil(|py| (k.to_string(), py_value.into_py(py)))
Python::with_gil(|py| (k.to_string(), py_value.into_pyobject(py).expect("failed to convert FieldValue to Python object, this shouldn't be possible").unbind()))
})
.collect()
}));
Expand Down Expand Up @@ -126,7 +118,7 @@ impl AdapterShim {
}

fn make_iterator<'py>(value: &Bound<'py, PyAny>, origin: &'static str) -> Bound<'py, PyIterator> {
value.iter().unwrap_or_else(|e| panic!("{origin} is not an iterable (caused by {e})"))
value.try_iter().unwrap_or_else(|e| panic!("{origin} is not an iterable (caused by {e})"))
}

#[pyclass(unsendable, frozen)]
Expand Down Expand Up @@ -200,12 +192,20 @@ impl Adapter<'static> for AdapterShim {
Python::with_gil(|py| {
let parameter_data: BTreeMap<String, Py<PyAny>> = parameters
.iter()
.map(|(k, v)| (k.to_string(), FieldValue::from(v.clone()).into_py(py)))
.map(|(k, v)| {
(
k.to_string(),
FieldValue::from(v.clone())
.into_pyobject(py)
.expect("failed to convert FieldValue to Python object")
.unbind(),
)
})
.collect();

let py_iterable = self
.adapter
.call_method_bound(
.call_method(
py,
pyo3::intern!(py, "resolve_starting_vertices"),
(edge_name.as_ref(), parameter_data),
Expand All @@ -229,7 +229,7 @@ impl Adapter<'static> for AdapterShim {
Python::with_gil(|py| {
let py_iterable = self
.adapter
.call_method_bound(
.call_method(
py,
pyo3::intern!(py, "resolve_property"),
(contexts, type_name.as_ref(), property_name.as_ref()),
Expand Down Expand Up @@ -263,12 +263,20 @@ impl Adapter<'static> for AdapterShim {
Python::with_gil(|py| {
let parameter_data: BTreeMap<String, Py<PyAny>> = parameters
.iter()
.map(|(k, v)| (k.to_string(), FieldValue::from(v.clone()).into_py(py)))
.map(|(k, v)| {
(
k.to_string(),
FieldValue::from(v.clone())
.into_pyobject(py)
.expect("failed to convert FieldValue to Python object")
.unbind(),
)
})
.collect();

let py_iterable = self
.adapter
.call_method_bound(
.call_method(
py,
pyo3::intern!(py, "resolve_neighbors"),
(contexts, type_name.as_ref(), edge_name.as_ref(), parameter_data),
Expand Down Expand Up @@ -300,7 +308,7 @@ impl Adapter<'static> for AdapterShim {
Python::with_gil(|py| {
let py_iterable = self
.adapter
.call_method_bound(
.call_method(
py,
pyo3::intern!(py, "resolve_coercion"),
(contexts, type_name.as_ref(), coerce_to_type.as_ref()),
Expand Down Expand Up @@ -336,7 +344,7 @@ impl Iterator for PythonVertexIterator {
type Item = Arc<Py<PyAny>>;

fn next(&mut self) -> Option<Self::Item> {
Python::with_gil(|py| match self.underlying.call_method_bound(py, "__next__", (), None) {
Python::with_gil(|py| match self.underlying.call_method(py, "__next__", (), None) {
Ok(value) => Some(Arc::new(value)),
Err(e) => {
if e.is_instance_of::<PyStopIteration>(py) {
Expand Down
28 changes: 17 additions & 11 deletions pytrustfall/src/value.rs
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,25 @@ impl Display for FieldValue {
}
}

impl IntoPy<Py<PyAny>> for FieldValue {
fn into_py(self, py: Python<'_>) -> Py<PyAny> {
impl<'py> IntoPyObject<'py> for FieldValue {
type Target = PyAny;
type Output = Bound<'py, Self::Target>;
type Error = PyErr;

fn into_pyobject(self, py: Python<'py>) -> Result<Self::Output, Self::Error> {
match self {
FieldValue::Null => Option::<i64>::None.into_py(py),
FieldValue::Uint64(x) => x.into_py(py),
FieldValue::Int64(x) => x.into_py(py),
FieldValue::Float64(x) => x.into_py(py),
FieldValue::String(x) => x.into_py(py),
FieldValue::Boolean(x) => x.into_py(py),
FieldValue::Null => Ok(Option::<i64>::None.into_pyobject(py)?),
FieldValue::Uint64(x) => Ok(x.into_pyobject(py).map(|x| x.into_any())?),
FieldValue::Int64(x) => Ok(x.into_pyobject(py).map(|x| x.into_any())?),
FieldValue::Float64(x) => Ok(x.into_pyobject(py).map(|x| x.into_any())?),
FieldValue::String(x) => Ok(x.into_pyobject(py).map(|x| x.into_any())?),
FieldValue::Boolean(x) => Ok(x.into_pyobject(py).map(|x| x.to_owned().into_any())?),
FieldValue::Enum(_) => todo!(),
FieldValue::List(x) => {
x.into_iter().map(|v| v.into_py(py)).collect::<Vec<_>>().into_py(py)
}
FieldValue::List(x) => x
.into_iter()
.map(|v| v.into_pyobject(py))
.collect::<Result<Vec<_>, _>>()?
.into_pyobject(py),
}
}
}
Expand Down

0 comments on commit 25f3f8c

Please sign in to comment.