@@ -40,7 +40,7 @@ def get_rss_mb():
4040 except Exception :
4141 return 0.0
4242
43- def run_worker (target_module ):
43+ def run_worker (target_module , skip_line_count = False ):
4444 """Performs ONE import and returns metrics."""
4545 tracemalloc .start ()
4646 importlib .invalidate_caches ()
@@ -66,33 +66,36 @@ def run_worker(target_module):
6666 new_modules = modules_after - modules_before
6767
6868 loaded_lines = 0
69- for m in new_modules :
70- try :
71- file_path = sys .modules [m ].__file__
72- if not file_path :
73- continue
69+ if not skip_line_count :
70+ for m in new_modules :
71+ try :
72+ file_path = sys .modules [m ].__file__
73+ if not file_path :
74+ continue
7475
75- if file_path .endswith ('.pyc' ):
76- try :
77- file_path = importlib .util .source_from_cache (file_path )
78- except ValueError :
79- # Raised if the .pyc path does not follow standard PEP 3147/488 conventions.
80- # We pass silently because the unresolved file_path will still end in '.pyc',
81- # meaning the subsequent '.endswith('.py')' check will fail and safely skip
82- # trying to count lines in a binary file.
83- pass
84- if file_path .endswith ('.py' ):
85- try :
86- with open (file_path , 'r' , encoding = 'utf-8' , errors = 'ignore' ) as f :
87- loaded_lines += sum (1 for _ in f )
88- except OSError as e :
89- print (f"WARNING: Failed to read lines from { file_path } : { e } " , file = sys .stderr )
90- except KeyError :
91- # Module disappeared from sys.modules during execution
92- pass
93- except AttributeError :
94- # Module has no __file__ attribute (likely a C-extension or built-in)
95- pass
76+ if file_path .endswith ('.pyc' ):
77+ try :
78+ file_path = importlib .util .source_from_cache (file_path )
79+ except ValueError :
80+ # Raised if the .pyc path does not follow standard PEP 3147/488 conventions.
81+ # We pass silently because the unresolved file_path will still end in '.pyc',
82+ # meaning the subsequent '.endswith('.py')' check will fail and safely skip
83+ # trying to count lines in a binary file.
84+ pass
85+ if file_path .endswith ('.py' ):
86+ try :
87+ with open (file_path , 'r' , encoding = 'utf-8' , errors = 'ignore' ) as f :
88+ loaded_lines += sum (1 for _ in f )
89+ except OSError as e :
90+ print (f"WARNING: Failed to read lines from { file_path } : { e } " , file = sys .stderr )
91+ except KeyError :
92+ # Module disappeared from sys.modules during execution
93+ pass
94+ except AttributeError :
95+ # Module has no __file__ attribute (likely a C-extension or built-in)
96+ pass
97+ else :
98+ loaded_lines = - 1
9699
97100 # Output to stdout for the Master to capture
98101 metrics = {
@@ -106,6 +109,8 @@ def run_worker(target_module):
106109
107110def _run_worker_and_parse (cmd ):
108111 result = subprocess .run (cmd , capture_output = True , text = True , check = True )
112+ if result .stderr .strip ():
113+ print (result .stderr .strip (), file = sys .stderr )
109114 try :
110115 lines = result .stdout .strip ().splitlines ()
111116 data = None
@@ -185,6 +190,8 @@ def run_master(iterations, target_module, cpu=0, csv_path=None, clear_cache=True
185190 cmd += ["taskset" , "-c" , str (cpu )]
186191
187192 cmd += python_exe + [__file__ , "--worker" , f"--module={ target_module } " ]
193+ if i > 0 :
194+ cmd += ["--skip-line-count" ]
188195
189196 try :
190197 data = _run_worker_and_parse (cmd )
@@ -194,11 +201,12 @@ def run_master(iterations, target_module, cpu=0, csv_path=None, clear_cache=True
194201 print (f"Iteration { i + 1 } /{ iterations } completed in { data ['time_ms' ]:.2f} ms" )
195202 if i > 0 and loaded_modules_val != data ["loaded_modules" ]:
196203 print (f"WARNING: Non-deterministic import behavior! Iteration { i + 1 } loaded { data ['loaded_modules' ]} modules (expected { loaded_modules_val } )." , file = sys .stderr )
197- if i > 0 and loaded_lines_val != data ["loaded_lines" ]:
198- print (f"WARNING: Non-deterministic import behavior! Iteration { i + 1 } loaded { data ['loaded_lines' ]} lines (expected { loaded_lines_val } )." , file = sys .stderr )
199204
200205 loaded_modules_val = data ["loaded_modules" ]
201- loaded_lines_val = data ["loaded_lines" ]
206+ if data ["loaded_lines" ] == - 1 :
207+ data ["loaded_lines" ] = loaded_lines_val
208+ else :
209+ loaded_lines_val = data ["loaded_lines" ]
202210 except FileNotFoundError as e :
203211 if cpu != NO_CPU_PINNING and cmd and cmd [0 ] == "taskset" :
204212 print ("ERROR: 'taskset' command not found. CPU pinning is enabled but taskset is not installed. "
@@ -442,6 +450,7 @@ def find_module_from_package(pkg):
442450 parser .add_argument ("--diff-baseline" , help = "Path to a baseline CSV file to compare against." )
443451 parser .add_argument ("--diff-threshold" , type = float , default = 100.0 , help = "Fail if Median time exceeds baseline Median by this many ms." )
444452 parser .add_argument ("--worker" , action = "store_true" , help = argparse .SUPPRESS )
453+ parser .add_argument ("--skip-line-count" , action = "store_true" , help = argparse .SUPPRESS )
445454
446455 args = parser .parse_args ()
447456
@@ -450,7 +459,7 @@ def find_module_from_package(pkg):
450459 target_module = find_module_from_package (args .package )
451460
452461 if args .worker :
453- run_worker (target_module )
462+ run_worker (target_module , skip_line_count = args . skip_line_count )
454463 elif args .trace :
455464 if not args .keep_pycache : clean_bytecode ()
456465 run_trace (target_module )
0 commit comments