6161
6262# Document: surviving mutants are retested when you ask mutmut to retest them, interactively in the UI or via command line
6363
64- # TODO: only count a test for a function if the stack depth to get to the test < some configurable limit.
65-
66- # TODO: collect tests always: first run we collect to update the known list of tests, then we run pytest with that list for stats
67- # - when we run again, we ask for all tests, check which are new and which are gone and update by running stats collection for just these
6864# TODO: pragma no mutate should end up in `skipped` category
6965# TODO: hash of function. If hash changes, retest all mutants as mutant IDs are not stable
70- # TODO: exclude mutating static typing
71- # TODO: implement timeout
72-
73- # TODO: don't remove arguments to `isinstance`, as that will always fail. Same with `len`
7466
7567
7668NEVER_MUTATE_FUNCTION_NAMES = {'__getattribute__' , '__setattr__' }
@@ -182,6 +174,8 @@ class CollectTestsFailedException(Exception):
182174class BadTestExecutionCommandsException (Exception ):
183175 pass
184176
177+
178+ # noinspection PyUnresolvedReferences
185179# language=python
186180trampoline_impl = """
187181from inspect import signature as _mutmut_signature
@@ -693,6 +687,7 @@ def new_tests(self):
693687
694688
695689class PytestRunner (TestRunner ):
690+ # noinspection PyMethodMayBeStatic
696691 def execute_pytest (self , params , ** kwargs ):
697692 import pytest
698693 params += ['--rootdir=.' ]
@@ -858,6 +853,7 @@ def collect_stat(m: SourceFileMutationData):
858853 for k in status_by_exit_code .values ()
859854 }
860855 for k , v in m .exit_code_by_key .items ():
856+ # noinspection PyTypeChecker
861857 r [status_by_exit_code [v ].replace (' ' , '_' )] += 1
862858 return Stat (
863859 ** r ,
@@ -916,6 +912,7 @@ def write(self, s):
916912 return len (s )
917913 self .redirect = StdOutRedirect (self )
918914
915+ # noinspection PyMethodMayBeStatic
919916 def stop (self ):
920917 sys .stdout = sys .__stdout__
921918 sys .stderr = sys .__stderr__
@@ -930,8 +927,8 @@ def start(self):
930927
931928 def dump_output (self ):
932929 self .stop ()
933- for l in self .strings :
934- print (l , end = '' )
930+ for line in self .strings :
931+ print (line , end = '' )
935932
936933 def __enter__ (self ):
937934 self .start ()
@@ -965,6 +962,7 @@ def config_reader():
965962 if sys .version_info >= (3 , 11 ):
966963 from tomllib import loads
967964 else :
965+ # noinspection PyPackageRequirements
968966 from toml import loads
969967 data = loads (path .read_text ('utf-8' ))
970968
@@ -1544,12 +1542,14 @@ def compose(self):
15441542
15451543 def on_mount (self ):
15461544 # files table
1545+ # noinspection PyTypeChecker
15471546 files_table : DataTable = self .query_one ('#files' )
15481547 files_table .cursor_type = 'row'
15491548 for key , label in self .columns :
15501549 files_table .add_column (key = key , label = label )
15511550
15521551 # mutants table
1552+ # noinspection PyTypeChecker
15531553 mutants_table : DataTable = self .query_one ('#mutants' )
15541554 mutants_table .cursor_type = 'row'
15551555 mutants_table .add_columns ('name' , 'status' )
@@ -1571,6 +1571,7 @@ def read_data(self):
15711571 self .source_file_mutation_data_and_stat_by_path [p ] = source_file_mutation_data , stat
15721572
15731573 def populate_files_table (self ):
1574+ # noinspection PyTypeChecker
15741575 files_table : DataTable = self .query_one ('#files' )
15751576 # TODO: restore selection
15761577 selected_row = files_table .cursor_row
@@ -1581,14 +1582,15 @@ def populate_files_table(self):
15811582 Text (str (getattr (stat , k .replace (' ' , '_' ))), justify = "right" )
15821583 for k , _ in self .columns [1 :]
15831584 ]
1584- files_table .add_row (* row , key = p )
1585+ files_table .add_row (* row , key = str ( p ) )
15851586
15861587 files_table .move_cursor (row = selected_row )
15871588
15881589 def on_data_table_row_highlighted (self , event ):
15891590 if not event .row_key or not event .row_key .value :
15901591 return
15911592 if event .data_table .id == 'files' :
1593+ # noinspection PyTypeChecker
15921594 mutants_table : DataTable = self .query_one ('#mutants' )
15931595 mutants_table .clear ()
15941596 source_file_mutation_data , stat = self .source_file_mutation_data_and_stat_by_path [event .row_key .value ]
@@ -1599,7 +1601,8 @@ def on_data_table_row_highlighted(self, event):
15991601 mutants_table .add_row (k , emoji_by_status [status ], key = k )
16001602 else :
16011603 assert event .data_table .id == 'mutants'
1602- diff_view = self .query_one ('#diff_view' )
1604+ # noinspection PyTypeChecker
1605+ diff_view : Static = self .query_one ('#diff_view' )
16031606 if event .row_key .value is None :
16041607 diff_view .update ('' )
16051608 else :
@@ -1629,6 +1632,7 @@ def retest(self, pattern):
16291632 self .populate_files_table ()
16301633
16311634 def get_mutant_name_from_selection (self ):
1635+ # noinspection PyTypeChecker
16321636 mutants_table : DataTable = self .query_one ('#mutants' )
16331637 if mutants_table .cursor_row is None :
16341638 return
@@ -1646,6 +1650,7 @@ def action_retest_module(self):
16461650
16471651 def action_apply_mutant (self ):
16481652 read_config ()
1653+ # noinspection PyTypeChecker
16491654 mutants_table : DataTable = self .query_one ('#mutants' )
16501655 if mutants_table .cursor_row is None :
16511656 return
0 commit comments