Skip to content

fix(task): reject boolean max_steps values during task validation - #183

Merged
jeqcho merged 2 commits into
robocurve:mainfrom
Adityakk9031:fix/task-bool-validation
Jul 29, 2026
Merged

fix(task): reject boolean max_steps values during task validation#183
jeqcho merged 2 commits into
robocurve:mainfrom
Adityakk9031:fix/task-bool-validation

Conversation

@Adityakk9031

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #161 as requested by @jeqcho in #161 (comment).

Because bool is a subclass of int in Python (isinstance(True, int) == True), Task(max_steps=True) previously bypassed validation and was silently treated as a 1-step horizon (max_steps=1).

This PR explicitly checks isinstance(self.max_steps, bool) in Task.__post_init__ and raises ConfigError.


Changes

  • inspect_robots.task.Task: Reject boolean max_steps values during __post_init__ validation.
  • tests/test_types_spaces.py: Added parameterized test test_task_rejects_invalid_steps_horizon testing [True, 0, -1].
  • CHANGELOG.md: Added entry under ## [Unreleased] -> ### Fixed.

Checklist

  • pre-commit run --all-files passes
  • Tests added/updated
  • Coverage stays at 100%
  • ruff check . and ruff format --check . pass
  • Strict mypy passes
  • CHANGELOG.md updated under "Unreleased"

Related

Follow-up to #161 (comment) / #160

@Adityakk9031

Copy link
Copy Markdown
Contributor Author

@jeqcho follow up pr

@jeqcho jeqcho left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Thanks for the quick follow-up on the #161 review note — this closes the bool-as-int loophole cleanly, and the scope is exactly what was asked for.

What I checked:

  • Correctness (src/inspect_robots/task.py:78): isinstance(self.max_steps, bool) or self.max_steps < 1 is right. True (previously accepted as a silent 1-step horizon) is now rejected, and False — which the old < 1 check already caught — still raises the same error. Putting the isinstance check first also mirrors the structure of the max_seconds guard directly below it (task.py:80-84), so the two horizon validations now read the same way.
  • Error message: reusing the existing "max_steps must be >= 1, got True" message rather than inventing a new one keeps things consistent and avoids churn in anything matching on it. (Strictly speaking True >= 1 is numerically true, but the sibling max_seconds message has the same quirk for True, so this is the established convention here.)
  • Tests (tests/test_types_spaces.py:147-158): the parameterization [True, 0, -1] covers the new bool branch plus both sides of the numeric boundary, and the test mirrors the style of test_task_rejects_invalid_seconds_horizon right next to it (local imports, pytest.raises(..., match=...)). Nice symmetry.
  • CHANGELOG: entry is accurate and correctly placed under ## [Unreleased] / ### Fixed.
  • Verification: full CI matrix is green; tests in tests/test_types_spaces.py also pass locally (30 passed).

Two optional nits, neither blocking:

  1. src/inspect_robots/task.py:78 sits at 99 characters against the 100-char limit. Wrapping the condition across lines like the max_seconds check below it would make the two guards visually parallel, but ruff is satisfied as-is.
  2. Not for this PR, but the same bool-is-int hole still exists in Epochs.__post_init__ (task.py:31-33): Task(epochs=True) currently validates as a 1-epoch spec. Might be worth a tiny follow-up issue for the same strictness there.

Approving — thanks for the contribution!

@jeqcho
jeqcho merged commit 0539e15 into robocurve:main Jul 29, 2026
19 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