Yet another Python binding to starlark-rust
, exposing the
Starlark language to your Python projects. The current version wraps
starlark-rust
version 0.12.x.
The project's name is a calque of "Starlark" into Chinese. It is pronounced xīng què (in Standard Pinyin) or Hsing-ch'üeh (in Wade-Giles).
The reason behind the curious name
I had to come up with another name for the project after discovering
an identically named project after I first renamed the
project starlark-pyo3
from python-starlark-rs
, and that the probably
next-best alternative pystarlark
was also taken long ago. Fortunately
though, the Chinese name is shorter to type, even shorter than "starlark"
itself...
NOTE: this project still has rough corners, do not use in production yet without due care. Expect breaking changes to the API before a 1.0 version.
A fair amount of starlark-rust
API has been wrapped so far. You can see the
smoke test cases for some examples on how to integrate
this package.
This project as compared to other known bindings:
Feature | β¨π¦ | starlark-pyo3 |
starlark-go |
---|---|---|---|
License | Apache-2.0 | Apache-2.0 | Apache-2.0 |
py.typed |
β | β | β |
Binding framework | PyO3 | PyO3 | cgo |
ABI3 compatibility | β any Python β₯ 3.8 | β | β |
Bundled β¨ | Rust, 0.12.x | Rust, 0.10.x | Go, circa March 2023 |
Data marshalling | β‘ native FFI | π¦ via Python json |
β‘ native FFI |
Accessing opaque π values from β¨ | β | β | π₯ crashes |
Accessing opaque β¨ values from π | β | β | β |
Magic method proxying for opaque π values | β somewhat complete | β | β |
Magic method proxying for opaque β¨ values | π§ WIP | β | β |
Invoking π callables from β¨ | β | β | β |
Invoking β¨ callables from π | β | β | β |
Linting | π planned | β | β |
LSP integration | π planned | β | β |
Profiling & code coverage | π planned | β | β |
Structured β¨ documentation | π planned | β | β |
Two-way data marshalling is done natively if a type is available both in Python
and Starlark. For complex and/or user-defined types such as classes, opaque
wrappers at both sides are available to allow some flexibility -- after all,
people would expect some degree of interoperability between Python and Starlark,
because Starlark is (arguably) seen by many as a dialect of Python.
Opaque Python values in Starlark all have the pyobject
type; while opaque
Starlark values are starlark.FrozenValue
and starlark.Value
in Python.
Identity i.e. uniqueness for the underlying concrete objects is NOT preserved
for objects across the language boundary: for example, each time you get
a
plain-old-data value from a FrozenModule
a new Python object would be created.
This should not cause problems at the Starlark side, as identity comparison (the
is
operator) is not supported in Starlark anyway, but you
should take care at the Python side. Opaque Python values in Starlark context
maintain their identities when being read back from Python though, because they
are in fact just references to the original object
being set
.
xingque
proxies an opaque Python value's most magic methods into Starlark.
This means you can pass your Python objects and callables into Starlark, and use
them largely as if the runtime is still Python.
Due to missing API in Starlark and/or PyO3, there can be some operators for whose Python to Starlark proxying is not supported right now. Currently this is:
- absolute value: Starlark
abs(x)
, Python__abs__
: missingStarlarkValue
trait method
There are other features that are not implemented right now, but I have plans to support in a future version. These are:
- slicing i.e. sequence-like usage
__{get,set,del}item__
i.e. mapping-like usage- iterator protocol
There is no enforced ownership tracking in Python, unlike Rust, so exceptions
will be thrown if one tries to use an already consumed object, for example an
AstModule
already evaluated by an Evaluator
.
The starlark::values::Value
type does not allow tracking its originating heap
in the public API (at least during my investigation while implementing this
library), so beware: Python interpreter crashes can occur if a
starlark.Value
's originating heap is GC-ed but a reference to such a Value
is kept elsewhere and later used. More design is needed for fixing the problem;
one should expect breaking changes to the API in a future version of this library.
Meanwhile, use frozen values and modules whenever appropriate; more determinism
can never hurt.
Copyright Β© 2024 WANG Xuerui. All rights reserved.
xingque
is licensed under the Apache 2.0 license.