Skip to content

Defaults in a TOML file, with user override - #92

Merged
peterbjohnson merged 4 commits into
mainfrom
defaults-toml
Oct 27, 2026
Merged

peterbjohnson merged 4 commits into
mainfrom
defaults-toml

Conversation

@peterbjohnson

@peterbjohnson peterbjohnson commented Oct 26, 2026 •

Copy link
Copy Markdown
Member

Defaults have been moved to a single file, in2lambda/defaults.toml. The abstraction helps manage the package as defaults were previously buried in the code. A user can override any individual default by creating a TOML file of their own. Other cleanups are included in this PR.

The PR contains four separate commits that can be reviewed separately. To keep them separate on main, merge with a merge commit or rebase, not squash.

  1. Require Python 3.11. Python 3.10 reached end of life this month, and 3.11 reads TOML natively. CI now tests on 3.11 and 3.12.
  2. Remove JSON templates. Now that in2lambda creates every field accommodated by Lambda Feedback, JSON templates are not needed. Further, a placeholder part ("Part text here") that was written for a question with no parts is not needed. The writer now builds the JSON itself, and questions without parts contain no parts in the JSON.
  3. Defaults extracted to a single file. The defaults for sets, questions, all response areas and each response type are now in defaults.toml. A response type's own table takes precedence over the general [response_area] table.
  4. Let users override the defaults. Users can pass their own file with in2lambda.defaults.override(path) or in2lambda --defaults path. A file that isn't valid TOML, or that has an unknown key or a value of the wrong type, is rejected. The quickstart docs has a new section on defaults.

Behaviour changes for existing users (for the release notes):

  • Questions are published with the chatbot available.
  • Sets are created with chatbots available (note Module options still override, so chatbots are likely to be OFF across the whole module anyway; however, if switched on by the user at the Module level, they will become active rather than still hidden at the Set and Question level).
  • Sets are no longer hidden when imported, so with publish on they are visible to students straight away. This is probably the desired behaviour in most cases (uplaoded it, and students can see it; users can change this in their own TOML, or in the exported JSON, or on the platform after upload).
  • Response areas show a live preview and are included in the PDF, except for multi-line maths, which is left out of the PDF.
  • Single-line maths shows its input symbols.

The full list is in commit 3's message.

Tests: all 36 pass, and each commit also passes on its own. The new tests/test_defaults.py checks that a user's file changes only what it sets, and that each kind of mistake is refused without changing anything.

Message edited significantly by PBJ after being generated with 🤖 Claude Code. Code itself is all by Claude, overseen and reviewed by PBJ.

peterbjohnson and others added 4 commits October 25, 2026 17:22
Python 3.10 reached its end of life in October 2026, and 3.11 reads TOML
without a further dependency. The tests run on 3.11 and 3.12.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The two JSON templates held defaults of their own, which every write then
overwrote, and a placeholder part ("Part text here") that a question without
parts was written with. The writer now builds the JSON from the set and its
questions alone, and a question without parts is written with none.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The defaults of the set, the question, every response area and each
response type were spread across the classes and the JSON templates. They
are now in in2lambda/defaults.toml, which fills in each setting an author
leaves unset; a response type's own table comes before the one for every
response area. A response type without a default evaluation function needs
one from the author.

The defaults change: questions are published with the chatbot shown, the
set's chatbot is open, and sets are no longer hidden on import. Response
areas show a live preview and are included in the PDF, multi-line maths
aside, and single-line maths shows its input symbols.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
in2lambda.defaults.override(path), or `in2lambda --defaults path`, lays a
TOML file holding only the values to change over in2lambda's defaults. A
file that is not valid TOML, or that sets something in2lambda has no default
for or a value of the wrong type, is refused and changes nothing.

The quickstart says how, and shows in2lambda's defaults.toml as it stands.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@peterbjohnson peterbjohnson changed the title Keep every default in one TOML file, which users can override Defaults in a TOML file, with user override Oct 26, 2026

@m-messer m-messer left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like a good design for setting defaults at runtime.

From some research into UNSET, it uses the sentinel design pattern (https://python-patterns.guide/python/sentinel-object/), as the defaults are set after importing the library with the CLI command --defaults. To make it clearer, you could rename UNSET to FROM_DEFAULTS.

Comment thread in2lambda/defaults.py

def _key(name: str) -> str:
"""A field's key in the defaults, e.g. ``_chatbotVisibility`` -> ``chatbot_visibility``."""
return re.sub(r"(?<!^)([A-Z])", r"_\1", name.lstrip("_")).lower()

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This could be made clearer by not using regex

@peterbjohnson
peterbjohnson merged commit 8654735 into main Oct 27, 2026
4 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants