Skip to main content

Pure-Python implementation of the Starlark configuration language.

Project description

Starlark in Python

PyPI package version badge. Python 3.11, 3.12, 3.13, 3.14 supported. PyPI download statistics badge.

This project provides a pure-Python implementation of the Starlark configuration language. Starlark in Python was ported by AI from the Java reference implementation that ships with Bazel. You can read how it was ported.

Status

Conformance test files are passing with the exception of 4 expected failures. Those are all documented divergences from the Java reference (UTF-16 string indexing, 32-bit range() bounds, and a Bazel-specific mutablestruct test helper).

Goals

  • Pure Python
    • Therefore usable in a cross-platform zipapp
  • No dependencies
  • Simple implementation (a tree-walking interpreter)
  • Safe to run untrusted code
  • Passes the conformance suite from Bazel (copied verbatim in conformance/)

Non-goals

  • Performance
  • Supporting old Python versions (3.11+ is currently required)

Quick start

import starlark

# Evaluate an expression.
starlark.eval("1 + 2 * 3")  # 7

# Run a Starlark file.
m = starlark.exec_file('''
def fact(n):
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

z = fact(5)
''')

m.globals["z"]  # 120

Users

  • dbohdan.com SSG: the site owner has switched the custom static site generator from TOML to Starlark for metadata reuse.
  • Lark Cycles: this Python/Tkinter/Starlark port of the 1988 Amiga programming game Warrior Cycles by Rico Mariana was developed as a demo for Starlark in Python.
  • Remarshal: a format converter between CBOR, JSON, MessagePack, TOML, and YAML 1.1 & 1.2. Remarshal gained the ability to modify the data it converted with Starlark. Part of the motivation for Starlark in Python was to add this functionality without a Go or Rust dependency.

API

See docs/.

CLI

The package installs a starlark-python console script. (We picked a suffixed name so it doesn't shadow starlark from go.starlark.net, which we use for cross-validation.) It can also be run as a zipapp:

poe zipapp                                 # builds ./starlark-python.pyz (~560K)
./starlark-python.pyz -c "1 + 2 * 3"       # 7
./starlark-python.pyz path/to/script.star

load() and the host API

The runtime does not load files itself; the host supplies a Loader callable. eval/loader.py ships a simple file-based loader you can plug in:

from starlark.eval.loader import FileLoader
import starlark

loader = FileLoader(exec_file=starlark.exec_file, search_paths=[".", "lib"])
starlark.exec_file(open("main.star").read(), loader=loader)

load("foo.star", "bar") then resolves foo.star against loader.

Security

Starlark in Python is new and has not been extensively reviewed and tested.

Starlark is a sandboxed language. A .star program cannot read or write files, open sockets, spawn processes, or reach any Python object the host did not explicitly hand it. Opt-on resource limits (max_steps, max_allocs) limit CPU and memory for hosts that accept untrusted input.

What we defend against, what we don't defend against, and the public limits API are documented in security/threat-model.md. In short: we mitigate DoS-style malicious values; defending against deliberately crafted (but otherwise valid) values is a host responsibility, the same as with JSON or TOML.

Documented divergences from the Java reference

These are intentional:

  • Integers are Python int. Arbitrary precision; no overflow. The Java reference uses a StarlarkInt type that is a union of int32, int64, and BigInteger.
  • Integer magnitude is bounded. A Starlark integer is hard-capped at MAX_INT_BITS = 2^19 bits (~158k decimal digits) to bound per-operation CPU. The Java reference's BigInteger is unbounded; this cap is far above any realistic configuration value, and operations that would exceed it raise a clean EvalError.
  • Strings are indexed by Unicode code point. The Java reference indexes by UTF-16 code unit, which produces surprising results for non-BMP characters. The spec leaves this implementation-defined.
  • No 32-bit range checks for range(), * repeat, etc. The Java reference rejects allocations whose length doesn't fit in a signed 32-bit int. We instead cap container allocations at 16M elements with a less specific error message.

The conformance suite includes a handful of tests that depend on the Java reference's exact error wording for these checks; they are listed in XFAIL_FILES in tests/test_conformance.py.

Layout

  • conformance/.star conformance tests, copied from Bazel.
  • src/starlark/ – The actual port.
    • eval/ – Value model, evaluator, builtins, methods, loader.
    • syntax/ – Lexer, parser, AST, resolver.
    • cmd.py – CLI entry point.
  • tests/ – Pytest suite (unit + conformance + property-based).
  • HISTORY.md – Original 14-phase plan + append-only journal.

Development

Install Poe the Poet to run the tasks (uv tool install poethepoet, pipx install poethepoet).

uv sync           # Install deps
poe test          # ~600 tests, ~3s
poe lint          # Ruff
poe typecheck     # Pyright
poe zipapp        # Build ./starlark-python.pyz

tests/test_cross_validation.py runs a curated set of programs under both this interpreter and the starlark-go CLI and asserts they produce identical output. To enable, install the Go implementation and make sure it's on PATH:

go install go.starlark.net/cmd/starlark@latest

License

Apache 2.0. See LICENSE.

This is a derivative work: the lexer, parser, resolver, evaluator, and value model are ported from the Java reference implementation maintained by The Bazel Authors as part of bazelbuild/bazel. The conformance test files under conformance/ are copied verbatim from that project. docs/spec.md is fetched verbatim from bazelbuild/starlark for reference.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

starlark-0.5.0.tar.gz (246.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

starlark-0.5.0-py3-none-any.whl (95.0 kB view details)

Uploaded Python 3

File details

Details for the file starlark-0.5.0.tar.gz.

File metadata

  • Download URL: starlark-0.5.0.tar.gz
  • Upload date:
  • Size: 246.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for starlark-0.5.0.tar.gz
Algorithm Hash digest
SHA256 321e1d07dffc8c89eb37945573a59e8e4a965a6f88cb87141010fdf52478eb91
MD5 602e66d2348da0e2cc733fbee452fe9e
BLAKE2b-256 0c1cf7bd41150c9ab4aa4bd02de46a0af88afa8d4da7af73e76aeb209e473ac2

See more details on using hashes here.

File details

Details for the file starlark-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: starlark-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 95.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: uv/0.11.14 {"installer":{"name":"uv","version":"0.11.14","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

File hashes

Hashes for starlark-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 001169e59b07a5c99d3c8799ef11359b02bec2413f7fa7db2d50e9fd84b5b7a3
MD5 aff589600d170e70fd9c600ea22f3d8a
BLAKE2b-256 1302a633594ec2bd1b6674fedc117fa9b987e1417d048c5c391397b536f4ad48

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page