diff options
Diffstat (limited to 'SCons/Environment.py')
-rw-r--r-- | SCons/Environment.py | 488 |
1 files changed, 305 insertions, 183 deletions
diff --git a/SCons/Environment.py b/SCons/Environment.py index 7212c89ea..b074af77d 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -35,7 +35,7 @@ import os import sys import re import shlex -from collections import UserDict +from collections import UserDict, deque import SCons.Action import SCons.Builder @@ -65,6 +65,7 @@ from SCons.Util import ( flatten, is_Dict, is_List, + is_Scalar, is_Sequence, is_String, is_Tuple, @@ -86,7 +87,7 @@ _warn_target_signatures_deprecated = True CleanTargets = {} CalculatorArgs = {} -def alias_builder(env, target, source): +def alias_builder(env, target, source) -> None: pass AliasBuilder = SCons.Builder.Builder( @@ -98,7 +99,7 @@ AliasBuilder = SCons.Builder.Builder( name='AliasBuilder', ) -def apply_tools(env, tools, toolpath): +def apply_tools(env, tools, toolpath) -> None: # Store the toolpath in the Environment. # This is expected to work even if no tools are given, so do this first. if toolpath is not None: @@ -144,11 +145,11 @@ def copy_non_reserved_keywords(dict): del result[k] return result -def _set_reserved(env, key, value): +def _set_reserved(env, key, value) -> None: msg = "Ignoring attempt to set reserved variable `$%s'" SCons.Warnings.warn(SCons.Warnings.ReservedVariableWarning, msg % key) -def _set_future_reserved(env, key, value): +def _set_future_reserved(env, key, value) -> None: env._dict[key] = value msg = "`$%s' will be reserved in a future release and setting it will become ignored" SCons.Warnings.warn(SCons.Warnings.FutureReservedVariableWarning, msg % key) @@ -166,11 +167,11 @@ def _set_BUILDERS(env, key, value): raise UserError('%s is not a Builder.' % repr(v)) bd.update(value) -def _del_SCANNERS(env, key): +def _del_SCANNERS(env, key) -> None: del env._dict[key] env.scanner_map_delete() -def _set_SCANNERS(env, key, value): +def _set_SCANNERS(env, key, value) -> None: env._dict[key] = value env.scanner_map_delete() @@ -193,6 +194,206 @@ def _delete_duplicates(l, keep_last): return result +def _add_cppdefines( + env_dict: dict, + val, # add annotation? + prepend: bool = False, + unique: bool = False, + delete_existing: bool = False, +) -> None: + """Adds to ``CPPDEFINES``, using the rules for C preprocessor macros. + + This is split out from regular construction variable addition because + these entries can express either a macro with a replacement value or + one without. A macro with replacement value can be supplied as *val* + in three ways: as a combined string ``"name=value"``; as a tuple + ``(name, value)``, or as an entry in a dictionary ``{"name": value}``. + A list argument with multiple macros can also be given. + + Additions can be unconditional (duplicates allowed) or uniquing (no dupes). + + Note if a replacement value is supplied, *unique* requires a full + match to decide uniqueness - both the macro name and the replacement. + The inner :func:`_is_in` is used to figure that out. + + Args: + env_dict: the dictionary containing the ``CPPDEFINES`` to be modified. + val: the value to add, can be string, sequence or dict + prepend: whether to put *val* in front or back. + unique: whether to add *val* if it already exists. + delete_existing: if *unique* is true, add *val* after removing previous. + + .. versionadded:: 4.5.0 + """ + + def _add_define(item, defines: deque, prepend: bool = False) -> None: + """Convenience function to prepend/append a single value. + + Sole purpose is to shorten code in the outer function. + """ + if prepend: + defines.appendleft(item) + else: + defines.append(item) + + + def _is_in(item, defines: deque): + """Returns match for *item* if found in *defines*. + + Accounts for type differences: tuple ("FOO", "BAR"), list + ["FOO", "BAR"], string "FOO=BAR" and dict {"FOO": "BAR"} all + differ as far as Python equality comparison is concerned, but + are the same for purposes of creating the preprocessor macro. + Also an unvalued string should match something like ``("FOO", None)``. + Since the caller may wish to remove a matched entry, we need to + return it - cannot remove *item* itself unless it happened to + be an exact (type) match. + + Called from a place we know *defines* is always a deque, and + *item* will not be a dict, so don't need to do much type checking. + If this ends up used more generally, would need to adjust that. + + Note implied assumption that members of a list-valued define + will not be dicts - we cannot actually guarantee this, since + if the initial add is a list its contents are not converted. + """ + def _macro_conv(v) -> list: + """Normalizes a macro to a list for comparisons.""" + if is_Tuple(v): + return list(v) + elif is_String(v): + rv = v.split("=") + if len(rv) == 1: + return [v, None] + return rv + return v + + if item in defines: # cheap check first + return item + + item = _macro_conv(item) + for define in defines: + if item == _macro_conv(define): + return define + + return False + + key = 'CPPDEFINES' + try: + defines = env_dict[key] + except KeyError: + # This is a new entry, just save it as is. Defer conversion to + # preferred type until someone tries to amend the value. + # processDefines has no problem with unconverted values if it + # gets called without any later additions. + if is_String(val): + env_dict[key] = val.split() + else: + env_dict[key] = val + return + + # Convert type of existing to deque (if necessary) to simplify processing + # of additions - inserting at either end is cheap. Deferred conversion + # is also useful in case CPPDEFINES was set initially without calling + # through here (e.g. Environment kwarg, or direct assignment). + if isinstance(defines, deque): + # Already a deque? do nothing. Explicit check is so we don't get + # picked up by the is_list case below. + pass + elif is_String(defines): + env_dict[key] = deque(defines.split()) + elif is_Tuple(defines): + if len(defines) > 2: + raise SCons.Errors.UserError( + f"Invalid tuple in CPPDEFINES: {defines!r}, must be a two-tuple" + ) + env_dict[key] = deque([defines]) + elif is_List(defines): + # a little extra work in case the initial container has dict + # item(s) inside it, so those can be matched by _is_in(). + result = deque() + for define in defines: + if is_Dict(define): + result.extend(define.items()) + else: + result.append(define) + env_dict[key] = result + elif is_Dict(defines): + env_dict[key] = deque(defines.items()) + else: + env_dict[key] = deque(defines) + defines = env_dict[key] # in case we reassigned due to conversion + + # now actually do the addition. + if is_Dict(val): + # Unpack the dict while applying to existing + for item in val.items(): + if unique: + match = _is_in(item, defines) + if match and delete_existing: + defines.remove(match) + _add_define(item, defines, prepend) + elif not match: + _add_define(item, defines, prepend) + else: + _add_define(item, defines, prepend) + + elif is_String(val): + for v in val.split(): + if unique: + match = _is_in(v, defines) + if match and delete_existing: + defines.remove(match) + _add_define(v, defines, prepend) + elif not match: + _add_define(v, defines, prepend) + else: + _add_define(v, defines, prepend) + + # A tuple appended to anything should yield -Dkey=value + elif is_Tuple(val): + if len(val) > 2: + raise SCons.Errors.UserError( + f"Invalid tuple added to CPPDEFINES: {val!r}, " + "must be a two-tuple" + ) + if len(val) == 1: + val = (val[0], None) # normalize + if not is_Scalar(val[0]) or not is_Scalar(val[1]): + raise SCons.Errors.UserError( + f"Invalid tuple added to CPPDEFINES: {val!r}, " + "values must be scalar" + ) + if unique: + match = _is_in(val, defines) + if match and delete_existing: + defines.remove(match) + _add_define(val, defines, prepend) + elif not match: + _add_define(val, defines, prepend) + else: + _add_define(val, defines, prepend) + + elif is_List(val): + tmp = [] + for item in val: + if unique: + match = _is_in(item, defines) + if match and delete_existing: + defines.remove(match) + tmp.append(item) + elif not match: + tmp.append(item) + else: + tmp.append(item) + + if prepend: + defines.extendleft(tmp) + else: + defines.extend(tmp) + + # else: # are there any other cases? processDefines doesn't think so. + # The following is partly based on code in a comment added by Peter # Shannon at the following page (there called the "transplant" class): @@ -237,10 +438,10 @@ class BuilderWrapper(MethodWrapper): source = [source] return super().__call__(target, source, *args, **kw) - def __repr__(self): + def __repr__(self) -> str: return '<BuilderWrapper %s>' % repr(self.name) - def __str__(self): + def __str__(self) -> str: return self.__repr__() def __getattr__(self, name): @@ -251,7 +452,7 @@ class BuilderWrapper(MethodWrapper): else: raise AttributeError(name) - def __setattr__(self, name, value): + def __setattr__(self, name, value) -> None: if name == 'env': self.object = value elif name == 'builder': @@ -275,7 +476,7 @@ class BuilderDict(UserDict): the Builders. We need to do this because every time someone changes the Builders in the Environment's BUILDERS dictionary, we must update the Environment's attributes.""" - def __init__(self, mapping, env): + def __init__(self, mapping, env) -> None: # Set self.env before calling the superclass initialization, # because it will end up calling our other methods, which will # need to point the values in this dictionary to self.env. @@ -287,7 +488,7 @@ class BuilderDict(UserDict): # just copying would modify the original builder raise TypeError( 'cannot semi_deepcopy a BuilderDict' ) - def __setitem__(self, item, val): + def __setitem__(self, item, val) -> None: try: method = getattr(self.env, item).method except AttributeError: @@ -297,11 +498,11 @@ class BuilderDict(UserDict): super().__setitem__(item, val) BuilderWrapper(self.env, val, item) - def __delitem__(self, item): + def __delitem__(self, item) -> None: super().__delitem__(item) delattr(self.env, item) - def update(self, mapping): + def update(self, mapping) -> None: for i, v in mapping.items(): self.__setitem__(i, v) @@ -343,7 +544,7 @@ class SubstitutionEnvironment: class actually becomes useful.) """ - def __init__(self, **kw): + def __init__(self, **kw) -> None: """Initialization of an underlying SubstitutionEnvironment class. """ if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.SubstitutionEnvironment') @@ -355,7 +556,7 @@ class SubstitutionEnvironment: self.added_methods = [] #self._memo = {} - def _init_special(self): + def _init_special(self) -> None: """Initial the dispatch tables for special handling of special construction variables.""" self._special_del = {} @@ -376,7 +577,7 @@ class SubstitutionEnvironment: def __eq__(self, other): return self._dict == other._dict - def __delitem__(self, key): + def __delitem__(self, key) -> None: special = self._special_del.get(key) if special: special(self, key) @@ -413,7 +614,7 @@ class SubstitutionEnvironment: """Emulates the get() method of dictionaries.""" return self._dict.get(key, default) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self._dict def keys(self): @@ -481,7 +682,7 @@ class SubstitutionEnvironment: def lvars(self): return {} - def subst(self, string, raw=0, target=None, source=None, conv=None, executor=None, overrides=False): + def subst(self, string, raw: int=0, target=None, source=None, conv=None, executor=None, overrides: bool=False): """Recursively interpolates construction variables from the Environment into the specified string, returning the expanded result. Construction variables are specified by a $ prefix @@ -498,7 +699,7 @@ class SubstitutionEnvironment: lvars.update(executor.get_lvars()) return SCons.Subst.scons_subst(string, self, raw, target, source, gvars, lvars, conv, overrides=overrides) - def subst_kw(self, kw, raw=0, target=None, source=None): + def subst_kw(self, kw, raw: int=0, target=None, source=None): nkw = {} for k, v in kw.items(): k = self.subst(k, raw, target, source) @@ -507,7 +708,7 @@ class SubstitutionEnvironment: nkw[k] = v return nkw - def subst_list(self, string, raw=0, target=None, source=None, conv=None, executor=None, overrides=False): + def subst_list(self, string, raw: int=0, target=None, source=None, conv=None, executor=None, overrides: bool=False): """Calls through to SCons.Subst.scons_subst_list(). See the documentation for that function.""" gvars = self.gvars() @@ -598,7 +799,7 @@ class SubstitutionEnvironment: return out - def AddMethod(self, function, name=None): + def AddMethod(self, function, name=None) -> None: """ Adds the specified function as a method of this construction environment with the specified name. If the name is omitted, @@ -607,7 +808,7 @@ class SubstitutionEnvironment: method = MethodWrapper(self, function, name) self.added_methods.append(method) - def RemoveMethod(self, function): + def RemoveMethod(self, function) -> None: """ Removes the specified function's MethodWrapper from the added_methods list, so we don't re-bind it when making a clone. @@ -672,7 +873,7 @@ class SubstitutionEnvironment: 'RPATH' : [], } - def do_parse(arg): + def do_parse(arg) -> None: # if arg is a sequence, recurse with each element if not arg: return @@ -686,7 +887,7 @@ class SubstitutionEnvironment: arg = self.backtick(arg[1:]) # utility function to deal with -D option - def append_define(name, mapping=mapping): + def append_define(name, mapping=mapping) -> None: t = name.split('=') if len(t) == 1: mapping['CPPDEFINES'].append(name) @@ -834,14 +1035,20 @@ class SubstitutionEnvironment: do_parse(arg) return mapping - def MergeFlags(self, args, unique=True) -> None: + def MergeFlags(self, args, unique: bool=True) -> None: """Merge flags into construction variables. - Merges the flags from ``args`` into this construction environent. - If ``args`` is not a dict, it is first converted to one with + Merges the flags from *args* into this construction environent. + If *args* is not a dict, it is first converted to one with flags distributed into appropriate construction variables. See :meth:`ParseFlags`. + As a side effect, if *unique* is true, a new object is created + for each modified construction variable by the loop at the end. + This is silently expected by the :meth:`Override` *parse_flags* + functionality, which does not want to share the list (or whatever) + with the environment being overridden. + Args: args: flags to merge unique: merge flags rather than appending (default: True). @@ -876,6 +1083,16 @@ class SubstitutionEnvironment: try: orig = orig + value except (KeyError, TypeError): + # If CPPDEFINES is a deque, adding value (a list) + # results in TypeError, so we handle that case here. + # Just in case we got called from Override, make + # sure we make a copy, because we don't go through + # the cleanup loops at the end of the outer for loop, + # which implicitly gives us a new object. + if isinstance(orig, deque): + self[key] = self[key].copy() + self.AppendUnique(CPPDEFINES=value, delete_existing=True) + continue try: add_to_orig = orig.append except AttributeError: @@ -894,6 +1111,7 @@ class SubstitutionEnvironment: for v in orig[::-1]: if v not in t: t.insert(0, v) + self[key] = t @@ -948,7 +1166,7 @@ class Base(SubstitutionEnvironment): variables=None, parse_flags=None, **kw - ): + ) -> None: """Initialization of a basic SCons construction environment. Sets up special construction variables like BUILDER, @@ -1086,7 +1304,7 @@ class Base(SubstitutionEnvironment): self._last_CacheDir = cd return cd - def get_factory(self, factory, default='File'): + def get_factory(self, factory, default: str='File'): """Return a factory function for creating Nodes for this construction environment. """ @@ -1155,7 +1373,7 @@ class Base(SubstitutionEnvironment): skey = skey.lower() return self._gsm().get(skey) - def scanner_map_delete(self, kw=None): + def scanner_map_delete(self, kw=None) -> None: """Delete the cached scanner map (if we need to). """ try: @@ -1163,14 +1381,14 @@ class Base(SubstitutionEnvironment): except KeyError: pass - def _update(self, other): + def _update(self, other) -> None: """Private method to update an environment's consvar dict directly. Bypasses the normal checks that occur when users try to set items. """ self._dict.update(other) - def _update_onlynew(self, other): + def _update_onlynew(self, other) -> None: """Private method to add new items to an environment's consvar dict. Only adds items from `other` whose keys do not already appear in @@ -1207,7 +1425,7 @@ class Base(SubstitutionEnvironment): # an Environment's construction variables. ####################################################################### - def Append(self, **kw): + def Append(self, **kw) -> None: """Append values to construction variables in an Environment. The variable is created if it is not already present. @@ -1215,16 +1433,15 @@ class Base(SubstitutionEnvironment): kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): + if key == 'CPPDEFINES': + _add_cppdefines(self._dict, val) + continue + try: - if key == 'CPPDEFINES' and is_String(self._dict[key]): - self._dict[key] = [self._dict[key]] orig = self._dict[key] except KeyError: # No existing var in the environment, so set to the new value. - if key == 'CPPDEFINES' and is_String(val): - self._dict[key] = [val] - else: - self._dict[key] = val + self._dict[key] = val continue try: @@ -1263,19 +1480,8 @@ class Base(SubstitutionEnvironment): # things like UserList will incorrectly coerce the # original dict to a list (which we don't want). if is_List(val): - if key == 'CPPDEFINES': - tmp = [] - for (k, v) in orig.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - orig = tmp - orig += val - self._dict[key] = orig - else: - for v in val: - orig[v] = None + for v in val: + orig[v] = None else: try: update_dict(val) @@ -1299,8 +1505,8 @@ class Base(SubstitutionEnvironment): path = str(self.fs.Dir(path)) return path - def AppendENVPath(self, name, newpath, envname='ENV', - sep=os.pathsep, delete_existing=False): + def AppendENVPath(self, name, newpath, envname: str='ENV', + sep=os.pathsep, delete_existing: bool=False) -> None: """Append path elements to the path *name* in the *envname* dictionary for this environment. Will only add any particular path once, and will normpath and normcase all paths to help @@ -1322,7 +1528,7 @@ class Base(SubstitutionEnvironment): self._dict[envname][name] = nv - def AppendUnique(self, delete_existing=False, **kw): + def AppendUnique(self, delete_existing: bool=False, **kw) -> None: """Append values to existing construction variables in an Environment, if they're not already there. If delete_existing is True, removes existing values first, so @@ -1330,6 +1536,9 @@ class Base(SubstitutionEnvironment): """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): + if key == 'CPPDEFINES': + _add_cppdefines(self._dict, val, unique=True, delete_existing=delete_existing) + continue if is_List(val): val = _delete_duplicates(val, delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1338,46 +1547,8 @@ class Base(SubstitutionEnvironment): self._dict[key].update(val) elif is_List(val): dk = self._dict[key] - if key == 'CPPDEFINES': - tmp = [] - for i in val: - if is_List(i): - if len(i) >= 2: - tmp.append((i[0], i[1])) - else: - tmp.append((i[0],)) - elif is_Tuple(i): - tmp.append(i) - else: - tmp.append((i,)) - val = tmp - # Construct a list of (key, value) tuples. - if is_Dict(dk): - tmp = [] - for (k, v) in dk.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - dk = tmp - elif is_String(dk): - dk = [(dk,)] - else: - tmp = [] - for i in dk: - if is_List(i): - if len(i) >= 2: - tmp.append((i[0], i[1])) - else: - tmp.append((i[0],)) - elif is_Tuple(i): - tmp.append(i) - else: - tmp.append((i,)) - dk = tmp - else: - if not is_List(dk): - dk = [dk] + if not is_List(dk): + dk = [dk] if delete_existing: dk = [x for x in dk if x not in val] else: @@ -1386,70 +1557,15 @@ class Base(SubstitutionEnvironment): else: dk = self._dict[key] if is_List(dk): - if key == 'CPPDEFINES': - tmp = [] - for i in dk: - if is_List(i): - if len(i) >= 2: - tmp.append((i[0], i[1])) - else: - tmp.append((i[0],)) - elif is_Tuple(i): - tmp.append(i) - else: - tmp.append((i,)) - dk = tmp - # Construct a list of (key, value) tuples. - if is_Dict(val): - tmp = [] - for (k, v) in val.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - val = tmp - elif is_String(val): - val = [(val,)] - if delete_existing: - dk = list(filter(lambda x, val=val: x not in val, dk)) - self._dict[key] = dk + val - else: - dk = [x for x in dk if x not in val] - self._dict[key] = dk + val + # By elimination, val is not a list. Since dk is a + # list, wrap val in a list first. + if delete_existing: + dk = list(filter(lambda x, val=val: x not in val, dk)) + self._dict[key] = dk + [val] else: - # By elimination, val is not a list. Since dk is a - # list, wrap val in a list first. - if delete_existing: - dk = list(filter(lambda x, val=val: x not in val, dk)) + if val not in dk: self._dict[key] = dk + [val] - else: - if val not in dk: - self._dict[key] = dk + [val] else: - if key == 'CPPDEFINES': - if is_String(dk): - dk = [dk] - elif is_Dict(dk): - tmp = [] - for (k, v) in dk.items(): - if v is not None: - tmp.append((k, v)) - else: - tmp.append((k,)) - dk = tmp - if is_String(val): - if val in dk: - val = [] - else: - val = [val] - elif is_Dict(val): - tmp = [] - for i,j in val.items(): - if j is not None: - tmp.append((i,j)) - else: - tmp.append(i) - val = tmp if delete_existing: dk = [x for x in dk if x not in val] self._dict[key] = dk + val @@ -1588,7 +1704,7 @@ class Base(SubstitutionEnvironment): return dlist - def Dump(self, key=None, format='pretty'): + def Dump(self, key=None, format: str='pretty'): """ Return construction variables serialized to a string. Args: @@ -1648,7 +1764,7 @@ class Base(SubstitutionEnvironment): return path - def ParseConfig(self, command, function=None, unique=True): + def ParseConfig(self, command, function=None, unique: bool=True): """Parse the result of running a command to update construction vars. Use ``function`` to parse the output of running ``command`` @@ -1674,7 +1790,7 @@ class Base(SubstitutionEnvironment): return function(self, self.backtick(command), unique) - def ParseDepends(self, filename, must_exist=None, only_one=False): + def ParseDepends(self, filename, must_exist=None, only_one: bool=False): """ Parse a mkdep-style file for explicit dependencies. This is completely abusable, and should be unnecessary in the "normal" @@ -1718,7 +1834,7 @@ class Base(SubstitutionEnvironment): platform = self.subst(platform) return SCons.Platform.Platform(platform)(self) - def Prepend(self, **kw): + def Prepend(self, **kw) -> None: """Prepend values to construction variables in an Environment. The variable is created if it is not already present. @@ -1726,6 +1842,9 @@ class Base(SubstitutionEnvironment): kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): + if key == 'CPPDEFINES': + _add_cppdefines(self._dict, val, prepend=True) + continue try: orig = self._dict[key] except KeyError: @@ -1783,8 +1902,8 @@ class Base(SubstitutionEnvironment): self.scanner_map_delete(kw) - def PrependENVPath(self, name, newpath, envname='ENV', - sep=os.pathsep, delete_existing=True): + def PrependENVPath(self, name, newpath, envname: str='ENV', + sep=os.pathsep, delete_existing: bool=True) -> None: """Prepend path elements to the path *name* in the *envname* dictionary for this environment. Will only add any particular path once, and will normpath and normcase all paths to help @@ -1807,7 +1926,7 @@ class Base(SubstitutionEnvironment): self._dict[envname][name] = nv - def PrependUnique(self, delete_existing=False, **kw): + def PrependUnique(self, delete_existing: bool=False, **kw) -> None: """Prepend values to existing construction variables in an Environment, if they're not already there. If delete_existing is True, removes existing values first, so @@ -1815,6 +1934,9 @@ class Base(SubstitutionEnvironment): """ kw = copy_non_reserved_keywords(kw) for key, val in kw.items(): + if key == 'CPPDEFINES': + _add_cppdefines(self._dict, val, unique=True, prepend=True, delete_existing=delete_existing) + continue if is_List(val): val = _delete_duplicates(val, not delete_existing) if key not in self._dict or self._dict[key] in ('', None): @@ -1847,7 +1969,7 @@ class Base(SubstitutionEnvironment): self._dict[key] = val + dk self.scanner_map_delete(kw) - def Replace(self, **kw): + def Replace(self, **kw) -> None: """Replace existing construction variables in an Environment with new construction variables and/or values. """ @@ -1887,7 +2009,7 @@ class Base(SubstitutionEnvironment): name = name[:-len(old_suffix)] return os.path.join(dir, new_prefix+name+new_suffix) - def SetDefault(self, **kw): + def SetDefault(self, **kw) -> None: for k in list(kw.keys()): if k in self._dict: del kw[k] @@ -2037,7 +2159,7 @@ class Base(SubstitutionEnvironment): nkw = self.subst_kw(kw) return SCons.Builder.Builder(**nkw) - def CacheDir(self, path, custom_class=None): + def CacheDir(self, path, custom_class=None) -> None: if path is not None: path = self.subst(path) self._CacheDir_path = path @@ -2052,7 +2174,7 @@ class Base(SubstitutionEnvironment): # multiple threads, but initializing it before the task walk starts self.get_CacheDir() - def Clean(self, targets, files): + def Clean(self, targets, files) -> None: global CleanTargets tlist = self.arg2nodes(targets, self.fs.Entry) flist = self.arg2nodes(files, self.fs.Entry) @@ -2219,7 +2341,7 @@ class Base(SubstitutionEnvironment): else: return result[0] - def Glob(self, pattern, ondisk=True, source=False, strings=False, exclude=None): + def Glob(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False, exclude=None): return self.fs.Glob(self.subst(pattern), ondisk, source, strings, exclude) def Ignore(self, target, dependency): @@ -2261,7 +2383,7 @@ class Base(SubstitutionEnvironment): t.set_pseudo() return tlist - def Repository(self, *dirs, **kw): + def Repository(self, *dirs, **kw) -> None: dirs = self.arg2nodes(list(dirs), self.fs.Dir) self.fs.Repository(*dirs, **kw) @@ -2284,7 +2406,7 @@ class Base(SubstitutionEnvironment): nkw = self.subst_kw(kw) return SCons.Scanner.ScannerBase(*nargs, **nkw) - def SConsignFile(self, name=SCons.SConsign.current_sconsign_filename(), dbm_module=None): + def SConsignFile(self, name=SCons.SConsign.current_sconsign_filename(), dbm_module=None) -> None: if name is not None: name = self.subst(name) if not os.path.isabs(name): @@ -2347,17 +2469,17 @@ class Base(SubstitutionEnvironment): """ return SCons.Node.Python.ValueWithMemo(value, built_value, name) - def VariantDir(self, variant_dir, src_dir, duplicate=1): + def VariantDir(self, variant_dir, src_dir, duplicate: int=1) -> None: variant_dir = self.arg2nodes(variant_dir, self.fs.Dir)[0] src_dir = self.arg2nodes(src_dir, self.fs.Dir)[0] self.fs.VariantDir(variant_dir, src_dir, duplicate) - def FindSourceFiles(self, node='.') -> list: + def FindSourceFiles(self, node: str='.') -> list: """Return a list of all source files.""" node = self.arg2nodes(node, self.fs.Entry)[0] sources = [] - def build_source(ss): + def build_source(ss) -> None: for s in ss: if isinstance(s, SCons.Node.FS.Dir): build_source(s.all_children()) @@ -2405,7 +2527,7 @@ class OverrideEnvironment(Base): values from the overrides dictionary. """ - def __init__(self, subject, overrides=None): + def __init__(self, subject, overrides=None) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Environment.OverrideEnvironment') self.__dict__['__subject'] = subject if overrides is None: @@ -2429,7 +2551,7 @@ class OverrideEnvironment(Base): else: return attr - def __setattr__(self, name, value): + def __setattr__(self, name, value) -> None: setattr(self.__dict__['__subject'], name, value) # Methods that make this class act like a dictionary. @@ -2466,7 +2588,7 @@ class OverrideEnvironment(Base): except KeyError: return self.__dict__['__subject'].get(key, default) - def __contains__(self, key): + def __contains__(self, key) -> bool: if key in self.__dict__['overrides']: return True return key in self.__dict__['__subject'] @@ -2502,10 +2624,10 @@ class OverrideEnvironment(Base): return default # Overridden private construction environment methods. - def _update(self, other): + def _update(self, other) -> None: self.__dict__['overrides'].update(other) - def _update_onlynew(self, other): + def _update_onlynew(self, other) -> None: """Update a dict with new keys. Unlike the .update method, if the key is already present, @@ -2524,7 +2646,7 @@ class OverrideEnvironment(Base): return lvars # Overridden public construction environment methods. - def Replace(self, **kw): + def Replace(self, **kw) -> None: kw = copy_non_reserved_keywords(kw) self.__dict__['overrides'].update(semi_deepcopy(kw)) @@ -2553,7 +2675,7 @@ def NoSubstitutionProxy(subject): might have assigned to SCons.Environment.Environment. """ class _NoSubstitutionProxy(Environment): - def __init__(self, subject): + def __init__(self, subject) -> None: self.__dict__['__subject'] = subject def __getattr__(self, name): @@ -2562,14 +2684,14 @@ def NoSubstitutionProxy(subject): def __setattr__(self, name, value): return setattr(self.__dict__['__subject'], name, value) - def executor_to_lvars(self, kwdict): + def executor_to_lvars(self, kwdict) -> None: if 'executor' in kwdict: kwdict['lvars'] = kwdict['executor'].get_lvars() del kwdict['executor'] else: kwdict['lvars'] = {} - def raw_to_mode(self, mapping): + def raw_to_mode(self, mapping) -> None: try: raw = mapping['raw'] except KeyError: |