Add scenic.setSeed() public API#454
Closed
KE7 wants to merge 1 commit intoBerkeleyLearnVerify:mainfrom
Closed
Conversation
Expose the seeding logic that the -s/--seed CLI option already uses as a module-level function, so Scenic scenarios can be made deterministic from Python code without touching `random` / `numpy.random` directly. Motivation: docs/api.rst currently teaches users to call `random.seed(n)` directly to get deterministic generation, which is incomplete (it does not seed numpy.random, so any distribution backed by numpy's RNG still drifts) and exposes an implementation detail. Meanwhile, `scenic/__main__.py` already does the right thing for the CLI: it seeds both `random` and `numpy.random`. This PR turns that into a named API following the same pattern as the existing `scenic.setDebuggingOptions` (added in 9b9c850). Changes: - `scenic/__init__.py`: add `setSeed(seed)`, documented, that seeds both `random` and `numpy.random`. - `scenic/__main__.py`: replace the inline `random.seed(args.seed); numpy.random.seed(args.seed)` block with `scenic.setSeed(args.seed)`, and drop the now-unused `import random` / `import numpy` at the top. Single source of truth for how `--seed` works. - `tests/syntax/test_basic.py`: add `test_setSeed` next to `test_verbose`, mirroring the existing `tests/test_main.py::test_seed` CLI-level structure (same seed → same sample; different seed → different sample). - `docs/api.rst`: document the new API with `.. autofunction::` and update the testcode example to use `scenic.setSeed(12345)` instead of `random.seed(12345)`. Expected output is unchanged — the example's `foo Range(0, 5)` is the same whether you seed via `random.seed` alone or via `scenic.setSeed` (verified locally). - `docs/options.rst`: add the standard "can be configured from the Python API using `scenic.setSeed`" cross-reference to the `-s`/`--seed` entry, matching the pattern already used for `scenic.setDebuggingOptions`. Local CI sign-off: - black 25.1.0 + isort 5.12.0 clean on all touched .py files - pytest --fast --no-graphics: 1444 passed, 538 skipped, 3 xfailed - pytest --no-graphics (slow, incl. tests/test_docs.py::test_build_docs): clean - tests/test_main.py::test_seed (verifies the __main__.py refactor): passes
Collaborator
|
Closed as feature is already being added in #422. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Exposes the seeding logic that the
-s/--seedCLI option already uses as a module-level function, so Scenic scenarios can be made deterministic from Python code without touchingrandom/numpy.randomdirectly.Motivation
docs/api.rstcurrently teaches users to callrandom.seed(n)directly to get deterministic generation:This is both:
random; it does not seednumpy.random, so any distribution backed by numpy's RNG (and anything that goes through numpy downstream) still drifts across runs.Meanwhile,
scenic/__main__.pyalready does the right thing for the CLI:This PR turns that into a named API —
scenic.setSeed(seed)— following the same pattern as the existingscenic.setDebuggingOptions, which was added in commit 9b9c850 ("unify control of debugging options; more docs"). Same structural precedent: ascenic.set*(...)public function wrapping CLI-equivalent behavior, documented with.. autofunction::inapi.rstand cross-referenced fromoptions.rst.I also hit this flakiness myself while using Scenic in a downstream project — having to remember "seed both random and numpy" kept being the wrong answer when constraints got tight enough to make rejection sampling probabilistic.
Changes
src/scenic/__init__.pysetSeed(seed), documented, that seeds bothrandomandnumpy.random.src/scenic/__main__.pyrandom.seed(args.seed); numpy.random.seed(args.seed)block withscenic.setSeed(args.seed). Drop the now-unusedimport random/import numpyat the top. Single source of truth for how--seedworks.tests/syntax/test_basic.pytest_setSeednext totest_verbose, mirroring the existingtests/test_main.py::test_seedCLI-level structure (same seed → same sample; different seed → different sample). Uses the existingsampleParamPFromhelper.docs/api.rst.. autofunction::and update the testcode example to usescenic.setSeed(12345)instead ofrandom.seed(12345). Expected output is unchanged — verified locally thatRange(0, 5)produces the samefoo = 2.083099362726706either way.docs/options.rst-s/--seedentry, matching the existing pattern forscenic.setDebuggingOptions.Net: +45 / -7 across 5 files.
Non-goals / deliberately out of scope
seed=kwarg onScenario.generate(). That's a bigger design question (per-call scoping vs. global) and would stall review. This PR is strictly CLI-parity.random.Random()instance. Keeping the global-RNG semantics matches the CLI exactly and means this PR is pure refactor + API exposure, not a behavior change.Test plan
Ran locally against this branch (Linux, Python 3.11,
pip install -e ".[test-full]"in a fresh venv):black --check/isort --check-onlyon all touched.pyfiles — clean (versions match.github/workflows/check-formatting.yml: black 25.1.0, isort 5.12.0)pytest --fast --no-graphics(matches.github/workflows/run-tests.yml): 1444 passed, 538 skipped, 3 xfailed, 0 failurespytest --no-graphics(slow suite, includingtests/test_docs.py::test_build_docswhich builds the Sphinx docs viamake htmlwith-W): passes after thedocs/api.rst+docs/options.rstupdatestests/test_main.py::test_seed(CLI-level, verifies the__main__.pyrefactor): passestests/syntax/test_basic.py::test_setSeed(new): passes — determinism and variation-across-seeds both hold🤖 Generated with Claude Code