Repository navigation
Conversation
`typing.override` (PEP 698) returns the function itself and only sets `__override__`, so copying it onto the trampoline and the mutants has none of the side effects the decorator rule guards against. It is now allowed on its own and stacked with `@staticmethod` / `@classmethod`; any other decorator still keeps the function out. The classmethod detection of the trampoline looks at every decorator, so a `@classmethod @override` method still binds to the subclass it is called on. Refs boxed#387 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Contributor
|
It would be good to have this; then maybe I can get rid of some of my monkeypatching. FYI, my combination so far is: ALLOWED = frozenset({"property", "abstractmethod", "register", "override"})
"""Decorators safe to apply again to a copied function body, as they do not cache a result or register a second time"""
NATIVE = frozenset({"staticmethod", "classmethod"})
"""Decorators instrumented by mutmut when alone, with `classmethod` bound through an argument of mutmut's trampoline"""This PR covers the combination of |
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.
Refs #387.
Problem
Since #476, a method with a single
@staticmethod/@classmethodis mutated; any other decorator keeps it out. In a typed codebase checked with mypy'sexplicit-override(or pyright'sreportImplicitOverride), every overriding method carries@typing.override(PEP 698), so all of them silently drop out of mutation testing. Reproduction onmain(857019a):Plain.areagets 3 mutants;Marked.area, identical apart from the decorator, gets none. In our project that was ~213 mutants across six modules.Change
overrideis allowed, alone or stacked with@staticmethod/@classmethod, in the forms@override,@typing.overrideand@typing_extensions.override. None of the reasons in the decorator rule applies to it: it returns the function itself, only setting__override__; it takes no arguments; it does not change the signature. The trampoline setup already copies the decorators onto the trampoline and the mutants, so nothing else changes there, except that the classmethod detection now looks at every decorator, so@classmethod @overridestill binds to the subclass (is_classmethod).Any other decorator still keeps the function out, including
overridecombined with@property, and the attribute form on another module (@other.override).Tests
test_mutate_override_methods: the three spellings, and stacked withstaticmethod/classmethod(red onmain).test_do_not_mutate_override_methods_with_other_decorators: the neighbours that must stay skipped.test_override_classmethod_subclass_runtime: a@classmethod @overridecalled through a subclass, with the mutant active and inactive, and the__override__marker kept (red onmain; also red if only the skip rule changes and the classmethod detection does not).Full suite: 483 passed, 4 skipped; pre-commit clean.
A possible follow-up
This only covers
override. The general direction @Otto-AA proposed in #387 (decorators kept on the trampoline only, mutants left undecorated) would cover most other decorators too; I'd be happy to work on it if you want to go that way, but it seemed better as a separate change with its own design discussion.🤖 Generated with Claude Code