Generated trampoline names look like public members to tests that inspect classes (more visible since 3.8.0 mutates dataclasses)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 4/5
- Tempo stimato
- 3-5 giorni
- Idoneità per principianti
- 35/100
- Tipo di issue
- Funzionalità
- Chiarezza
- Abbastanza chiara
- Stato di attività
- Ferma
- Stack tecnologico
- python
- Ambito
- testing-qa
Direzione di ricerca
Start by reviewing mutmut.utils.format_utils.is_mutated_method_name and the generated names from mutmut.mutation.file_mutation, then inspect the related trampoline handling and README guidance. Compare the proposed filtering approach with the alternative of prefixing generated names, including mutant IDs and classmethod lookup. Done means the chosen behavior covers generated class and module members without breaking existing mutation workflows.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
Mutated modules and classes gain functions and dicts whose names don't start with an underscore, such as x_span__mutmut_orig, xǁDateRangeǁ__post_init____mutmut_1 and mutants_x_span__mutmut. Any test that walks vars(), dir() or inspect.getmembers() and treats names without a leading _ as public API sees them as undocumented public members.
This isn't new, but 3.8.0 started mutating @dataclass methods (#480, #539), so it now reaches classes it didn't before. In our project, a test that checks every public member of the exported classes has a docstring started failing in the stats run after upgrading to 3.8.0. The stats pass stopped with exit code 2, so no mutants were tested at all.
Reproduction (mutmut 3.8.0)
import inspect, types
from mutmut.mutation.file_mutation import mutate_file_contents
src = '''
from dataclasses import dataclass
@dataclass
class DateRange:
"""A closed date interval."""
start: int
end: int
def __post_init__(self):
if self.end < self.start:
raise ValueError("end before start")
def span(r):
"""Length of the range."""
return r.end - r.start + 1
'''
mod = types.ModuleType("demo")
exec(compile(mutate_file_contents("demo.py", src).code, "demo.py", "exec"), mod.__dict__)
public = lambda ns: sorted(n for n in ns if not n.startswith("_"))
print(public(vars(mod.DateRange)))
print(public(vars(mod)))
Output:
['xǁDateRangeǁ__post_init____mutmut_1', 'xǁDateRangeǁ__post_init____mutmut_2', 'xǁDateRangeǁ__post_init____mutmut_3', 'xǁDateRangeǁ__post_init____mutmut_4', 'xǁDateRangeǁ__post_init____mutmut_orig']
['DateRange', 'MutantDict', 'dataclass', 'mutants_x_span__mutmut', 'mutants_xǁDateRangeǁ__post_init____mutmut', 'span', 'x_span__mutmut_1', 'x_span__mutmut_2', 'x_span__mutmut_3', 'x_span__mutmut_orig']
The copies of __post_init__ have no docstring. The original is a dunder, so docstring checks usually skip it, but the copies' names aren't dunders.
Options
- Prefix generated names with
_. This is the real fix, but the mangled names are also the mutant IDs inmutmut show,mutmut apply, the stats and meta files, andis_mutated_method_name. Classmethod dispatch also looks the copies up by name withgetattr. It would change every mutant ID, so it's your call whether that's worth it. - Give users a supported way to filter the names. Our workaround copies the logic of
mutmut.utils.format_utils.is_mutated_method_name, which isn't public API and doesn't cover themutants_...dicts. A public predicate plus a README note fixes this without changing any names.
I've opened a PR for option 2. It's small and doesn't break anything, and it doesn't rule out option 1 later.
MutantDict also shows up as a module attribute. It comes from the generated from mutmut.mutation.trampoline import ... MutantDict import. The PR doesn't filter it, because MutantDict is a name user code could also define. Importing it under an alias like _MutantDict would fix that, if you want it.
AI disclosure: Claude Code (Anthropic) did the investigation and wrote this issue and the reproduction, and posted it on my account at my request.
- Lingua principale
- Python
- Stelle
- 1.5k
- Fork
- 179
- Merge medio
- 1g 18h
- PR unite (30g)
- 6
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Nessun modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di boxed/mutmut
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
I maintainer di solito rispondono entro 1 giorno
-
Invalid unary plus generated in match statementForse già presa @GhostCoder6969 l’ha presa 8 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
I maintainer di solito rispondono entro 1 giorno
-
What do the emoji's mean?Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
boxed/mutmut#560 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
boxed/mutmut#529 · 7 commenti ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 64/100
boxed/mutmut#503 · 4 commenti ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di boxed/mutmut
Issue simili
-
first
Difficoltà 2/5 1-3 ore Idoneità per principianti 72/100
AcademySoftwareFoundation/rmtc#54 · 1 commento ·
-
feature/cohorts feature/feature-flags team/feature-flags
Difficoltà 2/5 1-3 ore Idoneità per principianti 74/100
I maintainer di solito rispondono entro 1 giorno
-
License examples/ as MITForse già presa @PGrayCS l’ha presa oggi. Apertadocumentation enhancement example good first issue
Difficoltà 2/5 1-3 ore Idoneità per principianti 84/100
speedyk-005/yasbd-lib#383 ·
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 68/100
interactions-py/interactions.py#1827 ·
-
Managed start can fail when OpenVMM reads its control capability before NVX writes itForse già presa @ppenna l’ha presa oggi. Apertabug
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
I maintainer di solito rispondono entro 1 giorno