@@ -301,10 +301,9 @@ def run_master(iterations, target_module, cpu=0, csv_path=None, clear_cache=True
301301
302302 if exit_code == 0 :
303303 print ("\n Session import_profiler was successful." )
304- sys .exit (0 )
305304 else :
306305 print ("\n Session import_profiler failed." )
307- sys . exit ( 1 )
306+ return exit_code
308307
309308
310309def run_trace (target_module ):
@@ -376,63 +375,64 @@ def run_mprofile(target_module):
376375 if p .exitcode != 0 :
377376 print (f"Error generating memory snapshot, process exited with code { p .exitcode } " , file = sys .stderr )
378377
379- if __name__ == "__main__" :
378+ def validate_module_name (module_name ):
379+ """Validates that the input is a structurally valid Python module identifier to prevent arbitrary code execution."""
380380 import argparse
381+ if not all (part .isidentifier () for part in module_name .split ('.' )):
382+ raise argparse .ArgumentTypeError (f"'{ module_name } ' is not a valid Python module identifier." )
383+ return module_name
381384
382- def validate_module_name (module_name ):
383- """Validates that the input is a structurally valid Python module identifier to prevent arbitrary code execution."""
384- if not all (part .isidentifier () for part in module_name .split ('.' )):
385- raise argparse .ArgumentTypeError (f"'{ module_name } ' is not a valid Python module identifier." )
386- return module_name
385+ def find_module_from_package (pkg ):
386+ import importlib .metadata
387+ import importlib .util
387388
388- def find_module_from_package (pkg ):
389- import importlib .metadata
390- import importlib .util
389+ # 1. Try to use importlib.metadata.files (works for standard installations from PyPI/wheels)
390+ try :
391+ files = importlib .metadata .files (pkg )
392+ if files :
393+ init_files = [str (f ) for f in files if str (f ).endswith ('__init__.py' ) and '__pycache__' not in str (f ) and not str (f ).startswith ('tests/' )]
394+ if init_files :
395+ from pathlib import Path
396+ shortest_init = min (init_files , key = lambda p : len (Path (p ).parts ))
397+ parts = Path (shortest_init ).parent .parts
398+ mod = '.' .join (parts )
399+ if importlib .util .find_spec (mod ):
400+ return mod
401+ except Exception :
402+ pass
391403
392- # 1. Try to use importlib.metadata.files (works for standard installations from PyPI/wheels)
393- try :
394- files = importlib .metadata .files (pkg )
395- if files :
396- init_files = [str (f ) for f in files if str (f ).endswith ('__init__.py' ) and '__pycache__' not in str (f ) and not str (f ).startswith ('tests/' )]
397- if init_files :
398- from pathlib import Path
399- shortest_init = min (init_files , key = lambda p : len (Path (p ).parts ))
400- parts = Path (shortest_init ).parent .parts
401- mod = '.' .join (parts )
402- if importlib .util .find_spec (mod ):
403- return mod
404- except Exception :
405- pass
404+ # 2. Try setuptools.find_namespace_packages() in current directory (works for editable installs in source trees)
405+ try :
406+ import setuptools
407+ import os
408+ if os .path .exists ('setup.py' ) or os .path .exists ('pyproject.toml' ):
409+ pkgs = setuptools .find_namespace_packages (where = '.' )
410+ for p in sorted (pkgs , key = len ):
411+ if p in ("google" , "google.cloud" ) or p .startswith ("tests" ):
412+ continue
413+ path = p .replace ('.' , os .sep )
414+ if os .path .isfile (os .path .join (path , '__init__.py' )):
415+ if importlib .util .find_spec (p ):
416+ return p
417+ except Exception :
418+ pass
406419
407- # 2. Try setuptools.find_namespace_packages() in current directory (works for editable installs in source trees)
420+ # 3. Fallback to basic string manipulation heuristics
421+ candidates = [
422+ pkg .replace ('-' , '.' ),
423+ '.' .join (pkg .split ('-' )[:- 1 ]) + '_' + pkg .split ('-' )[- 1 ] if '-' in pkg else pkg ,
424+ pkg .replace ('-' , '_' )
425+ ]
426+ for mod in candidates :
408427 try :
409- import setuptools
410- import os
411- if os .path .exists ('setup.py' ) or os .path .exists ('pyproject.toml' ):
412- pkgs = setuptools .find_namespace_packages (where = '.' )
413- for p in sorted (pkgs , key = len ):
414- if p in ("google" , "google.cloud" ) or p .startswith ("tests" ):
415- continue
416- path = p .replace ('.' , os .sep )
417- if os .path .isfile (os .path .join (path , '__init__.py' )):
418- if importlib .util .find_spec (p ):
419- return p
428+ if importlib .util .find_spec (mod ):
429+ return mod
420430 except Exception :
421431 pass
432+ return candidates [0 ]
422433
423- # 3. Fallback to basic string manipulation heuristics
424- candidates = [
425- pkg .replace ('-' , '.' ),
426- '.' .join (pkg .split ('-' )[:- 1 ]) + '_' + pkg .split ('-' )[- 1 ] if '-' in pkg else pkg ,
427- pkg .replace ('-' , '_' )
428- ]
429- for mod in candidates :
430- try :
431- if importlib .util .find_spec (mod ):
432- return mod
433- except Exception :
434- pass
435- return candidates [0 ]
434+ if __name__ == "__main__" :
435+ import argparse
436436
437437 parser = argparse .ArgumentParser (description = "Python SDK Import Profiler" )
438438 group = parser .add_mutually_exclusive_group (required = True )
@@ -470,4 +470,4 @@ def find_module_from_package(pkg):
470470 if not args .keep_pycache : clean_bytecode ()
471471 run_mprofile (target_module )
472472 else :
473- run_master (args .iterations , target_module , args .cpu , args .csv , not args .keep_pycache , args .fail_threshold , args .diff_baseline , args .diff_threshold )
473+ sys . exit ( run_master (args .iterations , target_module , args .cpu , args .csv , not args .keep_pycache , args .fail_threshold , args .diff_baseline , args .diff_threshold ) )
0 commit comments