Developing Scenic¶
This page covers information useful if you will be developing Scenic, either changing the language itself or adding new built-in libraries or simulator interfaces.
Getting Started¶
Start by cloning our repository on GitHub and installing Poetry as described in Getting Started with Scenic. When using Poetry to install Scenic in your virtual environment, use the command poetry install -E dev to make sure you get all the dependencies needed for development.
To find documentation (and code) for specific parts of Scenic’s implementation, see our page on Scenic Internals.
Running the Test Suite¶
Scenic has an extensive test suite exercising most of the features of the language. We use the pytest Python testing tool. To run the entire test suite, run the command pytest inside the virtual environment from the root directory of the repository.
Some of the tests are quite slow, e.g. those which test the parsing and construction of
road networks. We add a --fast
option to pytest which skips such tests, while
still covering all of the core features of the language. So it is convenient to often run
pytest --fast as a quick check, remembering to run the full pytest
before making any final commits. You can also run specific parts of the test suite with a
command like pytest tests/syntax/test_specifiers.py, or use pytest’s -k
option to filter by test name, e.g. pytest -k specifiers.
Note that many of Scenic’s tests are probabilistic, so in order to reproduce a test
failure you may need to set the random seed. We use the
pytest-randomly plugin to help with
this: at the beginning of each run of pytest
, it prints out a line like:
Using --randomly-seed=344295085
Adding this as an option, i.e. running pytest --randomly-seed=344295085, will reproduce the same sequence of tests with the same Python/Scenic random seed.
Debugging¶
You can use Python’s built-in debugger pdb
to debug the parsing, compilation, sampling,
and simulation of Scenic programs. The Scenic command-line option -b
will cause the
backtraces printed from uncaught exceptions to include Scenic’s internals; you can also
use the --pdb
option to automatically enter the debugger on such exceptions.
It is possible to put breakpoints into a Scenic program using the Python built-in
function breakpoint
. Note however that since code in a Scenic program is not always
executed the way you might expect (e.g. top-level code is only run once, whereas code in
requirements can run every time we generate a sample: see How Scenic is Compiled), some care is needed when
interpreting what you see in the debugger. The same consideration applies when adding
print
statements to a Scenic program. For example, a top-level print(x)
will
not print out the actual value of x
every time a sample is generated: instead,
you will get a single print at compile time, showing the Distribution
object which
represents the distribution of x
(and which is bound to x
in the Python
namespace used internally for the Scenic module).