Skip to content

Python in cells

Expanse evaluates Python cell formulas through Monty, a Python runtime sandboxed in Rust. Write Python directly with the =PY(…) kernel, or as an expression that references cells.

=PY("[x * x for x in range(5)]") # spills 0, 1, 4, 9, 16 down the column

Standard Python: +, -, *, /, //, %, **, comparisons (==, <, >=, …), and and / or / not.

  • Type conversion: int(), float(), str(), bool()
  • Collections: list(), dict(), tuple(), set()
  • Iteration: len(), range(), enumerate(), zip(), reversed()
  • Aggregation: min(), max(), sum(), all(), any()
  • Functional: map(), filter(), sorted()

List comprehensions, generator expressions, and lambda all work.

math is available with no import statement: Expanse prepends it when it sees math. in your formula:

=math.sqrt(16) # 4.0
=math.pi * 2 # ~6.283

Cell references become inputs to your code. =A1 + B1 receives both cell values; a range like A1:A48 expands to its individual cells. You write ordinary references: the wiring is invisible.

Return a Python list and it spills into the neighbouring cells, Excel-style:

=[1, 2, 3, 4] # spills down 4 rows
=[x * 1.1 for x in A1:A12] # a scaled copy of the column

Define a function in a code cell, then call it from formula cells:

def margin(rev, cost):
return (rev - cost) / rev
=margin(B2, C2)

Cells run in a locked-down sandbox. The following are not available:

  • File access: open() is blocked and returns a sandbox error.
  • Network: no HTTP, sockets, or other I/O.
  • numpy / pandas / polars: not bundled in the in-cell runtime today. For heavy numeric work, use SQL (=SQL(…)) over large ranges, or watch this space: richer scientific Python is on the roadmap, not in cells yet.
  • Most of the standard library: only math is pre-wired. Other modules are not guaranteed.

Python errors surface in the cell with their real message (for example ZeroDivisionError: division by zero) rather than a generic spreadsheet error code, so you can debug in place.