Skip to content

Commit

Permalink
Reorganize Python to better differentiate between pub and internals. (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
obi1kenobi authored Sep 19, 2024
1 parent 5589ad7 commit b31a090
Show file tree
Hide file tree
Showing 10 changed files with 83 additions and 22 deletions.
4 changes: 2 additions & 2 deletions pytrustfall/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ authors.workspace = true

[lib]
# The name of the native library. This is the name which will be used in Python to import the
# library (i.e. `import trustfall`). If you change this, you must also change the name of the
# `#[pymodule]` in `src/lib.rs`.
# library (i.e. `from trustfall import trustfall`). If you change this, you must also change
# the name of the top `#[pymodule]` in `src/lib.rs`.
name = "trustfall"

# Avoid the name conflict with the Rust lib with the same name.
Expand Down
12 changes: 6 additions & 6 deletions pytrustfall/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ use pyo3::{
Bound, PyResult, Python,
};

create_exception!(pytrustfall, InvalidSchemaError, pyo3::exceptions::PyException);
create_exception!(pytrustfall, ParseError, pyo3::exceptions::PyException);
create_exception!(pytrustfall, ValidationError, pyo3::exceptions::PyException);
create_exception!(pytrustfall, FrontendError, pyo3::exceptions::PyException);
create_exception!(pytrustfall, InvalidIRQueryError, pyo3::exceptions::PyException);
create_exception!(pytrustfall, QueryArgumentsError, pyo3::exceptions::PyException);
create_exception!(_trustfall_internal, InvalidSchemaError, pyo3::exceptions::PyException);
create_exception!(_trustfall_internal, ParseError, pyo3::exceptions::PyException);
create_exception!(_trustfall_internal, ValidationError, pyo3::exceptions::PyException);
create_exception!(_trustfall_internal, FrontendError, pyo3::exceptions::PyException);
create_exception!(_trustfall_internal, InvalidIRQueryError, pyo3::exceptions::PyException);
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>())?;
Expand Down
16 changes: 13 additions & 3 deletions pytrustfall/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,25 @@
#![forbid(unused_lifetimes)]
#![forbid(elided_lifetimes_in_paths)]

use pyo3::{pymodule, types::PyModule, Bound, PyResult, Python};
use pyo3::{
pymodule,
types::{PyModule, PyModuleMethods},
Bound, PyResult, Python,
};

pub mod errors;
pub mod shim;
mod value;

#[pymodule]
fn trustfall(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
fn _trustfall_internal(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
shim::register(py, m)?;
errors::register(py, m)?;
Ok(())
}

#[pymodule]
fn trustfall(py: Python<'_>, m: &Bound<'_, PyModule>) -> PyResult<()> {
let submodule = PyModule::new_bound(py, "_trustfall_internal")?;
_trustfall_internal(py, &submodule)?;
m.add_submodule(&submodule)
}
25 changes: 23 additions & 2 deletions pytrustfall/trustfall/__init__.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from .adapter import Adapter, Context
from .execution import execute_query

from .trustfall import Schema
from ._internals import Schema

# Error types:
# - ParseError, when the provided input doesn't even parse as valid syntax
Expand All @@ -10,12 +10,33 @@
# are not supported or not valid
# - InvalidIRQueryError should in principle never be seen in Python. It indicates that
# the internal representation could not be converted to its "indexed" (i.e. execution-ready) form.
# - InvalidSchemaError, when the provided schema cannot be used due to violating some necessary
# precondition as explained in the error message.
# - QueryArgumentsError, if the query by itself is fine but cannot be executed together with
# the provided arguments.
from .trustfall import (
from ._internals import (
FrontendError,
InvalidIRQueryError,
InvalidSchemaError,
ParseError,
QueryArgumentsError,
ValidationError,
)

__all__ = [
# from .adapter
"Adapter",
"Context",
#
# from .execution
"execute_query",
#
# from ._internals (defined in Rust)
"FrontendError",
"InvalidIRQueryError",
"InvalidSchemaError",
"ParseError",
"QueryArgumentsError",
"Schema",
"ValidationError",
]
27 changes: 27 additions & 0 deletions pytrustfall/trustfall/_internals.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
from . import trustfall

# Workaround around issue preventing direct `from ._trustfall_internal import X` imports:
# https://github.com/PyO3/pyo3/issues/759
# https://github.com/PyO3/pyo3/issues/1517
_trustfall_internal = trustfall._trustfall_internal
AdapterShim = _trustfall_internal.AdapterShim
Schema = _trustfall_internal.Schema
FrontendError = _trustfall_internal.FrontendError
InvalidIRQueryError = _trustfall_internal.InvalidIRQueryError
InvalidSchemaError = _trustfall_internal.InvalidSchemaError
ParseError = _trustfall_internal.ParseError
QueryArgumentsError = _trustfall_internal.QueryArgumentsError
ValidationError = _trustfall_internal.ValidationError
interpret_query = _trustfall_internal.interpret_query

__all__ = [
"AdapterShim",
"FrontendError",
"InvalidIRQueryError",
"InvalidSchemaError",
"ParseError",
"QueryArgumentsError",
"Schema",
"ValidationError",
"interpret_query",
]
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
from typing import Any, Dict, Iterator, Mapping

from .adapter import Adapter

class AdapterShim:
def __init__(self, adapter: Any) -> None: ...
def __init__(self, adapter: Adapter[Any]) -> None: ...

class InvalidSchemaError(Exception): ...
class ParseError(Exception): ...
class ValidationError(Exception): ...
class FrontendError(Exception): ...
class InvalidIRQueryError(Exception): ...
class InvalidSchemaError(Exception): ...
class ParseError(Exception): ...
class QueryArgumentsError(Exception): ...
class ValidationError(Exception): ...

class Schema:
def __init__(self, schema_txt: str) -> None: ...
Expand Down
4 changes: 3 additions & 1 deletion pytrustfall/trustfall/adapter.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,12 @@ class Context(Generic[Vertex]):

__slots__ = ("_active_vertex",)

_active_vertex: Optional[Vertex]

@property
def active_vertex(self) -> Optional[Vertex]:
"""The vertex whose information (properties, edges, etc.) needs to be resolved."""
return self._active_vertex # type: ignore[attr-defined,no-any-return]
return self._active_vertex


class Adapter(Generic[Vertex], metaclass=ABCMeta):
Expand Down
2 changes: 1 addition & 1 deletion pytrustfall/trustfall/execution.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
from typing import Any, Dict, Iterator, Mapping

from .adapter import Adapter, Vertex
from .trustfall import AdapterShim, Schema, interpret_query
from ._internals import AdapterShim, Schema, interpret_query


def execute_query(
Expand Down
3 changes: 1 addition & 2 deletions pytrustfall/trustfall/tests/test_execution.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
from typing import Any, Dict
import unittest

from ..trustfall import (
from .. import (
FrontendError,
InvalidIRQueryError,
ParseError,
QueryArgumentsError,
Schema,
Expand Down
2 changes: 1 addition & 1 deletion pytrustfall/trustfall/tests/test_schema.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import unittest

from ..trustfall import (
from .. import (
InvalidSchemaError,
Schema,
)
Expand Down

0 comments on commit b31a090

Please sign in to comment.