Skip to content

Commit dd33031

Browse files
committed
feat: python runtime facade for interop
Signed-off-by: Sam Gammon <[email protected]>
1 parent d342a1b commit dd33031

File tree

4 files changed

+86
-3
lines changed

4 files changed

+86
-3
lines changed

elide/runtime/python/BUILD.bazel

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ load(
55
)
66

77
PYTHON_BUILTINS = [
8+
"elide",
89
"sqlite3",
910
]
1011

@@ -13,6 +14,11 @@ py_runtime(
1314
deps = ["//elide/runtime/python/%s" % m for m in PYTHON_BUILTINS],
1415
)
1516

17+
alias(
18+
name = "python",
19+
actual = ":dist",
20+
)
21+
1622
## -- Distribution -- ##
1723

1824
runtime_dist(
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
load(
2+
"//tools:defs.bzl",
3+
"py_library",
4+
)
5+
package(
6+
default_visibility = ["//visibility:public"],
7+
)
8+
9+
py_library(
10+
name = "elide",
11+
srcs = ["__init__.py"],
12+
)

elide/runtime/python/elide/__init__.py

Lines changed: 68 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,71 @@
1515
Defines Elide-specific APIs.
1616
"""
1717

18-
hello = "hi"
18+
import polyglot
19+
20+
# Registered polyglot bindings.
21+
registered_py_symbols = {}
22+
23+
# Internal factory method for binding management.
24+
def __bind_factory(name = None):
25+
def binder(obj):
26+
symbol = name or obj.__name__
27+
if symbol in registered_py_symbols:
28+
raise ValueError(f"Symbol '{symbol}' already bound for polyglot access.")
29+
30+
# register the symbol
31+
polyglot.export_value(
32+
symbol,
33+
obj
34+
)
35+
return obj
36+
return binder
37+
38+
def bind(obj):
39+
"""Binds a Python symbol within Elide's polyglot context; this exposes the symbol (at its regular name)
40+
for cross-language interop.
41+
42+
This function is designed to be used as a parameterless decorator. For example:
43+
44+
```python
45+
from elide import bind
46+
47+
@bind
48+
def my_function():
49+
# do something
50+
pass
51+
```
52+
53+
`bind` specifically exists to reuse a symbol's name as-defined in Python. To bind the symbol to a
54+
different name, use `poly`.
55+
56+
:param obj: The Python object to bind for polyglot access.
57+
:return: The bound object, which is also registered for polyglot access.
58+
"""
59+
60+
return __bind_factory()(obj)
61+
62+
def poly(name = None):
63+
"""Binds a Python symbol within Elide's polyglot context; this exposes the symbol at its regular given
64+
name, or at the name provided as a parameter, for cross-language interop.
65+
66+
This function is designed to be used as a parameterized decorator. For example:
67+
68+
```python
69+
from elide import poly
70+
71+
@poly("my_function")
72+
def some_function():
73+
# do something
74+
pass
75+
```
76+
77+
`poly` must be called even if no name is provided. `bind` is also provided as a shorthand which needs
78+
not be called, takes no parameters, and always uses the name of the symbol as defined in Python.
79+
80+
:param name: The name to bind the symbol to for polyglot access. If not provided, the symbol's name
81+
as defined in Python will be used.
82+
:return: The bound object, which is also registered for polyglot access.
83+
"""
84+
85+
return __bind_factory(name)

elide/runtime/python/sqlite3/__init__.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,5 +15,3 @@
1515
Defines the Python-side SQLite3 API for use in Elide; roughly follows the standardized
1616
Python `sqlite3` module API.
1717
"""
18-
19-
hello = "hi"

0 commit comments

Comments
 (0)