Skip to content

feat: add InjectException mutation...#2

Draft
amirouche wants to merge 4 commits intodevfrom
mutation-inject-exception
Draft

feat: add InjectException mutation...#2
amirouche wants to merge 4 commits intodevfrom
mutation-inject-exception

Conversation

@amirouche
Copy link
Owner

...fix pytest_addoption double-registration

  • Add InjectException class: replaces expressions with the exception they can raise (ZeroDivisionError, KeyError, IndexError, ValueError, FileNotFoundError, StopIteration, AttributeError). Guarded against injecting inside try/except blocks that already handle the exception, and inside except blocks themselves.
  • Add --without-exception-injection flag to mutation play to skip all InjectException mutations cleanly.
  • Add ijk = 42 / a to foobar/ex.py to exercise the ZeroDivisionError mutation path in the check-foobar target.
  • Document InjectException in README.md with contracts table and example.
  • Fix pytest_addoption double-registration: catch ValueError when --mutation is already registered (conftest.py + -p mutation conflict), restoring make check-foobar functionality.

amirouche and others added 4 commits March 4, 2026 23:16
…e-registration

- Add InjectException class: replaces expressions with the exception
  they can raise (ZeroDivisionError, KeyError, IndexError, ValueError,
  FileNotFoundError, StopIteration, AttributeError). Guarded against
  injecting inside try/except blocks that already handle the exception,
  and inside except blocks themselves.
- Add --without-exception-injection flag to mutation play to skip all
  InjectException mutations cleanly.
- Add ijk = 42 / a to foobar/ex.py to exercise the ZeroDivisionError
  mutation path in the check-foobar target.
- Document InjectException in README.md with contracts table and example.
- Fix pytest_addoption double-registration: catch ValueError when
  --mutation is already registered (conftest.py + -p mutation conflict),
  restoring make check-foobar functionality.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
When mutating a file like schema/__init__.py, the module name in
sys.modules is "schema", not "schema.__init__". Without this fix every
mutation appeared to survive because the patched module was registered
under the wrong key and the test suite kept importing the original.

Two changes:
- Strip trailing __init__ component from the path before the sys.path
  search so the module is patched as "schema" not "schema.__init__".
- Also accept a package directory (has __init__.py) as a valid match
  during the sys.path walk, not just a plain .py file.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…eption-injection

The process pool executor cannot pickle local lambdas. Replace the
lambda in play_create_mutations with a top-level named function
mutation_without_inject_exception so it survives cross-process
serialisation.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…oader

The previous approach started from project-relative path components and
searched sys.path for a matching file, picking the first hit.  This
broke src/ layouts (e.g. src/itsdangerous/) where the project root
matched before the editable-install src/ entry, producing "src.pkg"
instead of "pkg".

New approach: resolve the mutation file to an absolute path, then test
every sys.path entry to see if the file falls under it.  The entry that
produces the *shortest* (most specific) module name wins, which
correctly handles both flat layouts and src/ layouts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
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.

1 participant