@@ -53,8 +53,33 @@ it will try to figure out where the code to mutate is.
5353
5454
5555You can stop the mutation run at any time and mutmut will restart where you
56- left off. It will continue where it left off, and re-test functions that were
57- modified since last run.
56+ left off.
57+
58+ Incremental Testing
59+ ~~~~~~~~~~~~~~~~~~~
60+
61+ Mutmut is designed for incremental workflows. It remembers which mutants have
62+ been tested and their results, so subsequent runs skip already-tested mutants.
63+
64+ **Function-level change detection: ** Mutmut computes a hash of each function's
65+ source code. When you modify a function, mutmut detects the change and
66+ automatically re-tests all mutants in that function. Unchanged functions keep
67+ their previous results.
68+
69+ **Limitation: ** Change detection only tracks direct function changes, not
70+ transitive dependencies. If function A calls function B, and you modify B,
71+ mutants in A are not automatically re-tested. For significant changes to
72+ shared utilities, use ``mutmut run "module*" `` to re-test affected modules,
73+ or delete the ``mutants/ `` directory for a full re-run.
74+
75+ This means you can:
76+
77+ - Run ``mutmut run ``, stop partway through, and continue later
78+ - Modify your source code and re-run - only changed functions are re-tested
79+ - Update your tests and use ``mutmut browse `` to selectively re-test mutants
80+
81+ The mutation data is stored in the ``mutants/ `` directory. Delete this
82+ directory to start completely fresh.
5883
5984To work with the results, use `mutmut browse ` where you can see the mutants,
6085retest them when you've updated your tests.
@@ -226,6 +251,92 @@ whitelist lines are:
226251 to continue, but it's slower.
227252
228253
254+ Enum Classes and Metaclass Compatibility
255+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
256+
257+ Mutmut 3.x fully supports mutating enum classes. Methods inside enum classes
258+ (``Enum ``, ``IntEnum ``, ``Flag ``, ``IntFlag ``, ``StrEnum ``) are automatically
259+ mutated using an external injection pattern that avoids conflicts with the
260+ enum metaclass.
261+
262+ This means enums with methods like:
263+
264+ .. code-block :: python
265+
266+ from enum import Enum
267+
268+ class Color (Enum ):
269+ RED = 1
270+ GREEN = 2
271+
272+ def describe (self ):
273+ return self .name.lower()
274+
275+ @ staticmethod
276+ def count ():
277+ return 3
278+
279+ ...will have their methods mutated just like regular class methods.
280+
281+ **Disabling Enum Mutation **
282+
283+ If you prefer to skip enum mutation entirely, you can disable it in your config:
284+
285+ .. code-block :: toml
286+
287+ # pyproject.toml
288+ [tool.mutmut]
289+ mutate_enums = false
290+
291+ Or skip a specific enum class using the pragma:
292+
293+ .. code-block :: python
294+
295+ class Color (Enum ): # pragma: no mutate class
296+ RED = 1
297+ GREEN = 2
298+
299+ def describe (self ):
300+ return f " Color is { self .name} "
301+
302+ This tells mutmut to completely skip the class—no mutations will be created
303+ for any methods.
304+
305+ Both syntax styles are supported:
306+
307+ - ``# pragma: no mutate class ``
308+ - ``# pragma: no mutate: class ``
309+
310+ **Note: ** The regular ``# pragma: no mutate `` on a class line only prevents
311+ mutations on that specific line. It does NOT prevent mutations inside methods.
312+ Use ``# pragma: no mutate class `` to skip the entire class (kept for backward
313+ compatibility with <v3.5.0).
314+
315+
316+ Skipping Entire Functions
317+ ~~~~~~~~~~~~~~~~~~~~~~~~~
318+
319+ Similarly, you can skip an entire function from mutation using
320+ ``# pragma: no mutate function ``:
321+
322+ .. code-block :: python
323+
324+ def complex_algorithm (): # pragma: no mutate function
325+ # This function won't be mutated at all
326+ return some_complex_calculation()
327+
328+ Both syntax styles are supported:
329+
330+ - ``# pragma: no mutate function ``
331+ - ``# pragma: no mutate: function ``
332+
333+ This is useful for functions that:
334+
335+ - Have complex side effects that make mutation testing impractical
336+ - Are performance-critical and you want to avoid trampoline overhead
337+ - Are known to cause issues with the mutation testing framework
338+
339+
229340Modifying pytest arguments
230341~~~~~~~~~~~~~~~~~~~~~~~~~~
231342
0 commit comments