1818import keyword
1919import threading
2020from inspect import getcallargs
21- from functools import wraps
21+ from functools import wraps , lru_cache
2222
2323# Notes for v3
2424#
@@ -3255,6 +3255,18 @@ def _file_watcher_callback(name, info, event):
32553255
32563256_file_watcher = FileWatcher (_file_watcher_callback )
32573257
3258+ @lru_cache (None )
3259+ def _have_vcs (vcs ):
3260+ try :
3261+ subprocess .check_output ([vcs , '--version' ])
3262+ return True
3263+ except FileNotFoundError :
3264+ msg = f"""Warning: Cannot run { vcs } commands, { vcs } info for labscriptlib files
3265+ will not be saved. You can disable this warning by setting
3266+ [labscript]/save_{ vcs } _info = False in labconfig."""
3267+ sys .stderr .write (dedent (msg ) + '\n ' )
3268+ return False
3269+
32583270def _run_vcs_commands (path ):
32593271 """Run some VCS commands on a file and return their output.
32603272
@@ -3282,7 +3294,7 @@ def _run_vcs_commands(path):
32823294 # Gather together a list of commands to run.
32833295 module_directory , module_filename = os .path .split (path )
32843296 vcs_commands = []
3285- if compiler .save_hg_info :
3297+ if compiler .save_hg_info and _have_vcs ( 'hg' ) :
32863298 hg_commands = [
32873299 ['log' , '--limit' , '1' ],
32883300 ['status' ],
@@ -3291,7 +3303,7 @@ def _run_vcs_commands(path):
32913303 for command in hg_commands :
32923304 command = tuple (['hg' ] + command + [module_filename ])
32933305 vcs_commands .append ((command , module_directory ))
3294- if compiler .save_git_info :
3306+ if compiler .save_git_info and _have_vcs ( 'git' ) :
32953307 git_commands = [
32963308 ['branch' , '--show-current' ],
32973309 ['describe' , '--tags' , '--always' , 'HEAD' ],
@@ -3341,34 +3353,33 @@ def save_labscripts(hdf5_file):
33413353 script .attrs ['path' ] = os .path .dirname (compiler .labscript_file ).encode () if compiler .labscript_file is not None else sys .path [0 ]
33423354 try :
33433355 import labscriptlib
3344- prefix = os .path .dirname (labscriptlib .__file__ )
3345- for module in sys .modules .values ():
3346- if getattr (module , '__file__' , None ) is not None :
3347- path = os .path .abspath (module .__file__ )
3348- if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3349- path = path .replace ('.pyc' , '.py' )
3350- save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3351- if save_path in hdf5_file :
3352- # Don't try to save the same module script twice!
3353- # (seems to at least double count __init__.py when you import an entire module as in from labscriptlib.stages import * where stages is a folder with an __init__.py file.
3354- # Doesn't seem to want to double count files if you just import the contents of a file within a module
3355- continue
3356- hdf5_file .create_dataset (save_path , data = open (path ).read ())
3357- with _vcs_cache_rlock :
3358- already_cached = path in _vcs_cache
3359- if not already_cached :
3356+ except ImportError :
3357+ return
3358+ prefix = os .path .dirname (labscriptlib .__file__ )
3359+ for module in sys .modules .values ():
3360+ if getattr (module , '__file__' , None ) is not None :
3361+ path = os .path .abspath (module .__file__ )
3362+ if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3363+ path = path .replace ('.pyc' , '.py' )
3364+ save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3365+ if save_path in hdf5_file :
3366+ # Don't try to save the same module script twice! (seems to at least
3367+ # double count __init__.py when you import an entire module as in
3368+ # from labscriptlib.stages import * where stages is a folder with an
3369+ # __init__.py file. Doesn't seem to want to double count files if
3370+ # you just import the contents of a file within a module
3371+ continue
3372+ hdf5_file .create_dataset (save_path , data = open (path ).read ())
3373+ with _vcs_cache_rlock :
3374+ if not path in _vcs_cache :
33603375 # Add file to watch list and create its entry in the cache.
33613376 _file_watcher .add_file (path )
33623377 _file_watcher_callback (path , None , None )
3363- with _vcs_cache_rlock :
3364- # Save the cached vcs output to the file.
3365- for command , info , err in _vcs_cache [path ]:
3366- attribute_str = command [0 ] + ' ' + command [1 ]
3367- hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3368- except ImportError :
3369- pass
3370- except WindowsError if os .name == 'nt' else None :
3371- sys .stderr .write ('Warning: Cannot save version control data for imported scripts. Check that the hg and/or git command can be run from the command line.\n ' )
3378+ # Save the cached vcs output to the file.
3379+ for command , info , err in _vcs_cache [path ]:
3380+ attribute_str = command [0 ] + ' ' + command [1 ]
3381+ hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3382+
33723383
33733384
33743385def write_device_properties (hdf5_file ):
0 commit comments