• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

source-academy / py-slang / 31229644468
86%

Build:
DEFAULT BRANCH: main
Ran 08 Aug 2026 12:35AM UTC
Jobs 1
Files 138
Run time 1min
Badge
Embed ▾
README BADGES
x

If you need to use a raster PNG badge, change the '.svg' to '.png' in the link

Markdown

Textile

RDoc

HTML

Rst

08 Aug 2026 12:16AM UTC coverage: 86.472% (+0.07%) from 86.402%
31229644468

push

github

web-flow
Stepper: let a module call back into a Python function it was handed (#424)

* Stepper: let a module call back into a Python function it was handed

py-slang#423: `connect_ends(diagonal, diagonal)`, where diagonal is a
Python-authored def whose own body calls another module function
(make_point), worked fine in Py2JS but failed in the stepper with "a
Python function value cannot be passed to an imported module function
here" -- moduleInterop.ts's stepNodeToModule refused to convert a
lambda/def (or a bare builtin reference) into a module argument at
all, by design: doing so would need the module to call back into
Python mid-call, which the substitution reducer had no way to do
without re-entering its own step machinery.

It turns out it does, and much more simply than CSE's control/stash
re-entrant loop or py2js's own async interpreter recursion need: the
substitution model's only notion of "run this to completion" is
already just repeated one-step reduceExpr contraction, exactly what
the outer step sequence itself runs on (getSteps.ts's drive). reduce.ts's
new applyPythonCallable reuses that same loop, scoped to a single call
expression, to fully reduce fn(...args) to a value -- producing no
visible steps of its own, since this happens entirely inside one
contraction of the outer sequence (the module call this callback is
answering).

moduleInterop.ts's stepNodeToModule now wraps a genuine Python
callable in a module closure (pythonCallableToModule) instead of
throwing, whose body converts the module's arguments back to Python
values, calls applyPythonCallable, and converts the result back --
threaded in as a plain callback (not imported directly) to avoid a
circular reduce.ts <-> moduleInterop.ts dependency. Because this
reuses the ordinary reducer, a callback whose own body calls a
*different* module function (the issue's exact repro) or hits a
genuine Python-level error (ZeroDivisionError, say) both just work,
with no special-casing needed for eit... (continued)

4823 of 6015 branches covered (80.18%)

Branch coverage included in aggregate %.

41 of 43 new or added lines in 3 files covered. (95.35%)

10774 of 12022 relevant lines covered (89.62%)

164187.03 hits per line

Uncovered Changes

Lines Coverage ∆ File
1
84.36
4.71% src/conductor/stepper/moduleInterop.ts
1
94.95
-0.11% src/conductor/stepper/reduce.ts
Jobs
ID Job ID Ran Files Coverage
1 31229644468.1 08 Aug 2026 12:35AM UTC 138
86.47
GitHub Action Run
Source Files on build 31229644468
  • Tree
  • List 138
  • Changed 4
  • Source Changed 3
  • Coverage Changed 4
Coverage ∆ File Lines Relevant Covered Missed Hits/Line Branch Hits Branch Misses
  • Back to Repo
  • Github Actions Build #31229644468
  • 0166ee08 on github
  • Prev Build on main (#31165450514)
  • Next Build on main (#31236306643)
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE TRIAL · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc