FS.py (SCons-4.3.0) | : | FS.py (SCons-4.4.0) | ||
---|---|---|---|---|
skipping to change at line 84 | skipping to change at line 84 | |||
class FileBuildInfoFileToCsigMappingError(Exception): | class FileBuildInfoFileToCsigMappingError(Exception): | |||
pass | pass | |||
class EntryProxyAttributeError(AttributeError): | class EntryProxyAttributeError(AttributeError): | |||
""" | """ | |||
An AttributeError subclass for recording and displaying the name | An AttributeError subclass for recording and displaying the name | |||
of the underlying Entry involved in an AttributeError exception. | of the underlying Entry involved in an AttributeError exception. | |||
""" | """ | |||
def __init__(self, entry_proxy, attribute): | def __init__(self, entry_proxy, attribute): | |||
AttributeError.__init__(self) | super().__init__() | |||
self.entry_proxy = entry_proxy | self.entry_proxy = entry_proxy | |||
self.attribute = attribute | self.attribute = attribute | |||
def __str__(self): | def __str__(self): | |||
entry = self.entry_proxy.get() | entry = self.entry_proxy.get() | |||
fmt = "%s instance %s has no attribute %s" | fmt = "%s instance %s has no attribute %s" | |||
return fmt % (entry.__class__.__name__, | return fmt % (entry.__class__.__name__, | |||
repr(entry.name), | repr(entry.name), | |||
repr(self.attribute)) | repr(self.attribute)) | |||
# The max_drift value: by default, use a cached signature value for | # The max_drift value: by default, use a cached signature value for | |||
skipping to change at line 257 | skipping to change at line 257 | |||
if hasattr(os, 'symlink') and sys.platform != 'win32': | if hasattr(os, 'symlink') and sys.platform != 'win32': | |||
def _softlink_func(fs, src, dst): | def _softlink_func(fs, src, dst): | |||
fs.symlink(src, dst) | fs.symlink(src, dst) | |||
else: | else: | |||
_softlink_func = None | _softlink_func = None | |||
def _copy_func(fs, src, dest): | def _copy_func(fs, src, dest): | |||
shutil.copy2(src, dest) | shutil.copy2(src, dest) | |||
st = fs.stat(src) | st = fs.stat(src) | |||
fs.chmod(dest, stat.S_IMODE(st[stat.ST_MODE]) | stat.S_IWRITE) | fs.chmod(dest, stat.S_IMODE(st.st_mode) | stat.S_IWRITE) | |||
Valid_Duplicates = ['hard-soft-copy', 'soft-hard-copy', | Valid_Duplicates = ['hard-soft-copy', 'soft-hard-copy', | |||
'hard-copy', 'soft-copy', 'copy'] | 'hard-copy', 'soft-copy', 'copy'] | |||
Link_Funcs = [] # contains the callables of the specified duplication style | Link_Funcs = [] # contains the callables of the specified duplication style | |||
def set_duplicate(duplicate): | def set_duplicate(duplicate): | |||
# Fill in the Link_Funcs list according to the argument | # Fill in the Link_Funcs list according to the argument | |||
# (discarding those not available on the platform). | # (discarding those not available on the platform). | |||
skipping to change at line 573 | skipping to change at line 573 | |||
def __init__(self, name, directory, fs): | def __init__(self, name, directory, fs): | |||
"""Initialize a generic Node.FS.Base object. | """Initialize a generic Node.FS.Base object. | |||
Call the superclass initialization, take care of setting up | Call the superclass initialization, take care of setting up | |||
our relative and absolute paths, identify our parent | our relative and absolute paths, identify our parent | |||
directory, and indicate that this node should use | directory, and indicate that this node should use | |||
signatures.""" | signatures.""" | |||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Base' ) | if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Base' ) | |||
SCons.Node.Node.__init__(self) | super().__init__() | |||
# Filenames and paths are probably reused and are intern'ed to save some memory. | # Filenames and paths are probably reused and are intern'ed to save some memory. | |||
# Filename with extension as it was specified when the object was | # Filename with extension as it was specified when the object was | |||
# created; to obtain filesystem path, use Python str() function | # created; to obtain filesystem path, use Python str() function | |||
self.name = SCons.Util.silent_intern(name) | self.name = SCons.Util.silent_intern(name) | |||
self.fs = fs #: Reference to parent Node.FS object | self.fs = fs #: Reference to parent Node.FS object | |||
assert directory, "A directory must be provided" | assert directory, "A directory must be provided" | |||
self._abspath = None | self._abspath = None | |||
skipping to change at line 727 | skipping to change at line 727 | |||
self._memo['lstat'] = result | self._memo['lstat'] = result | |||
return result | return result | |||
def exists(self): | def exists(self): | |||
return SCons.Node._exists_map[self._func_exists](self) | return SCons.Node._exists_map[self._func_exists](self) | |||
def rexists(self): | def rexists(self): | |||
return SCons.Node._rexists_map[self._func_rexists](self) | return SCons.Node._rexists_map[self._func_rexists](self) | |||
def getmtime(self): | def getmtime(self): | |||
if self.islink(): | st = self.stat() | |||
st = self.lstat() | ||||
else: | ||||
st = self.stat() | ||||
if st: | if st: | |||
return st[stat.ST_MTIME] | return st[stat.ST_MTIME] | |||
else: | else: | |||
return None | return None | |||
def getsize(self): | def getsize(self): | |||
if self.islink(): | st = self.stat() | |||
st = self.lstat() | ||||
else: | ||||
st = self.stat() | ||||
if st: | if st: | |||
return st[stat.ST_SIZE] | return st.st_size | |||
else: | else: | |||
return None | return None | |||
def isdir(self): | def isdir(self): | |||
st = self.stat() | st = self.stat() | |||
return st is not None and stat.S_ISDIR(st[stat.ST_MODE]) | return st is not None and stat.S_ISDIR(st.st_mode) | |||
def isfile(self): | def isfile(self): | |||
st = self.stat() | st = self.stat() | |||
return st is not None and stat.S_ISREG(st[stat.ST_MODE]) | return st is not None and stat.S_ISREG(st.st_mode) | |||
if hasattr(os, 'symlink'): | if hasattr(os, 'symlink'): | |||
def islink(self): | def islink(self): | |||
st = self.lstat() | st = self.lstat() | |||
return st is not None and stat.S_ISLNK(st[stat.ST_MODE]) | return st is not None and stat.S_ISLNK(st.st_mode) | |||
else: | else: | |||
def islink(self): | def islink(self): | |||
return False # no symlinks | return False # no symlinks | |||
def is_under(self, dir): | def is_under(self, dir): | |||
if self is dir: | if self is dir: | |||
return 1 | return 1 | |||
else: | else: | |||
return self.dir.is_under(dir) | return self.dir.is_under(dir) | |||
skipping to change at line 976 | skipping to change at line 970 | |||
'searched', | 'searched', | |||
'_sconsign', | '_sconsign', | |||
'variant_dirs', | 'variant_dirs', | |||
'root', | 'root', | |||
'dirname', | 'dirname', | |||
'on_disk_entries', | 'on_disk_entries', | |||
'released_target_info', | 'released_target_info', | |||
'contentsig'] | 'contentsig'] | |||
def __init__(self, name, directory, fs): | def __init__(self, name, directory, fs): | |||
Base.__init__(self, name, directory, fs) | super().__init__(name, directory, fs) | |||
self._func_exists = 3 | self._func_exists = 3 | |||
self._func_get_contents = 1 | self._func_get_contents = 1 | |||
def diskcheck_match(self): | def diskcheck_match(self): | |||
pass | pass | |||
def disambiguate(self, must_exist=None): | def disambiguate(self, must_exist=None): | |||
""" | """ | |||
""" | """ | |||
if self.isfile(): | if self.isfile(): | |||
skipping to change at line 1565 | skipping to change at line 1559 | |||
'dirname', | 'dirname', | |||
'on_disk_entries', | 'on_disk_entries', | |||
'released_target_info', | 'released_target_info', | |||
'contentsig'] | 'contentsig'] | |||
NodeInfo = DirNodeInfo | NodeInfo = DirNodeInfo | |||
BuildInfo = DirBuildInfo | BuildInfo = DirBuildInfo | |||
def __init__(self, name, directory, fs): | def __init__(self, name, directory, fs): | |||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Dir') | if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Dir') | |||
Base.__init__(self, name, directory, fs) | super().__init__(name, directory, fs) | |||
self._morph() | self._morph() | |||
def _morph(self): | def _morph(self): | |||
"""Turn a file system Node (either a freshly initialized directory | """Turn a file system Node (either a freshly initialized directory | |||
object or a separate Entry object) into a proper directory object. | object or a separate Entry object) into a proper directory object. | |||
Set up this directory's entries and hook it into the file | Set up this directory's entries and hook it into the file | |||
system tree. Specify that directories (this Node) don't use | system tree. Specify that directories (this Node) don't use | |||
signatures for calculating whether they're current. | signatures for calculating whether they're current. | |||
""" | """ | |||
skipping to change at line 1930 | skipping to change at line 1924 | |||
"""Return the .sconsign file info for this directory. """ | """Return the .sconsign file info for this directory. """ | |||
return _sconsign_map[self._func_sconsign](self) | return _sconsign_map[self._func_sconsign](self) | |||
def srcnode(self): | def srcnode(self): | |||
"""Dir has a special need for srcnode()...if we | """Dir has a special need for srcnode()...if we | |||
have a srcdir attribute set, then that *is* our srcnode.""" | have a srcdir attribute set, then that *is* our srcnode.""" | |||
if self.srcdir: | if self.srcdir: | |||
return self.srcdir | return self.srcdir | |||
return Base.srcnode(self) | return Base.srcnode(self) | |||
def get_timestamp(self): | def get_timestamp(self) -> int: | |||
"""Return the latest timestamp from among our children""" | """Return the latest timestamp from among our children""" | |||
stamp = 0 | stamp = 0 | |||
for kid in self.children(): | for kid in self.children(): | |||
if kid.get_timestamp() > stamp: | if kid.get_timestamp() > stamp: | |||
stamp = kid.get_timestamp() | stamp = kid.get_timestamp() | |||
return stamp | return stamp | |||
def get_abspath(self): | def get_abspath(self) -> str: | |||
"""Get the absolute path of the file.""" | """Get the absolute path of the file.""" | |||
return self._abspath | return self._abspath | |||
def get_labspath(self): | def get_labspath(self) -> str: | |||
"""Get the absolute path of the file.""" | """Get the absolute path of the file.""" | |||
return self._labspath | return self._labspath | |||
def get_internal_path(self): | def get_internal_path(self): | |||
return self._path | return self._path | |||
def get_tpath(self): | def get_tpath(self): | |||
return self._tpath | return self._tpath | |||
def get_path_elements(self): | def get_path_elements(self): | |||
skipping to change at line 2551 | skipping to change at line 2545 | |||
def __setattr__(self, key, value): | def __setattr__(self, key, value): | |||
# If any attributes are changed in FileBuildInfo, we need to | # If any attributes are changed in FileBuildInfo, we need to | |||
# invalidate the cached map of file name to content signature | # invalidate the cached map of file name to content signature | |||
# heald in dependency_map. Currently only used with | # heald in dependency_map. Currently only used with | |||
# MD5-timestamp decider | # MD5-timestamp decider | |||
if key != 'dependency_map' and hasattr(self, 'dependency_map'): | if key != 'dependency_map' and hasattr(self, 'dependency_map'): | |||
del self.dependency_map | del self.dependency_map | |||
return super(FileBuildInfo, self).__setattr__(key, value) | return super().__setattr__(key, value) | |||
def convert_to_sconsign(self): | def convert_to_sconsign(self): | |||
""" | """ | |||
Converts this FileBuildInfo object for writing to a .sconsign file | Converts this FileBuildInfo object for writing to a .sconsign file | |||
This replaces each Node in our various dependency lists with its | This replaces each Node in our various dependency lists with its | |||
usual string representation: relative to the top-level SConstruct | usual string representation: relative to the top-level SConstruct | |||
directory, or an absolute path if it's outside. | directory, or an absolute path if it's outside. | |||
""" | """ | |||
if os_sep_is_slash: | if os_sep_is_slash: | |||
skipping to change at line 2661 | skipping to change at line 2655 | |||
# Although the command-line argument is in kilobytes, this is in bytes. | # Although the command-line argument is in kilobytes, this is in bytes. | |||
hash_chunksize = 65536 | hash_chunksize = 65536 | |||
def diskcheck_match(self): | def diskcheck_match(self): | |||
diskcheck_match(self, self.isdir, | diskcheck_match(self, self.isdir, | |||
"Directory %s found where file expected.") | "Directory %s found where file expected.") | |||
def __init__(self, name, directory, fs): | def __init__(self, name, directory, fs): | |||
if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.File' ) | if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.File' ) | |||
Base.__init__(self, name, directory, fs) | super().__init__(name, directory, fs) | |||
self._morph() | self._morph() | |||
def Entry(self, name): | def Entry(self, name): | |||
"""Create an entry node named 'name' relative to | """Create an entry node named 'name' relative to | |||
the directory of this file.""" | the directory of this file.""" | |||
return self.dir.Entry(name) | return self.dir.Entry(name) | |||
def Dir(self, name, create=True): | def Dir(self, name, create=True): | |||
"""Create a directory node named 'name' relative to | """Create a directory node named 'name' relative to | |||
the directory of this file.""" | the directory of this file.""" | |||
End of changes. 16 change blocks. | ||||
22 lines changed or deleted | 16 lines changed or added |