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#
@@ -3194,6 +3194,18 @@ def _file_watcher_callback(name, info, event):
31943194
31953195_file_watcher = FileWatcher (_file_watcher_callback )
31963196
3197+ @lru_cache (None )
3198+ def _have_vcs (vcs ):
3199+ try :
3200+ subprocess .check_output ([vcs , '--version' ])
3201+ return True
3202+ except FileNotFoundError :
3203+ msg = f"""Warning: Cannot run { vcs } commands, { vcs } info for labscriptlib files
3204+ will not be saved. You can disable this warning by setting
3205+ [labscript]/save_{ vcs } _info = False in labconfig."""
3206+ sys .stderr .write (dedent (msg ) + '\n ' )
3207+ return False
3208+
31973209def _run_vcs_commands (path ):
31983210 """Run some VCS commands on a file and return their output.
31993211
@@ -3221,7 +3233,7 @@ def _run_vcs_commands(path):
32213233 # Gather together a list of commands to run.
32223234 module_directory , module_filename = os .path .split (path )
32233235 vcs_commands = []
3224- if compiler .save_hg_info :
3236+ if compiler .save_hg_info and _have_vcs ( 'hg' ) :
32253237 hg_commands = [
32263238 ['log' , '--limit' , '1' ],
32273239 ['status' ],
@@ -3230,7 +3242,7 @@ def _run_vcs_commands(path):
32303242 for command in hg_commands :
32313243 command = tuple (['hg' ] + command + [module_filename ])
32323244 vcs_commands .append ((command , module_directory ))
3233- if compiler .save_git_info :
3245+ if compiler .save_git_info and _have_vcs ( 'git' ) :
32343246 git_commands = [
32353247 ['branch' , '--show-current' ],
32363248 ['describe' , '--tags' , '--always' , 'HEAD' ],
@@ -3280,34 +3292,33 @@ def save_labscripts(hdf5_file):
32803292 script .attrs ['path' ] = os .path .dirname (compiler .labscript_file ).encode () if compiler .labscript_file is not None else sys .path [0 ]
32813293 try :
32823294 import labscriptlib
3283- prefix = os .path .dirname (labscriptlib .__file__ )
3284- for module in sys .modules .values ():
3285- if getattr (module , '__file__' , None ) is not None :
3286- path = os .path .abspath (module .__file__ )
3287- if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3288- path = path .replace ('.pyc' , '.py' )
3289- save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3290- if save_path in hdf5_file :
3291- # Don't try to save the same module script twice!
3292- # (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.
3293- # Doesn't seem to want to double count files if you just import the contents of a file within a module
3294- continue
3295- hdf5_file .create_dataset (save_path , data = open (path ).read ())
3296- with _vcs_cache_rlock :
3297- already_cached = path in _vcs_cache
3298- if not already_cached :
3295+ except ImportError :
3296+ return
3297+ prefix = os .path .dirname (labscriptlib .__file__ )
3298+ for module in sys .modules .values ():
3299+ if getattr (module , '__file__' , None ) is not None :
3300+ path = os .path .abspath (module .__file__ )
3301+ if path .startswith (prefix ) and (path .endswith ('.pyc' ) or path .endswith ('.py' )):
3302+ path = path .replace ('.pyc' , '.py' )
3303+ save_path = 'labscriptlib/' + path .replace (prefix , '' ).replace ('\\ ' , '/' ).replace ('//' , '/' )
3304+ if save_path in hdf5_file :
3305+ # Don't try to save the same module script twice! (seems to at least
3306+ # double count __init__.py when you import an entire module as in
3307+ # from labscriptlib.stages import * where stages is a folder with an
3308+ # __init__.py file. Doesn't seem to want to double count files if
3309+ # you just import the contents of a file within a module
3310+ continue
3311+ hdf5_file .create_dataset (save_path , data = open (path ).read ())
3312+ with _vcs_cache_rlock :
3313+ if not path in _vcs_cache :
32993314 # Add file to watch list and create its entry in the cache.
33003315 _file_watcher .add_file (path )
33013316 _file_watcher_callback (path , None , None )
3302- with _vcs_cache_rlock :
3303- # Save the cached vcs output to the file.
3304- for command , info , err in _vcs_cache [path ]:
3305- attribute_str = command [0 ] + ' ' + command [1 ]
3306- hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3307- except ImportError :
3308- pass
3309- except WindowsError if os .name == 'nt' else None :
3310- 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 ' )
3317+ # Save the cached vcs output to the file.
3318+ for command , info , err in _vcs_cache [path ]:
3319+ attribute_str = command [0 ] + ' ' + command [1 ]
3320+ hdf5_file [save_path ].attrs [attribute_str ] = (info + '\n ' + err )
3321+
33113322
33123323
33133324def write_device_properties (hdf5_file ):
0 commit comments