diff --git a/.github/workflows/CI.yml b/.github/workflows/CI.yml index 7b999c7..e5e307d 100644 --- a/.github/workflows/CI.yml +++ b/.github/workflows/CI.yml @@ -10,6 +10,10 @@ on: schedule: - cron: '17 3 * * 0' +concurrency: + group: ${{ github.head_ref || github.ref_name }} + cancel-in-progress: true + jobs: linux: runs-on: ubuntu-latest @@ -40,7 +44,7 @@ jobs: target: ${{ matrix.target }} command: build rust-toolchain: stable - args: --release -o dist --find-interpreter + args: --release -o dist -i 3.9 -i 3.10 -i 3.11 -i 3.12 -i 3.13 - name: Upload wheels uses: actions/upload-artifact@v4 with: diff --git a/Cargo.lock b/Cargo.lock index 8a2a1af..d222f54 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -14,13 +14,14 @@ dependencies = [ [[package]] name = "ahash" -version = "0.7.7" +version = "0.8.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5a824f2aa7e75a0c98c5a504fceb80649e9c35265d44525b5f94de4771a395cd" +checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011" dependencies = [ - "getrandom", + "cfg-if", "once_cell", "version_check", + "zerocopy", ] [[package]] @@ -34,28 +35,34 @@ dependencies = [ [[package]] name = "allocative" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38d7346fefe76a2adfb9729f00e3a6f0992480d20a6c2df5ba36dc24262b4998" +checksum = "082af274fd02beef17b7f0725a49ecafe6c075ef56cac9d6363eb3916a9817ae" dependencies = [ "allocative_derive", "bumpalo", "ctor", - "hashbrown 0.12.3", + "hashbrown", "num-bigint", ] [[package]] name = "allocative_derive" -version = "0.3.1" +version = "0.3.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e21abe3434e1b78feb5fe14d30bf3fcfa0a3c599f0b8fb381302ee6f68eb5716" +checksum = "fe233a377643e0fc1a56421d7c90acdec45c291b30345eb9f08e8d0ddce5a4ab" dependencies = [ "proc-macro2", "quote", "syn 2.0.87", ] +[[package]] +name = "allocator-api2" +version = "0.2.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" + [[package]] name = "annotate-snippets" version = "0.9.2" @@ -125,6 +132,12 @@ version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7f30e7476521f6f8af1a1c4c0b8cc94f0bee37d91763d0ca2665f299b6cd8aec" +[[package]] +name = "byteorder" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" + [[package]] name = "cfg-if" version = "1.0.0" @@ -318,16 +331,6 @@ dependencies = [ "str-buf", ] -[[package]] -name = "fancy-regex" -version = "0.10.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0678ab2d46fa5195aaf59ad034c083d351377d4af57f3e073c074d0da3e3c766" -dependencies = [ - "bit-set", - "regex", -] - [[package]] name = "fd-lock" version = "3.0.13" @@ -360,6 +363,15 @@ dependencies = [ "percent-encoding", ] +[[package]] +name = "fxhash" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c" +dependencies = [ + "byteorder", +] + [[package]] name = "gazebo" version = "0.8.1" @@ -393,24 +405,19 @@ dependencies = [ [[package]] name = "hashbrown" -version = "0.12.3" +version = "0.14.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" +checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" dependencies = [ "ahash", + "allocator-api2", ] -[[package]] -name = "hashbrown" -version = "0.14.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "290f1a1d9242c78d09ce40a5e87e7554ee637af1351968159f4952f028f75604" - [[package]] name = "heck" -version = "0.4.1" +version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" [[package]] name = "hermit-abi" @@ -441,7 +448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d530e1a18b1cb4c484e6e34556a0d948706958449fca0cab753d649f2bce3d1f" dependencies = [ "equivalent", - "hashbrown 0.14.3", + "hashbrown", ] [[package]] @@ -763,15 +770,15 @@ dependencies = [ [[package]] name = "pyo3" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a5e00b96a521718e08e03b1a622f01c8a8deb50719335de3f60b3b3950f069d8" +checksum = "f402062616ab18202ae8319da13fa4279883a2b8a9d9f83f20dbade813ce1884" dependencies = [ "cfg-if", "indoc", "libc", "memoffset 0.9.1", - "parking_lot", + "once_cell", "portable-atomic", "pyo3-build-config", "pyo3-ffi", @@ -781,9 +788,9 @@ dependencies = [ [[package]] name = "pyo3-build-config" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7883df5835fafdad87c0d888b266c8ec0f4c9ca48a5bed6bbb592e8dedee1b50" +checksum = "b14b5775b5ff446dd1056212d778012cbe8a0fbffd368029fd9e25b514479c38" dependencies = [ "once_cell", "target-lexicon", @@ -791,9 +798,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "01be5843dc60b916ab4dad1dca6d20b9b4e6ddc8e15f50c47fe6d85f1fb97403" +checksum = "9ab5bcf04a2cdcbb50c7d6105de943f543f9ed92af55818fd17b660390fc8636" dependencies = [ "libc", "pyo3-build-config", @@ -801,9 +808,9 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77b34069fc0682e11b31dbd10321cbf94808394c56fd996796ce45217dfac53c" +checksum = "0fd24d897903a9e6d80b968368a34e1525aeb719d568dba8b3d4bfa5dc67d453" dependencies = [ "proc-macro2", "pyo3-macros-backend", @@ -813,9 +820,9 @@ dependencies = [ [[package]] name = "pyo3-macros-backend" -version = "0.21.2" +version = "0.22.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08260721f32db5e1a5beae69a55553f56b99bd0e1c3e6e0a5e8851a9d0f5a85c" +checksum = "36c011a03ba1e50152b4b394b479826cad97e7a21eb52df179cd91ac411cbfbe" dependencies = [ "heck", "proc-macro2", @@ -1065,9 +1072,9 @@ checksum = "4dccd0940a2dcdf68d092b8cbab7dc0ad8fa938bf95787e1b916b0e3d0e8e970" [[package]] name = "starlark" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a06c0ca1e553a2908f48797a733ddbc6769854005d9035565ff3e19b85ad3877" +checksum = "419b088f6fe8393b8b2525d57f32e240ff07ab49e39f0afe3c8a5372bb94a823" dependencies = [ "allocative", "anyhow", @@ -1080,8 +1087,7 @@ dependencies = [ "dupe", "either", "erased-serde", - "fancy-regex", - "hashbrown 0.12.3", + "hashbrown", "inventory", "itertools", "maplit", @@ -1094,7 +1100,7 @@ dependencies = [ "rustyline", "serde", "serde_json", - "starlark_derive", + "starlark_derive 0.12.0", "starlark_map", "starlark_syntax", "static_assertions", @@ -1116,7 +1122,7 @@ dependencies = [ "pyo3", "serde_json", "starlark", - "starlark_derive", + "starlark_derive 0.10.0", "syn 1.0.109", "thiserror", ] @@ -1133,25 +1139,37 @@ dependencies = [ "syn 2.0.87", ] +[[package]] +name = "starlark_derive" +version = "0.12.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ee8407ca86174f600acfc8b7e0576058bb866a19521b92f9590fa2bcf1c8c807" +dependencies = [ + "dupe", + "proc-macro2", + "quote", + "syn 2.0.87", +] + [[package]] name = "starlark_map" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0708516dd469849751f49c0a9c2c7db8eda8553d5313c4f665b2810c7eb0603" +checksum = "0e03678553f5f0ce473a7a9064fc7bf2c1fa5013eb605c95d09896e3eacbacc5" dependencies = [ "allocative", "dupe", "equivalent", - "fnv", - "hashbrown 0.12.3", + "fxhash", + "hashbrown", "serde", ] [[package]] name = "starlark_syntax" -version = "0.10.0" +version = "0.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f5c9476e3a6cfda9cc965329a77d5a6f73c1e3134abe04747b5d5077695fc94b" +checksum = "6ae4c126dbc9702fae89fb2460f06b0f562e7de1351ab545591a27e9528afa2f" dependencies = [ "allocative", "annotate-snippets", @@ -1522,3 +1540,23 @@ name = "windows_x86_64_msvc" version = "0.52.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "dff9641d1cd4be8d1a070daf9e3773c5f67e78b4d9d42263020c057706765c04" + +[[package]] +name = "zerocopy" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +dependencies = [ + "zerocopy-derive", +] + +[[package]] +name = "zerocopy-derive" +version = "0.7.35" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.87", +] diff --git a/Cargo.toml b/Cargo.toml index a0081d9..82f89da 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,10 @@ crate-type = ["cdylib"] name = "starlark" [dependencies] -starlark = "^0.10.0" +starlark = "^0.12.0" starlark_derive = "^0.10.0" anyhow = "^1.0.65" -pyo3 = { version = "0.21.2", features = ["extension-module"] } +pyo3 = { version = "0.22.6", features = ["extension-module"] } # needed to resolve contradictory constraints in dependencies syn = "^1.0.96" diff --git a/src/lib.rs b/src/lib.rs index 7420aa8..9711cae 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -95,7 +95,7 @@ fn serde_to_starlark<'v>(x: serde_json::Value, heap: &'v Heap) -> anyhow::Result // }}} fn value_to_pyobject(value: Value) -> PyResult { - let json_val = convert_err(value.to_json())?; + let json_val = convert_anyhow_err(value.to_json())?; Python::with_gil(|py| { let json = py.import_bound("json")?; json.getattr("loads")?.call1((json_val,))?.extract() @@ -106,7 +106,7 @@ fn pyobject_to_value<'v>(obj: PyObject, heap: &'v Heap) -> PyResult> { Python::with_gil(|py| -> PyResult> { let json = py.import_bound("json")?; let json_str: String = json.getattr("dumps")?.call1((obj,))?.extract()?; - convert_err(serde_to_starlark( + convert_anyhow_err(serde_to_starlark( convert_serde_err(serde_json::from_str(&json_str))?, heap, )) @@ -117,7 +117,14 @@ fn pyobject_to_value<'v>(obj: PyObject, heap: &'v Heap) -> PyResult> { // {{{ result conversions -fn convert_err(err: Result) -> Result { +fn convert_anyhow_err(err: Result) -> Result { + match err { + Ok(t) => Ok(t), + Err(e) => Err(StarlarkError::new_err(e.to_string())), + } +} + +fn convert_starlark_err(err: starlark::Result) -> Result { match err { Ok(t) => Ok(t), Err(e) => Err(StarlarkError::new_err(e.to_string())), @@ -131,10 +138,10 @@ fn convert_serde_err(err: Result) -> Result { } } -fn convert_to_anyhow(err: Result) -> Result { +fn convert_to_starlark_err(err: Result) -> Result { match err { Ok(t) => Ok(t), - Err(e) => Err(anyhow::Error::new(e)), + Err(e) => Err(starlark::Error::new_other(e)), } } @@ -443,18 +450,16 @@ struct AstModule(starlark::syntax::AstModule); /// Parse Starlark source code as a string and return an AST. #[pyfunction] #[pyo3( - text_signature = "(filename: str, content: str, dialect: Optional[Dialect] = None) -> AstModule" + signature = (filename, content, dialect=None) )] -fn parse(filename: &str, content: &str, dialect_opt: Option) -> PyResult { - let dialect = match dialect_opt { +fn parse(filename: &str, content: &str, dialect: Option) -> PyResult { + let dialect = match dialect { Some(dialect) => dialect.0, None => starlark::syntax::Dialect::Standard, }; - Ok(AstModule(convert_err(starlark::syntax::AstModule::parse( - filename, - content.to_string(), - &dialect, - ))?)) + Ok(AstModule(convert_starlark_err( + starlark::syntax::AstModule::parse(filename, content.to_string(), &dialect), + )?)) } /// .. automethod:: lint @@ -529,11 +534,6 @@ impl LibraryExtension { } #[classattr] #[allow(non_snake_case)] - fn ExperimentalRegex() -> Self { - LibraryExtension(starlark::environment::LibraryExtension::ExperimentalRegex) - } - #[classattr] - #[allow(non_snake_case)] fn Debug() -> Self { LibraryExtension(starlark::environment::LibraryExtension::Debug) } @@ -625,15 +625,17 @@ impl<'v> StarlarkValue<'v> for PythonCallableValue { _me: Value<'v>, args: &Arguments<'v, '_>, eval: &mut starlark::eval::Evaluator<'v, '_>, - ) -> anyhow::Result> { - Python::with_gil(|py| -> anyhow::Result> { + ) -> starlark::Result> { + Python::with_gil(|py| -> starlark::Result> { args.no_named_args()?; - let py_args: Vec = (args - .positions(eval.heap())? - .map(|v| -> PyResult { value_to_pyobject(v) })) - .collect::>>()?; - convert_to_anyhow(pyobject_to_value( - self.callable.call1(py, PyTuple::new_bound(py, py_args))?, + let py_args: Vec = convert_to_starlark_err( + (args + .positions(eval.heap())? + .map(|v| -> PyResult { value_to_pyobject(v) })) + .collect::>>(), + )?; + convert_to_starlark_err(pyobject_to_value( + convert_to_starlark_err(self.callable.call1(py, PyTuple::new_bound(py, py_args)))?, eval.heap(), )) }) @@ -680,11 +682,13 @@ impl Module { self.0.set(name, b); } - fn freeze(mod_cell: &PyCell) -> PyResult { - let module = mod_cell - .replace(Module(starlark::environment::Module::new())) - .0; - Ok(FrozenModule(convert_err(module.freeze())?)) + fn freeze(mod_cell: &Bound) -> PyResult { + let module = std::mem::replace( + &mut *mod_cell.borrow_mut(), + Module(starlark::environment::Module::new()), + ) + .0; + Ok(FrozenModule(convert_anyhow_err(module.freeze())?)) } } @@ -748,20 +752,21 @@ fn empty_ast() -> AstModule { /// :returns: the value returned by the evaluation, after :ref:`object-conversion`. #[pyfunction] #[pyo3( - text_signature = "(module: Module, ast: AstModule, globals: Globals, file_loader: Optional[FileLoader]) -> object" + signature = (module, ast, globals, file_loader=None) )] fn eval( module: &mut Module, - ast: &PyCell, + ast: &Bound, globals: &Globals, file_loader: Option<&Bound>, ) -> PyResult { let tail = |evaluator: &mut starlark::eval::Evaluator| { // Stupid: eval_module consumes the AST. // Python would like it to live on, but starlark-rust says no. - value_to_pyobject(convert_err( - evaluator.eval_module(ast.replace(empty_ast()).0, &globals.0), - )?) + value_to_pyobject(convert_starlark_err(evaluator.eval_module( + std::mem::replace(&mut *ast.borrow_mut(), empty_ast()).0, + &globals.0, + ))?) }; match file_loader { diff --git a/starlark.pyi b/starlark.pyi index 78a30a2..46c8f11 100644 --- a/starlark.pyi +++ b/starlark.pyi @@ -66,7 +66,6 @@ class LibraryExtension: Map: LibraryExtension Filter: LibraryExtension Partial: LibraryExtension - ExperimentalRegex: LibraryExtension Debug: LibraryExtension Print: LibraryExtension Pprint: LibraryExtension