From f8c2a438f82eddd270dbe29a637fd3c76a0f9263 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 23 Feb 2023 15:30:59 -0800 Subject: move qt -> qt3 tool, adjust testing as well --- SCons/Tool/qt.py | 371 -------------------------------------------- SCons/Tool/qt.xml | 447 ----------------------------------------------------- SCons/Tool/qt3.py | 375 ++++++++++++++++++++++++++++++++++++++++++++ SCons/Tool/qt3.xml | 447 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 822 insertions(+), 818 deletions(-) delete mode 100644 SCons/Tool/qt.py delete mode 100644 SCons/Tool/qt.xml create mode 100644 SCons/Tool/qt3.py create mode 100644 SCons/Tool/qt3.xml (limited to 'SCons') diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py deleted file mode 100644 index ff995657d..000000000 --- a/SCons/Tool/qt.py +++ /dev/null @@ -1,371 +0,0 @@ -# MIT License -# -# Copyright The SCons Foundation -# -# Permission is hereby granted, free of charge, to any person obtaining -# a copy of this software and associated documentation files (the -# "Software"), to deal in the Software without restriction, including -# without limitation the rights to use, copy, modify, merge, publish, -# distribute, sublicense, and/or sell copies of the Software, and to -# permit persons to whom the Software is furnished to do so, subject to -# the following conditions: -# -# The above copyright notice and this permission notice shall be included -# in all copies or substantial portions of the Software. -# -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY -# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE -# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE -# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION -# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION -# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -"""Tool-specific initialization for Qt. - -There normally shouldn't be any need to import this module directly. -It will usually be imported through the generic SCons.Tool.Tool() -selection method. -""" - -import os.path -import re - -import SCons.Action -import SCons.Builder -import SCons.Defaults -import SCons.Scanner -import SCons.Tool -import SCons.Util -import SCons.Tool.cxx -import SCons.Warnings -cplusplus = SCons.Tool.cxx - -class ToolQtWarning(SCons.Warnings.SConsWarning): - pass - -class GeneratedMocFileNotIncluded(ToolQtWarning): - pass - -class QtdirNotFound(ToolQtWarning): - pass - -SCons.Warnings.enableWarningClass(ToolQtWarning) - -header_extensions = [".h", ".hxx", ".hpp", ".hh"] -if SCons.Util.case_sensitive_suffixes('.h', '.H'): - header_extensions.append('.H') - -cxx_suffixes = cplusplus.CXXSuffixes - - -def find_platform_specific_qt_paths(): - """ - find non-standard QT paths - - If the platform does not put QT tools in standard search paths, - the path is expected to be set using QTDIR. SCons violates - the normal rule of not pulling from the user's environment - in this case. However, some test cases try to validate what - happens when QTDIR is unset, so we need to try to make a guess. - - :return: a guess at a path - """ - - # qt_bin_dirs = [] - qt_bin_dir = None - if os.path.isfile('/etc/redhat-release'): - with open('/etc/redhat-release','r') as rr: - lines = rr.readlines() - distro = lines[0].split()[0] - if distro == 'CentOS': - # Centos installs QT under /usr/{lib,lib64}/qt{4,5,-3.3}/bin - # so we need to handle this differently - # qt_bin_dirs = glob.glob('/usr/lib64/qt*/bin') - # TODO: all current Fedoras do the same, need to look deeper here. - qt_bin_dir = '/usr/lib64/qt-3.3/bin' - - return qt_bin_dir - - -QT_BIN_DIR = find_platform_specific_qt_paths() - -def checkMocIncluded(target, source, env): - moc = target[0] - cpp = source[0] - # looks like cpp.includes is cleared before the build stage :-( - # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ - path = SCons.Defaults.CScan.path(env, moc.cwd) - includes = SCons.Defaults.CScan(cpp, env, path) - if moc not in includes: - SCons.Warnings.warn( - GeneratedMocFileNotIncluded, - "Generated moc file '%s' is not included by '%s'" % - (str(moc), str(cpp))) - -def find_file(filename, paths, node_factory): - for dir in paths: - node = node_factory(filename, dir) - if node.rexists(): - return node - return None - -class _Automoc: - """ - Callable class, which works as an emitter for Programs, SharedLibraries and - StaticLibraries. - """ - - def __init__(self, objBuilderName): - self.objBuilderName = objBuilderName - - def __call__(self, target, source, env): - """ - Smart autoscan function. Gets the list of objects for the Program - or Lib. Adds objects and builders for the special qt files. - """ - try: - if int(env.subst('$QT_AUTOSCAN')) == 0: - return target, source - except ValueError: - pass - try: - debug = int(env.subst('$QT_DEBUG')) - except ValueError: - debug = 0 - - # some shortcuts used in the scanner - splitext = SCons.Util.splitext - objBuilder = getattr(env, self.objBuilderName) - - # some regular expressions: - # Q_OBJECT detection - q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') - # cxx and c comment 'eater' - #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') - # CW: something must be wrong with the regexp. See also bug #998222 - # CURRENTLY THERE IS NO TEST CASE FOR THAT - - # The following is kind of hacky to get builders working properly (FIXME) - objBuilderEnv = objBuilder.env - objBuilder.env = env - mocBuilderEnv = env.Moc.env - env.Moc.env = env - - # make a deep copy for the result; MocH objects will be appended - out_sources = source[:] - - for obj in source: - if not obj.has_builder(): - # binary obj file provided - if debug: - print("scons: qt: '%s' seems to be a binary. Discarded." % str(obj)) - continue - cpp = obj.sources[0] - if not splitext(str(cpp))[1] in cxx_suffixes: - if debug: - print("scons: qt: '%s' is no cxx file. Discarded." % str(cpp)) - # c or fortran source - continue - #cpp_contents = comment.sub('', cpp.get_text_contents()) - if debug: - print("scons: qt: Getting contents of %s" % cpp) - cpp_contents = cpp.get_text_contents() - h=None - for h_ext in header_extensions: - # try to find the header file in the corresponding source - # directory - hname = splitext(cpp.name)[0] + h_ext - h = find_file(hname, (cpp.get_dir(),), env.File) - if h: - if debug: - print("scons: qt: Scanning '%s' (header of '%s')" % (str(h), str(cpp))) - #h_contents = comment.sub('', h.get_text_contents()) - h_contents = h.get_text_contents() - break - if not h and debug: - print("scons: qt: no header for '%s'." % (str(cpp))) - if h and q_object_search.search(h_contents): - # h file with the Q_OBJECT macro found -> add moc_cpp - moc_cpp = env.Moc(h) - moc_o = objBuilder(moc_cpp) - out_sources.append(moc_o) - #moc_cpp.target_scanner = SCons.Defaults.CScan - if debug: - print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))) - if cpp and q_object_search.search(cpp_contents): - # cpp file with Q_OBJECT macro found -> add moc - # (to be included in cpp) - moc = env.Moc(cpp) - env.Ignore(moc, moc) - if debug: - print("scons: qt: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))) - #moc.source_scanner = SCons.Defaults.CScan - # restore the original env attributes (FIXME) - objBuilder.env = objBuilderEnv - env.Moc.env = mocBuilderEnv - - return (target, out_sources) - -AutomocShared = _Automoc('SharedObject') -AutomocStatic = _Automoc('StaticObject') - -def _detect(env): - """Not really safe, but fast method to detect the QT library""" - - QTDIR = env.get('QTDIR',None) - if not QTDIR: - QTDIR = os.environ.get('QTDIR',None) - if not QTDIR: - moc = env.WhereIs('moc') or env.WhereIs('moc',QT_BIN_DIR) - if moc: - QTDIR = os.path.dirname(os.path.dirname(moc)) - SCons.Warnings.warn( - QtdirNotFound, - "Could not detect qt, using moc executable as a hint (QTDIR=%s)" % QTDIR) - else: - QTDIR = None - SCons.Warnings.warn( - QtdirNotFound, - "Could not detect qt, using empty QTDIR") - return QTDIR - -def uicEmitter(target, source, env): - adjustixes = SCons.Util.adjustixes - bs = SCons.Util.splitext(str(source[0].name))[0] - bs = os.path.join(str(target[0].get_dir()),bs) - # first target (header) is automatically added by builder - if len(target) < 2: - # second target is implementation - target.append(adjustixes(bs, - env.subst('$QT_UICIMPLPREFIX'), - env.subst('$QT_UICIMPLSUFFIX'))) - if len(target) < 3: - # third target is moc file - target.append(adjustixes(bs, - env.subst('$QT_MOCHPREFIX'), - env.subst('$QT_MOCHSUFFIX'))) - return target, source - -def uicScannerFunc(node, env, path): - lookout = [] - lookout.extend(env['CPPPATH']) - lookout.append(str(node.rfile().dir)) - includes = re.findall("(.*?)", node.get_text_contents()) - result = [] - for incFile in includes: - dep = env.FindFile(incFile,lookout) - if dep: - result.append(dep) - return result - -uicScanner = SCons.Scanner.ScannerBase(uicScannerFunc, - name = "UicScanner", - node_class = SCons.Node.FS.File, - node_factory = SCons.Node.FS.File, - recursive = 0) - -def generate(env): - """Add Builders and construction variables for qt to an Environment.""" - CLVar = SCons.Util.CLVar - Action = SCons.Action.Action - Builder = SCons.Builder.Builder - - SCons.Warnings.warn( - SCons.Warnings.ToolQtDeprecatedWarning, "Tool module for Qt version 3 is deprecated" - ) - - env.SetDefault(QTDIR = _detect(env), - QT_BINPATH = os.path.join('$QTDIR', 'bin'), - QT_CPPPATH = os.path.join('$QTDIR', 'include'), - QT_LIBPATH = os.path.join('$QTDIR', 'lib'), - QT_MOC = os.path.join('$QT_BINPATH','moc'), - QT_UIC = os.path.join('$QT_BINPATH','uic'), - QT_LIB = 'qt', # may be set to qt-mt - - QT_AUTOSCAN = 1, # scan for moc'able sources - - # Some QT specific flags. I don't expect someone wants to - # manipulate those ... - QT_UICIMPLFLAGS = CLVar(''), - QT_UICDECLFLAGS = CLVar(''), - QT_MOCFROMHFLAGS = CLVar(''), - QT_MOCFROMCXXFLAGS = CLVar('-i'), - - # suffixes/prefixes for the headers / sources to generate - QT_UICDECLPREFIX = '', - QT_UICDECLSUFFIX = '.h', - QT_UICIMPLPREFIX = 'uic_', - QT_UICIMPLSUFFIX = '$CXXFILESUFFIX', - QT_MOCHPREFIX = 'moc_', - QT_MOCHSUFFIX = '$CXXFILESUFFIX', - QT_MOCCXXPREFIX = '', - QT_MOCCXXSUFFIX = '.moc', - QT_UISUFFIX = '.ui', - - # Commands for the qt support ... - # command to generate header, implementation and moc-file - # from a .ui file - QT_UICCOM = [ - CLVar('$QT_UIC $QT_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'), - CLVar('$QT_UIC $QT_UICIMPLFLAGS -impl ${TARGETS[0].file} ' - '-o ${TARGETS[1]} $SOURCE'), - CLVar('$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')], - # command to generate meta object information for a class - # declarated in a header - QT_MOCFROMHCOM = ( - '$QT_MOC $QT_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE'), - # command to generate meta object information for a class - # declarated in a cpp file - QT_MOCFROMCXXCOM = [ - CLVar('$QT_MOC $QT_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'), - Action(checkMocIncluded,None)]) - - # ... and the corresponding builders - uicBld = Builder(action=SCons.Action.Action('$QT_UICCOM', '$QT_UICCOMSTR'), - emitter=uicEmitter, - src_suffix='$QT_UISUFFIX', - suffix='$QT_UICDECLSUFFIX', - prefix='$QT_UICDECLPREFIX', - source_scanner=uicScanner) - mocBld = Builder(action={}, prefix={}, suffix={}) - for h in header_extensions: - act = SCons.Action.Action('$QT_MOCFROMHCOM', '$QT_MOCFROMHCOMSTR') - mocBld.add_action(h, act) - mocBld.prefix[h] = '$QT_MOCHPREFIX' - mocBld.suffix[h] = '$QT_MOCHSUFFIX' - for cxx in cxx_suffixes: - act = SCons.Action.Action('$QT_MOCFROMCXXCOM', '$QT_MOCFROMCXXCOMSTR') - mocBld.add_action(cxx, act) - mocBld.prefix[cxx] = '$QT_MOCCXXPREFIX' - mocBld.suffix[cxx] = '$QT_MOCCXXSUFFIX' - - # register the builders - env['BUILDERS']['Uic'] = uicBld - env['BUILDERS']['Moc'] = mocBld - static_obj, shared_obj = SCons.Tool.createObjBuilders(env) - static_obj.add_src_builder('Uic') - shared_obj.add_src_builder('Uic') - - # We use the emitters of Program / StaticLibrary / SharedLibrary - # to scan for moc'able files - # We can't refer to the builders directly, we have to fetch them - # as Environment attributes because that sets them up to be called - # correctly later by our emitter. - env.AppendUnique(PROGEMITTER =[AutomocStatic], - SHLIBEMITTER=[AutomocShared], - LDMODULEEMITTER=[AutomocShared], - LIBEMITTER =[AutomocStatic], - # Of course, we need to link against the qt libraries - CPPPATH=["$QT_CPPPATH"], - LIBPATH=["$QT_LIBPATH"], - LIBS=['$QT_LIB']) - -def exists(env): - return _detect(env) - -# Local Variables: -# tab-width:4 -# indent-tabs-mode:nil -# End: -# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/SCons/Tool/qt.xml b/SCons/Tool/qt.xml deleted file mode 100644 index 5298a82c4..000000000 --- a/SCons/Tool/qt.xml +++ /dev/null @@ -1,447 +0,0 @@ - - - - -%scons; - -%builders-mod; - -%functions-mod; - -%tools-mod; - -%variables-mod; -]> - - - - - - -Sets &consvars; for building Qt3 applications. - - - -This tool is only suitable for building targeted to Qt3, -which is obsolete -(the tool is deprecated since 4.3). -There are contributed tools for Qt4 and Qt5, see - -https://github.com/SCons/scons-contrib. -Qt4 has also passed end of life for standard support (in Dec 2015). - - - -Note paths for these &consvars; are assembled -using the os.path.join method -so they will have the appropriate separator at runtime, -but are listed here in the various -entries only with the '/' separator -for simplicity. - - - -In addition, the &consvars; -&cv-link-CPPPATH;, -&cv-link-LIBPATH; and -&cv-link-LIBS; may be modified -and the variables -&cv-link-PROGEMITTER;, &cv-link-SHLIBEMITTER; and &cv-link-LIBEMITTER; -are modified. Because the build-performance is affected when using this tool, -you have to explicitly specify it at Environment creation: - - - -Environment(tools=['default','qt']) - - - -The &t-qt; tool supports the following operations: - - - -Automatic moc file generation from header files. -You do not have to specify moc files explicitly, the tool does it for you. -However, there are a few preconditions to do so: Your header file must have -the same filebase as your implementation file and must stay in the same -directory. It must have one of the suffixes -.h, -.hpp, -.H, -.hxx, -.hh. -You can turn off automatic moc file generation by setting -&cv-link-QT_AUTOSCAN; to False. -See also the corresponding -&b-link-Moc; Builder. - - - -Automatic moc file generation from C++ files. -As described in the Qt documentation, include the moc file at the end of -the C++ file. Note that you have to include the file, which is generated -by the transformation -${QT_MOCCXXPREFIX}<basename>${QT_MOCCXXSUFFIX}, by default -<basename>.mo. A warning is generated after building the moc file if you -do not include the correct file. If you are using &f-link-VariantDir;, you may -need to specify duplicate=True. -You can turn off automatic moc file generation by setting &cv-QT_AUTOSCAN; to -False. See also the corresponding -&b-link-Moc; Builder. - - - -Automatic handling of .ui files. -The implementation files generated from .ui -files are handled much the same as yacc or lex files. -Each .ui file given as a source of &b-link-Program;, -&b-link-Library; or &b-link-SharedLibrary; -will generate three files: the declaration file, the -implementation file and a moc file. Because there are also generated headers, -you may need to specify duplicate=True in calls to -&f-link-VariantDir;. -See also the corresponding -&b-link-Uic; Builder. - - - -QTDIR -QT_BINPATH -QT_CPPPATH -QT_LIBPATH -QT_MOC -QT_UIC -QT_LIB -QT_AUTOSCAN -QT_UICIMPLFLAGS -QT_UICDECLFLAGS -QT_MOCFROMHFLAGS -QT_MOCFROMCXXFLAGS -QT_UICDECLPREFIX -QT_UICDECLSUFFIX -QT_UICIMPLPREFIX -QT_UICIMPLSUFFIX -QT_MOCHPREFIX -QT_MOCHSUFFIX -QT_MOCCXXPREFIX -QT_MOCCXXSUFFIX -QT_UISUFFIX -QT_UICCOM -QT_MOCFROMHCOM -QT_MOCFROMCXXCOM - - -QTDIR - - - - - - -Builds an output file from a moc input file. -moc input files are either header files or C++ files. -This builder is only available after using the -tool &t-link-qt;. See the &cv-link-QTDIR; variable for more information. -Example: - - - -env.Moc('foo.h') # generates moc_foo.cc -env.Moc('foo.cpp') # generates foo.moc - - - - - - - -Builds a header file, an implementation file and a moc file from an ui file. -and returns the corresponding nodes in the that order. -This builder is only available after using the tool &t-link-qt;. -Note: you can specify .ui files directly as source -files to the &b-link-Program;, -&b-link-Library; and &b-link-SharedLibrary; builders -without using this builder. Using this builder lets you override the standard -naming conventions (be careful: prefixes are always prepended to names of -built files; if you don't want prefixes, you may set them to ``). -See the &cv-link-QTDIR; variable for more information. -Example: - - - -env.Uic('foo.ui') # -> ['foo.h', 'uic_foo.cc', 'moc_foo.cc'] -env.Uic( - target=Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'), - source='foo.ui' -) # -> ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc'] - - - - - - - -The path to the Qt installation to build against. -If not already set, -&t-link-qt; tool tries to obtain this from -os.environ; -if not found there, it tries to make a guess. - - - - - - - -Turn off scanning for mocable files. Use the &b-link-Moc; Builder to explicitly -specify files to run moc on. - - - - - - - -The path where the Qt binaries are installed. -The default value is '&cv-link-QTDIR;/bin'. - - - - - - - -The path where the Qt header files are installed. -The default value is '&cv-link-QTDIR;/include'. -Note: If you set this variable to None, -the tool won't change the &cv-link-CPPPATH; -construction variable. - - - - - - - -Prints lots of debugging information while scanning for moc files. - - - - - - - -Default value is 'qt'. -You may want to set this to 'qt-mt'. -Note: If you set this variable to None, -the tool won't change the &cv-link-LIBS; variable. - - - - - - - -The path where the Qt libraries are installed. -The default value is '&cv-link-QTDIR;/lib'. -Note: If you set this variable to None, -the tool won't change the &cv-link-LIBPATH; -construction variable. - - - - - - - -Default value is '&cv-link-QT_BINPATH;/moc'. - - - - - - - -Default value is ''. -Prefix for moc output files when source is a C++ file. - - - - - - - -Default value is '.moc'. -Suffix for moc output files when source is a C++ file. - - - - - - - -Default value is '-i'. -These flags are passed to moc when moccing a C++ file. - - - - - - - -Command to generate a moc file from a C++ file. - - - - - - - -The string displayed when generating a moc file from a C++ file. -If this is not set, then &cv-link-QT_MOCFROMCXXCOM; (the command line) is displayed. - - - - - - - -Command to generate a moc file from a header. - - - - - - - -The string displayed when generating a moc file from a C++ file. -If this is not set, then &cv-link-QT_MOCFROMHCOM; (the command line) is displayed. - - - - - - - -Default value is ''. These flags are passed to moc -when moccing a header file. - - - - - - - -Default value is 'moc_'. -Prefix for moc output files when source is a header. - - - - - - - -Default value is '&cv-link-CXXFILESUFFIX;'. -Suffix for moc output files when source is a header. - - - - - - - -Default value is '&cv-link-QT_BINPATH;/uic'. - - - - - - - -Command to generate header files from .ui files. - - - - - - - -The string displayed when generating header files from .ui files. -If this is not set, then &cv-link-QT_UICCOM; (the command line) is displayed. - - - - - - - -Default value is ''. These flags are passed to uic -when creating a header file from a .ui file. - - - - - - - -Default value is ''. -Prefix for uic generated header files. - - - - - - - -Default value is '.h'. -Suffix for uic generated header files. - - - - - - - -Default value is ''. -These flags are passed to uic when creating a C++ -file from a .ui file. - - - - - - - -Default value is 'uic_'. -Prefix for uic generated implementation files. - - - - - - - -Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for uic generated implementation -files. - - - - - - - -Default value is '.ui'. -Suffix of designer input files. - - - - - diff --git a/SCons/Tool/qt3.py b/SCons/Tool/qt3.py new file mode 100644 index 000000000..2b315548e --- /dev/null +++ b/SCons/Tool/qt3.py @@ -0,0 +1,375 @@ +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +"""Tool-specific initialization for Qt. + +There normally shouldn't be any need to import this module directly. +It will usually be imported through the generic SCons.Tool.Tool() +selection method. +""" + +import os.path +import re + +import SCons.Action +import SCons.Builder +import SCons.Defaults +import SCons.Scanner +import SCons.Tool +import SCons.Util +import SCons.Tool.cxx +import SCons.Warnings +cplusplus = SCons.Tool.cxx + +class ToolQtWarning(SCons.Warnings.SConsWarning): + pass + +class GeneratedMocFileNotIncluded(ToolQtWarning): + pass + +class QtdirNotFound(ToolQtWarning): + pass + +SCons.Warnings.enableWarningClass(ToolQtWarning) + +header_extensions = [".h", ".hxx", ".hpp", ".hh"] +if SCons.Util.case_sensitive_suffixes('.h', '.H'): + header_extensions.append('.H') + +cxx_suffixes = cplusplus.CXXSuffixes + + +def find_platform_specific_qt3_paths(): + """ + find non-standard QT paths + + If the platform does not put QT tools in standard search paths, + the path is expected to be set using QT3DIR. SCons violates + the normal rule of not pulling from the user's environment + in this case. However, some test cases try to validate what + happens when QT3DIR is unset, so we need to try to make a guess. + + :return: a guess at a path + """ + + # qt3_bin_dirs = [] + qt3_bin_dir = None + if os.path.isfile('/etc/redhat-release'): + with open('/etc/redhat-release','r') as rr: + lines = rr.readlines() + distro = lines[0].split()[0] + if distro == 'CentOS': + # Centos installs QT under /usr/{lib,lib64}/qt{4,5,-3.3}/bin + # so we need to handle this differently + # qt3_bin_dirs = glob.glob('/usr/lib64/qt*/bin') + # TODO: all current Fedoras do the same, need to look deeper here. + qt3_bin_dir = '/usr/lib64/qt-3.3/bin' + + return qt3_bin_dir + + +QT3_BIN_DIR = find_platform_specific_qt3_paths() + +def checkMocIncluded(target, source, env): + moc = target[0] + cpp = source[0] + # looks like cpp.includes is cleared before the build stage :-( + # not really sure about the path transformations (moc.cwd? cpp.cwd?) :-/ + path = SCons.Defaults.CScan.path(env, moc.cwd) + includes = SCons.Defaults.CScan(cpp, env, path) + if moc not in includes: + SCons.Warnings.warn( + GeneratedMocFileNotIncluded, + "Generated moc file '%s' is not included by '%s'" % + (str(moc), str(cpp))) + +def find_file(filename, paths, node_factory): + for dir in paths: + node = node_factory(filename, dir) + if node.rexists(): + return node + return None + +class _Automoc: + """ + Callable class, which works as an emitter for Programs, SharedLibraries and + StaticLibraries. + """ + + def __init__(self, objBuilderName): + self.objBuilderName = objBuilderName + + def __call__(self, target, source, env): + """ + Smart autoscan function. Gets the list of objects for the Program + or Lib. Adds objects and builders for the special qt3 files. + """ + try: + if int(env.subst('$QT3_AUTOSCAN')) == 0: + return target, source + except ValueError: + pass + try: + debug = int(env.subst('$QT3_DEBUG')) + except ValueError: + debug = 0 + + # some shortcuts used in the scanner + splitext = SCons.Util.splitext + objBuilder = getattr(env, self.objBuilderName) + + # some regular expressions: + # Q_OBJECT detection + q_object_search = re.compile(r'[^A-Za-z0-9]Q_OBJECT[^A-Za-z0-9]') + # cxx and c comment 'eater' + #comment = re.compile(r'(//.*)|(/\*(([^*])|(\*[^/]))*\*/)') + # CW: something must be wrong with the regexp. See also bug #998222 + # CURRENTLY THERE IS NO TEST CASE FOR THAT + + # The following is kind of hacky to get builders working properly (FIXME) + objBuilderEnv = objBuilder.env + objBuilder.env = env + mocBuilderEnv = env.Moc.env + env.Moc.env = env + + # make a deep copy for the result; MocH objects will be appended + out_sources = source[:] + + for obj in source: + if not obj.has_builder(): + # binary obj file provided + if debug: + print("scons: qt3: '%s' seems to be a binary. Discarded." % str(obj)) + continue + cpp = obj.sources[0] + if not splitext(str(cpp))[1] in cxx_suffixes: + if debug: + print("scons: qt3: '%s' is no cxx file. Discarded." % str(cpp)) + # c or fortran source + continue + #cpp_contents = comment.sub('', cpp.get_text_contents()) + if debug: + print("scons: qt3: Getting contents of %s" % cpp) + cpp_contents = cpp.get_text_contents() + h=None + for h_ext in header_extensions: + # try to find the header file in the corresponding source + # directory + hname = splitext(cpp.name)[0] + h_ext + h = find_file(hname, (cpp.get_dir(),), env.File) + if h: + if debug: + print("scons: qt3: Scanning '%s' (header of '%s')" % (str(h), str(cpp))) + #h_contents = comment.sub('', h.get_text_contents()) + h_contents = h.get_text_contents() + break + if not h and debug: + print("scons: qt3: no header for '%s'." % (str(cpp))) + if h and q_object_search.search(h_contents): + # h file with the Q_OBJECT macro found -> add moc_cpp + moc_cpp = env.Moc(h) + moc_o = objBuilder(moc_cpp) + out_sources.append(moc_o) + #moc_cpp.target_scanner = SCons.Defaults.CScan + if debug: + print("scons: qt3: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(h), str(moc_cpp))) + if cpp and q_object_search.search(cpp_contents): + # cpp file with Q_OBJECT macro found -> add moc + # (to be included in cpp) + moc = env.Moc(cpp) + env.Ignore(moc, moc) + if debug: + print("scons: qt3: found Q_OBJECT macro in '%s', moc'ing to '%s'" % (str(cpp), str(moc))) + #moc.source_scanner = SCons.Defaults.CScan + # restore the original env attributes (FIXME) + objBuilder.env = objBuilderEnv + env.Moc.env = mocBuilderEnv + + return (target, out_sources) + +AutomocShared = _Automoc('SharedObject') +AutomocStatic = _Automoc('StaticObject') + +def _detect_qt3(env): + """Not really safe, but fast method to detect the QT library""" + + QT3DIR = env.get('QT3DIR',None) + if not QT3DIR: + QT3DIR = os.environ.get('QTDIR',None) + if not QT3DIR: + moc = env.WhereIs('moc') or env.WhereIs('moc',QT3_BIN_DIR) + if moc: + QT3DIR = os.path.dirname(os.path.dirname(moc)) + SCons.Warnings.warn( + QtdirNotFound, + "Could not detect qt3, using moc executable as a hint (QT3DIR=%s)" % QT3DIR) + else: + QT3DIR = None + SCons.Warnings.warn( + QtdirNotFound, + "Could not detect qt3, using empty QT3DIR") + return QT3DIR + +def uicEmitter(target, source, env): + adjustixes = SCons.Util.adjustixes + bs = SCons.Util.splitext(str(source[0].name))[0] + bs = os.path.join(str(target[0].get_dir()),bs) + # first target (header) is automatically added by builder + if len(target) < 2: + # second target is implementation + target.append(adjustixes(bs, + env.subst('$QT3_UICIMPLPREFIX'), + env.subst('$QT3_UICIMPLSUFFIX'))) + if len(target) < 3: + # third target is moc file + target.append(adjustixes(bs, + env.subst('$QT3_MOCHPREFIX'), + env.subst('$QT3_MOCHSUFFIX'))) + return target, source + +def uicScannerFunc(node, env, path): + lookout = [] + lookout.extend(env['CPPPATH']) + lookout.append(str(node.rfile().dir)) + includes = re.findall("(.*?)", node.get_text_contents()) + result = [] + for incFile in includes: + dep = env.FindFile(incFile,lookout) + if dep: + result.append(dep) + return result + +uicScanner = SCons.Scanner.ScannerBase(uicScannerFunc, + name = "UicScanner", + node_class = SCons.Node.FS.File, + node_factory = SCons.Node.FS.File, + recursive = 0) + +def generate(env): + """Add Builders and construction variables for qt3 to an Environment.""" + CLVar = SCons.Util.CLVar + Action = SCons.Action.Action + Builder = SCons.Builder.Builder + + SCons.Warnings.warn( + SCons.Warnings.ToolQtDeprecatedWarning, "Tool module for Qt version 3 is deprecated" + ) + + qt3path = _detect_qt3(env) + if qt3path is None: + return None + + env.SetDefault(QT3DIR = qt3path, + QT3_BINPATH = os.path.join('$QT3DIR', 'bin'), + QT3_CPPPATH = os.path.join('$QT3DIR', 'include'), + QT3_LIBPATH = os.path.join('$QT3DIR', 'lib'), + QT3_MOC = os.path.join('$QT3_BINPATH','moc'), + QT3_UIC = os.path.join('$QT3_BINPATH','uic'), + QT3_LIB = 'qt', # may be set to qt-mt + + QT3_AUTOSCAN = 1, # scan for moc'able sources + + # Some QT specific flags. I don't expect someone wants to + # manipulate those ... + QT3_UICIMPLFLAGS = CLVar(''), + QT3_UICDECLFLAGS = CLVar(''), + QT3_MOCFROMHFLAGS = CLVar(''), + QT3_MOCFROMCXXFLAGS = CLVar('-i'), + + # suffixes/prefixes for the headers / sources to generate + QT3_UICDECLPREFIX = '', + QT3_UICDECLSUFFIX = '.h', + QT3_UICIMPLPREFIX = 'uic_', + QT3_UICIMPLSUFFIX = '$CXXFILESUFFIX', + QT3_MOCHPREFIX = 'moc_', + QT3_MOCHSUFFIX = '$CXXFILESUFFIX', + QT3_MOCCXXPREFIX = '', + QT3_MOCCXXSUFFIX = '.moc', + QT3_UISUFFIX = '.ui', + + # Commands for the qt3 support ... + # command to generate header, implementation and moc-file + # from a .ui file + QT3_UICCOM = [ + CLVar('$QT3_UIC $QT3_UICDECLFLAGS -o ${TARGETS[0]} $SOURCE'), + CLVar('$QT3_UIC $QT3_UICIMPLFLAGS -impl ${TARGETS[0].file} ' + '-o ${TARGETS[1]} $SOURCE'), + CLVar('$QT3_MOC $QT3_MOCFROMHFLAGS -o ${TARGETS[2]} ${TARGETS[0]}')], + # command to generate meta object information for a class + # declarated in a header + QT3_MOCFROMHCOM = ( + '$QT3_MOC $QT3_MOCFROMHFLAGS -o ${TARGETS[0]} $SOURCE'), + # command to generate meta object information for a class + # declarated in a cpp file + QT3_MOCFROMCXXCOM = [ + CLVar('$QT3_MOC $QT3_MOCFROMCXXFLAGS -o ${TARGETS[0]} $SOURCE'), + Action(checkMocIncluded,None)]) + + # ... and the corresponding builders + uicBld = Builder(action=SCons.Action.Action('$QT3_UICCOM', '$QT3_UICCOMSTR'), + emitter=uicEmitter, + src_suffix='$QT3_UISUFFIX', + suffix='$QT3_UICDECLSUFFIX', + prefix='$QT3_UICDECLPREFIX', + source_scanner=uicScanner) + mocBld = Builder(action={}, prefix={}, suffix={}) + for h in header_extensions: + act = SCons.Action.Action('$QT3_MOCFROMHCOM', '$QT3_MOCFROMHCOMSTR') + mocBld.add_action(h, act) + mocBld.prefix[h] = '$QT3_MOCHPREFIX' + mocBld.suffix[h] = '$QT3_MOCHSUFFIX' + for cxx in cxx_suffixes: + act = SCons.Action.Action('$QT3_MOCFROMCXXCOM', '$QT3_MOCFROMCXXCOMSTR') + mocBld.add_action(cxx, act) + mocBld.prefix[cxx] = '$QT3_MOCCXXPREFIX' + mocBld.suffix[cxx] = '$QT3_MOCCXXSUFFIX' + + # register the builders + env['BUILDERS']['Uic'] = uicBld + env['BUILDERS']['Moc'] = mocBld + static_obj, shared_obj = SCons.Tool.createObjBuilders(env) + static_obj.add_src_builder('Uic') + shared_obj.add_src_builder('Uic') + + # We use the emitters of Program / StaticLibrary / SharedLibrary + # to scan for moc'able files + # We can't refer to the builders directly, we have to fetch them + # as Environment attributes because that sets them up to be called + # correctly later by our emitter. + env.AppendUnique(PROGEMITTER =[AutomocStatic], + SHLIBEMITTER=[AutomocShared], + LDMODULEEMITTER=[AutomocShared], + LIBEMITTER =[AutomocStatic], + # Of course, we need to link against the qt3 libraries + CPPPATH=["$QT3_CPPPATH"], + LIBPATH=["$QT3_LIBPATH"], + LIBS=['$QT3_LIB']) + +def exists(env): + return _detect(env) + +# Local Variables: +# tab-width:4 +# indent-tabs-mode:nil +# End: +# vim: set expandtab tabstop=4 shiftwidth=4: diff --git a/SCons/Tool/qt3.xml b/SCons/Tool/qt3.xml new file mode 100644 index 000000000..88df2e8f2 --- /dev/null +++ b/SCons/Tool/qt3.xml @@ -0,0 +1,447 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Sets &consvars; for building Qt3 applications. + + + +This tool is only suitable for building targeted to Qt3, +which is obsolete +(the tool is deprecated since 4.3). +There are contributed tools for Qt4 and Qt5, see + +https://github.com/SCons/scons-contrib. +Qt4 has also passed end of life for standard support (in Dec 2015). + + + +Note paths for these &consvars; are assembled +using the os.path.join method +so they will have the appropriate separator at runtime, +but are listed here in the various +entries only with the '/' separator +for simplicity. + + + +In addition, the &consvars; +&cv-link-CPPPATH;, +&cv-link-LIBPATH; and +&cv-link-LIBS; may be modified +and the variables +&cv-link-PROGEMITTER;, &cv-link-SHLIBEMITTER; and &cv-link-LIBEMITTER; +are modified. Because the build-performance is affected when using this tool, +you have to explicitly specify it at Environment creation: + + + +Environment(tools=['default','qt3']) + + + +The &t-qt3; tool supports the following operations: + + + +Automatic moc file generation from header files. +You do not have to specify moc files explicitly, the tool does it for you. +However, there are a few preconditions to do so: Your header file must have +the same filebase as your implementation file and must stay in the same +directory. It must have one of the suffixes +.h, +.hpp, +.H, +.hxx, +.hh. +You can turn off automatic moc file generation by setting +&cv-link-qt3_AUTOSCAN; to False. +See also the corresponding +&b-link-Moc; Builder. + + + +Automatic moc file generation from C++ files. +As described in the Qt documentation, include the moc file at the end of +the C++ file. Note that you have to include the file, which is generated +by the transformation +${qt3_MOCCXXPREFIX}<basename>${QT3_MOCCXXSUFFIX}, by default +<basename>.mo. A warning is generated after building the moc file if you +do not include the correct file. If you are using &f-link-VariantDir;, you may +need to specify duplicate=True. +You can turn off automatic moc file generation by setting &cv-QT3_AUTOSCAN; to +False. See also the corresponding +&b-link-Moc; Builder. + + + +Automatic handling of .ui files. +The implementation files generated from .ui +files are handled much the same as yacc or lex files. +Each .ui file given as a source of &b-link-Program;, +&b-link-Library; or &b-link-SharedLibrary; +will generate three files: the declaration file, the +implementation file and a moc file. Because there are also generated headers, +you may need to specify duplicate=True in calls to +&f-link-VariantDir;. +See also the corresponding +&b-link-Uic; Builder. + + + +QT3DIR +QT3_BINPATH +QT3_CPPPATH +QT3_LIBPATH +QT3_MOC +QT3_UIC +QT3_LIB +QT3_AUTOSCAN +QT3_UICIMPLFLAGS +QT3_UICDECLFLAGS +QT3_MOCFROMHFLAGS +QT3_MOCFROMCXXFLAGS +QT3_UICDECLPREFIX +QT3_UICDECLSUFFIX +QT3_UICIMPLPREFIX +QT3_UICIMPLSUFFIX +QT3_MOCHPREFIX +QT3_MOCHSUFFIX +QT3_MOCCXXPREFIX +QT3_MOCCXXSUFFIX +QT3_UISUFFIX +QT3_UICCOM +QT3_MOCFROMHCOM +QT3_MOCFROMCXXCOM + + +QT3DIR + + + + + + +Builds an output file from a moc input file. +moc input files are either header files or C++ files. +This builder is only available after using the +tool &t-link-qt;. See the &cv-link-QT3DIR; variable for more information. +Example: + + + +env.Moc('foo.h') # generates moc_foo.cc +env.Moc('foo.cpp') # generates foo.moc + + + + + + + +Builds a header file, an implementation file and a moc file from an ui file. +and returns the corresponding nodes in the that order. +This builder is only available after using the tool &t-link-qt;. +Note: you can specify .ui files directly as source +files to the &b-link-Program;, +&b-link-Library; and &b-link-SharedLibrary; builders +without using this builder. Using this builder lets you override the standard +naming conventions (be careful: prefixes are always prepended to names of +built files; if you don't want prefixes, you may set them to ``). +See the &cv-link-QT3DIR; variable for more information. +Example: + + + +env.Uic('foo.ui') # -> ['foo.h', 'uic_foo.cc', 'moc_foo.cc'] +env.Uic( + target=Split('include/foo.h gen/uicfoo.cc gen/mocfoo.cc'), + source='foo.ui' +) # -> ['include/foo.h', 'gen/uicfoo.cc', 'gen/mocfoo.cc'] + + + + + + + +The path to the Qt installation to build against. +If not already set, +&t-link-qt; tool tries to obtain this from +os.environ; +if not found there, it tries to make a guess. + + + + + + + +Turn off scanning for mocable files. Use the &b-link-Moc; Builder to explicitly +specify files to run moc on. + + + + + + + +The path where the Qt binaries are installed. +The default value is '&cv-link-QT3DIR;/bin'. + + + + + + + +The path where the Qt header files are installed. +The default value is '&cv-link-QT3DIR;/include'. +Note: If you set this variable to None, +the tool won't change the &cv-link-CPPPATH; +construction variable. + + + + + + + +Prints lots of debugging information while scanning for moc files. + + + + + + + +Default value is 'qt'. +You may want to set this to 'qt-mt'. +Note: If you set this variable to None, +the tool won't change the &cv-link-LIBS; variable. + + + + + + + +The path where the Qt libraries are installed. +The default value is '&cv-link-QT3DIR;/lib'. +Note: If you set this variable to None, +the tool won't change the &cv-link-LIBPATH; +construction variable. + + + + + + + +Default value is '&cv-link-QT3_BINPATH;/moc'. + + + + + + + +Default value is ''. +Prefix for moc output files when source is a C++ file. + + + + + + + +Default value is '.moc'. +Suffix for moc output files when source is a C++ file. + + + + + + + +Default value is '-i'. +These flags are passed to moc when moccing a C++ file. + + + + + + + +Command to generate a moc file from a C++ file. + + + + + + + +The string displayed when generating a moc file from a C++ file. +If this is not set, then &cv-link-QT3_MOCFROMCXXCOM; (the command line) is displayed. + + + + + + + +Command to generate a moc file from a header. + + + + + + + +The string displayed when generating a moc file from a C++ file. +If this is not set, then &cv-link-QT3_MOCFROMHCOM; (the command line) is displayed. + + + + + + + +Default value is ''. These flags are passed to moc +when moccing a header file. + + + + + + + +Default value is 'moc_'. +Prefix for moc output files when source is a header. + + + + + + + +Default value is '&cv-link-CXXFILESUFFIX;'. +Suffix for moc output files when source is a header. + + + + + + + +Default value is '&cv-link-QT3_BINPATH;/uic'. + + + + + + + +Command to generate header files from .ui files. + + + + + + + +The string displayed when generating header files from .ui files. +If this is not set, then &cv-link-QT3_UICCOM; (the command line) is displayed. + + + + + + + +Default value is ''. These flags are passed to uic +when creating a header file from a .ui file. + + + + + + + +Default value is ''. +Prefix for uic generated header files. + + + + + + + +Default value is '.h'. +Suffix for uic generated header files. + + + + + + + +Default value is ''. +These flags are passed to uic when creating a C++ +file from a .ui file. + + + + + + + +Default value is 'uic_'. +Prefix for uic generated implementation files. + + + + + + + +Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for uic generated implementation +files. + + + + + + + +Default value is '.ui'. +Suffix of designer input files. + + + + + -- cgit v1.2.1 From 181ce80cf3df9a8f6ba7efd3dee77d8e92158337 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 24 Feb 2023 01:31:21 +0000 Subject: moved the qt tool to qt3. Changed all QT envvars to be now prefixed with QT3 --- SCons/Tool/qt3.py | 6 +----- SCons/Warnings.py | 2 +- 2 files changed, 2 insertions(+), 6 deletions(-) (limited to 'SCons') diff --git a/SCons/Tool/qt3.py b/SCons/Tool/qt3.py index 2b315548e..4e6975648 100644 --- a/SCons/Tool/qt3.py +++ b/SCons/Tool/qt3.py @@ -271,10 +271,6 @@ def generate(env): Action = SCons.Action.Action Builder = SCons.Builder.Builder - SCons.Warnings.warn( - SCons.Warnings.ToolQtDeprecatedWarning, "Tool module for Qt version 3 is deprecated" - ) - qt3path = _detect_qt3(env) if qt3path is None: return None @@ -366,7 +362,7 @@ def generate(env): LIBS=['$QT3_LIB']) def exists(env): - return _detect(env) + return _detect_qt3(env) # Local Variables: # tab-width:4 diff --git a/SCons/Warnings.py b/SCons/Warnings.py index 754f05d86..f77a24a2d 100644 --- a/SCons/Warnings.py +++ b/SCons/Warnings.py @@ -131,7 +131,7 @@ class DeprecatedDebugOptionsWarning(MandatoryDeprecatedWarning): class DeprecatedMissingSConscriptWarning(DeprecatedWarning): pass -class ToolQtDeprecatedWarning(FutureDeprecatedWarning): +class ToolQtDeprecatedWarning(DeprecatedWarning): pass # The below is a list of 2-tuples. The first element is a class object. -- cgit v1.2.1 From ea8c3ee4c644c0e30fdefea4cac1f8c7e18a9375 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 24 Feb 2023 05:28:32 +0000 Subject: add placeholder tool qt to instruct users to switch to qt3 --- SCons/Tool/qt.py | 35 +++++++++++++++++++++++++++++++++++ SCons/Tool/qt.xml | 34 ++++++++++++++++++++++++++++++++++ 2 files changed, 69 insertions(+) create mode 100644 SCons/Tool/qt.py create mode 100644 SCons/Tool/qt.xml (limited to 'SCons') diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py new file mode 100644 index 000000000..8e34eb7cd --- /dev/null +++ b/SCons/Tool/qt.py @@ -0,0 +1,35 @@ +# MIT License +# +# Copyright The SCons Foundation +# +# Permission is hereby granted, free of charge, to any person obtaining +# a copy of this software and associated documentation files (the +# "Software"), to deal in the Software without restriction, including +# without limitation the rights to use, copy, modify, merge, publish, +# distribute, sublicense, and/or sell copies of the Software, and to +# permit persons to whom the Software is furnished to do so, subject to +# the following conditions: +# +# The above copyright notice and this permission notice shall be included +# in all copies or substantial portions of the Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY +# KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE +# WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +""" +This is a fake tool to instruct any builds still referencing 'qt' instead +of the new 'qt3' or a newer QT builder how to fix their now broken build. +""" +import SCons.Warnings + +def generate(env): + pass + +def exists(env): + return False + diff --git a/SCons/Tool/qt.xml b/SCons/Tool/qt.xml new file mode 100644 index 000000000..3ba71b92c --- /dev/null +++ b/SCons/Tool/qt.xml @@ -0,0 +1,34 @@ + + + + +%scons; + +%builders-mod; + +%functions-mod; + +%tools-mod; + +%variables-mod; +]> + + + + + + +Placeholder tool to alert anyone still using qt tools to switch to qt3 or newer tool. + + + + + -- cgit v1.2.1 From cc77c4bfe5130ddeed0bf176b0b733abb25eadea Mon Sep 17 00:00:00 2001 From: William Deegan Date: Fri, 24 Feb 2023 05:33:22 +0000 Subject: Fix qt3 -> QT3 typos --- SCons/Tool/qt3.xml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'SCons') diff --git a/SCons/Tool/qt3.xml b/SCons/Tool/qt3.xml index 88df2e8f2..306b53c07 100644 --- a/SCons/Tool/qt3.xml +++ b/SCons/Tool/qt3.xml @@ -79,7 +79,7 @@ directory. It must have one of the suffixes .hxx, .hh. You can turn off automatic moc file generation by setting -&cv-link-qt3_AUTOSCAN; to False. +&cv-link-QT3_AUTOSCAN; to False. See also the corresponding &b-link-Moc; Builder. @@ -89,7 +89,7 @@ See also the corresponding As described in the Qt documentation, include the moc file at the end of the C++ file. Note that you have to include the file, which is generated by the transformation -${qt3_MOCCXXPREFIX}<basename>${QT3_MOCCXXSUFFIX}, by default +${QT3_MOCCXXPREFIX}<basename>${QT3_MOCCXXSUFFIX}, by default <basename>.mo. A warning is generated after building the moc file if you do not include the correct file. If you are using &f-link-VariantDir;, you may need to specify duplicate=True. @@ -149,7 +149,7 @@ See also the corresponding Builds an output file from a moc input file. moc input files are either header files or C++ files. This builder is only available after using the -tool &t-link-qt;. See the &cv-link-QT3DIR; variable for more information. +tool &t-link-qt3;. See the &cv-link-QT3DIR; variable for more information. Example: @@ -165,7 +165,7 @@ env.Moc('foo.cpp') # generates foo.moc Builds a header file, an implementation file and a moc file from an ui file. and returns the corresponding nodes in the that order. -This builder is only available after using the tool &t-link-qt;. +This builder is only available after using the tool &t-link-qt3;. Note: you can specify .ui files directly as source files to the &b-link-Program;, &b-link-Library; and &b-link-SharedLibrary; builders @@ -191,7 +191,7 @@ env.Uic( The path to the Qt installation to build against. If not already set, -&t-link-qt; tool tries to obtain this from +&t-link-qt3; tool tries to obtain this from os.environ; if not found there, it tries to make a guess. -- cgit v1.2.1 From a4c586aaf7d453c6f202ec1c026fdacb4f9eb9c8 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 1 Mar 2023 07:51:25 -0700 Subject: Update PR 4305: failing stub qt tool Proposed addition of code to cause stub qt to fail, and test/import.py to detect this situation. Unfortunately, it doesn't seem to work... needs adjustment. Doc updates to record rename version. Signed-off-by: Mats Wichmann --- SCons/Tool/qt.py | 9 ++++-- SCons/Tool/qt3.xml | 82 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 87 insertions(+), 4 deletions(-) (limited to 'SCons') diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py index 8e34eb7cd..607b58d83 100644 --- a/SCons/Tool/qt.py +++ b/SCons/Tool/qt.py @@ -25,11 +25,14 @@ This is a fake tool to instruct any builds still referencing 'qt' instead of the new 'qt3' or a newer QT builder how to fix their now broken build. """ -import SCons.Warnings +import SCons.Errors def generate(env): - pass + raise SCons.Errors.UserError( + "Deprecated tool 'qt' renamed to 'qt3'. " + "Please update your build accordingly. " + "'qt3' will be removed entirely in a future release." + ) def exists(env): return False - diff --git a/SCons/Tool/qt3.xml b/SCons/Tool/qt3.xml index 306b53c07..445751b5e 100644 --- a/SCons/Tool/qt3.xml +++ b/SCons/Tool/qt3.xml @@ -32,7 +32,9 @@ Sets &consvars; for building Qt3 applications. This tool is only suitable for building targeted to Qt3, which is obsolete -(the tool is deprecated since 4.3). +(the tool is deprecated since 4.3, +and was renamed to qt3 in 4.5.0. +). There are contributed tools for Qt4 and Qt5, see https://github.com/SCons/scons-contrib. @@ -195,6 +197,9 @@ If not already set, os.environ; if not found there, it tries to make a guess. + +Changed in 4.5.0: renamed from QTDIR. + @@ -204,6 +209,9 @@ if not found there, it tries to make a guess. Turn off scanning for mocable files. Use the &b-link-Moc; Builder to explicitly specify files to run moc on. + +Changed in 4.5.0: renamed from QT_AUTOSCAN. + @@ -213,6 +221,9 @@ specify files to run moc on. The path where the Qt binaries are installed. The default value is '&cv-link-QT3DIR;/bin'. + +Changed in 4.5.0: renamed from QT_BINPATH. + @@ -225,6 +236,9 @@ Note: If you set this variable to None, the tool won't change the &cv-link-CPPPATH; construction variable. + +Changed in 4.5.0: renamed from QT_CPPPATH. + @@ -233,6 +247,9 @@ construction variable. Prints lots of debugging information while scanning for moc files. + +Changed in 4.5.0: renamed from QT_DEBUG. + @@ -244,6 +261,9 @@ You may want to set this to 'qt-mt'. Note: If you set this variable to None, the tool won't change the &cv-link-LIBS; variable. + +Changed in 4.5.0: renamed from QT_LIB. + @@ -256,6 +276,9 @@ Note: If you set this variable to None, the tool won't change the &cv-link-LIBPATH; construction variable. + +Changed in 4.5.0: renamed from QT_LIBPATH. + @@ -282,6 +305,9 @@ Prefix for moc output files when source is a C++ file. Default value is '.moc'. Suffix for moc output files when source is a C++ file. + +Changed in 4.5.0: renamed from QT_MOCCXXSUFFIX. + @@ -291,6 +317,9 @@ Suffix for moc output files when source is a C++ file. Default value is '-i'. These flags are passed to moc when moccing a C++ file. + +Changed in 4.5.0: renamed from QT_MOCFROMCXXFLAGS. + @@ -299,6 +328,9 @@ These flags are passed to moc when moccing a C++ file. Command to generate a moc file from a C++ file. + +Changed in 4.5.0: renamed from QT_MOCFROMCXXCOM. + @@ -308,6 +340,9 @@ Command to generate a moc file from a C++ file. The string displayed when generating a moc file from a C++ file. If this is not set, then &cv-link-QT3_MOCFROMCXXCOM; (the command line) is displayed. + +Changed in 4.5.0: renamed from QT_MOCFROMCXXCOMSTR. + @@ -316,6 +351,9 @@ If this is not set, then &cv-link-QT3_MOCFROMCXXCOM; (the command line) is displ Command to generate a moc file from a header. + +Changed in 4.5.0: renamed from QT_MOCFROMSHCOM. + @@ -325,6 +363,9 @@ Command to generate a moc file from a header. The string displayed when generating a moc file from a C++ file. If this is not set, then &cv-link-QT3_MOCFROMHCOM; (the command line) is displayed. + +Changed in 4.5.0: renamed from QT_MOCFROMSHCOMSTR. + @@ -334,6 +375,9 @@ If this is not set, then &cv-link-QT3_MOCFROMHCOM; (the command line) is display Default value is ''. These flags are passed to moc when moccing a header file. + +Changed in 4.5.0: renamed from QT_MOCFROMSHFLAGS. + @@ -343,6 +387,9 @@ when moccing a header file. Default value is 'moc_'. Prefix for moc output files when source is a header. + +Changed in 4.5.0: renamed from QT_MOCHPREFIX. + @@ -352,6 +399,9 @@ Prefix for moc output files when source is a header. Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for moc output files when source is a header. + +Changed in 4.5.0: renamed from QT_MOCHSUFFIX. + @@ -360,6 +410,9 @@ Suffix for moc output files when source is a header. Default value is '&cv-link-QT3_BINPATH;/uic'. + +Changed in 4.5.0: renamed from QT_UIC. + @@ -368,6 +421,9 @@ Default value is '&cv-link-QT3_BINPATH;/uic'. Command to generate header files from .ui files. + +Changed in 4.5.0: renamed from QT_UICCOM. + @@ -377,6 +433,9 @@ Command to generate header files from .ui files. The string displayed when generating header files from .ui files. If this is not set, then &cv-link-QT3_UICCOM; (the command line) is displayed. + +Changed in 4.5.0: renamed from QT_UICCOMSTR. + @@ -386,6 +445,9 @@ If this is not set, then &cv-link-QT3_UICCOM; (the command line) is displayed. Default value is ''. These flags are passed to uic when creating a header file from a .ui file. + +Changed in 4.5.0: renamed from QT_UICDECLFLAGS. + @@ -395,6 +457,9 @@ when creating a header file from a .ui file. Default value is ''. Prefix for uic generated header files. + +Changed in 4.5.0: renamed from QT_UICDECLPREFIX. + @@ -404,6 +469,9 @@ Prefix for uic generated header files. Default value is '.h'. Suffix for uic generated header files. + +Changed in 4.5.0: renamed from QT_UICDECLSUFFIX. + @@ -414,6 +482,9 @@ Default value is ''. These flags are passed to uic when creating a C++ file from a .ui file. + +Changed in 4.5.0: renamed from QT_UICIMPFLAGS. + @@ -423,6 +494,9 @@ file from a .ui file. Default value is 'uic_'. Prefix for uic generated implementation files. + +Changed in 4.5.0: renamed from QT_UICIMPLPREFIX. + @@ -432,6 +506,9 @@ Prefix for uic generated implementation files. Default value is '&cv-link-CXXFILESUFFIX;'. Suffix for uic generated implementation files. + +Changed in 4.5.0: renamed from QT_UICIMPLSUFFIX. + @@ -441,6 +518,9 @@ files. Default value is '.ui'. Suffix of designer input files. + +Changed in 4.5.0: renamed from QT_UISUFFIX. + -- cgit v1.2.1 From 1c83ac3958a6779a638fbef98493b178ad264bbd Mon Sep 17 00:00:00 2001 From: William Deegan Date: Thu, 2 Mar 2023 09:09:04 -0800 Subject: [ci skip] Update versionadded for ValidateOptions() --- SCons/Script/Main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'SCons') diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index b90284278..d4228facb 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -505,7 +505,7 @@ def ValidateOptions(throw_exception=False) -> None: :raises SConsBadOptionError: If throw_exception is True and there are invalid options on command line. - .. versionadded:: 4.4.1 + .. versionadded:: 4.5.0 """ OptionsParser.raise_exception_on_error = throw_exception -- cgit v1.2.1 From 34cd13741c84cfc58f13170ce25496633105f4c4 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Fri, 3 Mar 2023 08:26:46 -0700 Subject: man: add a "New in..." to ValidateOPtions [skip appveyor] The new ValidateOptions had a :versionadded: in the docstring, but just noticed the actual manpage entry didn't have similar. Signed-off-by: Mats Wichmann --- SCons/Script/Main.xml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'SCons') diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index fbb90fd07..2070c36b0 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -1000,9 +1000,9 @@ scons --compilers=mingw (the correct flag is --compiler) Could cause SCons to run configure steps with the incorrect compiler. Costing developer time trying to track down why the configure logic failed with a compiler which should work. - - - + + New in version 4.5.0 + -- cgit v1.2.1 From 62d59afee332c3a4184609d19fd20bfd9d4420a1 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 5 Mar 2023 16:43:53 -0500 Subject: Post build commits for 4.5.0 --- SCons/__init__.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'SCons') diff --git a/SCons/__init__.py b/SCons/__init__.py index 8f397bcd2..3abe0db43 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ -__version__="4.4.1" -__copyright__="Copyright (c) 2001 - 2022 The SCons Foundation" +__version__="4.5.0" +__copyright__="Copyright (c) 2001 - 2023 The SCons Foundation" __developer__="bdbaddog" -__date__="Sun, 13 Nov 2022 11:31:29 -0400" +__date__="Sun, 05 Mar 2023 16:19:37 -0400" __buildsys__="M1DOG2021" -__revision__="15379ff3b369560c4bf13459b630387bf7349bb7" -__build__="15379ff3b369560c4bf13459b630387bf7349bb7" +__revision__="3d67dd35fe8fb786afc7af2bf0e31fe2a60b492b" +__build__="3d67dd35fe8fb786afc7af2bf0e31fe2a60b492b" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file -- cgit v1.2.1 From 6d13c3bba872d41e37fc23b7abd8ea49d0caedad Mon Sep 17 00:00:00 2001 From: William Deegan Date: Sun, 5 Mar 2023 17:03:32 -0500 Subject: updates --- SCons/__init__.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'SCons') diff --git a/SCons/__init__.py b/SCons/__init__.py index 3abe0db43..7cb697d2c 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ __version__="4.5.0" __copyright__="Copyright (c) 2001 - 2023 The SCons Foundation" __developer__="bdbaddog" -__date__="Sun, 05 Mar 2023 16:19:37 -0400" +__date__="Sun, 05 Mar 2023 16:59:21 -0400" __buildsys__="M1DOG2021" -__revision__="3d67dd35fe8fb786afc7af2bf0e31fe2a60b492b" -__build__="3d67dd35fe8fb786afc7af2bf0e31fe2a60b492b" +__revision__="2be4e5dc83319222cc725d13f6e98e033c042197" +__build__="2be4e5dc83319222cc725d13f6e98e033c042197" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file -- cgit v1.2.1 From e2b614ddb9c9b1b0e2241e6aff7432a488529e74 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 6 Mar 2023 16:03:22 -0700 Subject: Fix issue with CPPDEFINES and Clone environments Signed-off-by: Mats Wichmann --- SCons/EnvironmentTests.py | 250 +++++++++++++++++++++++++++------------------- SCons/Util/__init__.py | 4 +- 2 files changed, 148 insertions(+), 106 deletions(-) (limited to 'SCons') diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index a021794c9..0f429b492 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -28,7 +28,7 @@ import io import os import sys import unittest -from collections import UserDict as UD, UserList as UL +from collections import UserDict as UD, UserList as UL, deque import TestCmd @@ -1821,147 +1821,189 @@ def exists(env): updates and check that the original remains intact and the copy has the updated values. """ - env1 = self.TestEnvironment(XXX='x', YYY='y') - env2 = env1.Clone() - env1copy = env1.Clone() - assert env1copy == env1 - assert env2 == env1 - env2.Replace(YYY = 'yyy') - assert env1 != env2 - assert env1 == env1copy - - env3 = env1.Clone(XXX='x3', ZZZ='z3') - assert env3 != env1 - assert env3.Dictionary('XXX') == 'x3' - assert env1.Dictionary('XXX') == 'x' - assert env3.Dictionary('YYY') == 'y' - assert env3.Dictionary('ZZZ') == 'z3' - assert env1 == env1copy + with self.subTest(): + env1 = self.TestEnvironment(XXX='x', YYY='y') + env2 = env1.Clone() + env1copy = env1.Clone() + self.assertEqual(env1copy, env1) + self.assertEqual(env2, env1) + env2.Replace(YYY = 'yyy') + self.assertNotEqual(env1, env2) + self.assertEqual(env1, env1copy) + + env3 = env1.Clone(XXX='x3', ZZZ='z3') + self.assertNotEqual(env3, env1) + self.assertEqual(env3.Dictionary('XXX'), 'x3') + self.assertEqual(env1.Dictionary('XXX'), 'x') + self.assertEqual(env3.Dictionary('YYY'), 'y') + self.assertEqual(env3.Dictionary('ZZZ'), 'z3') + self.assertRaises(KeyError, env1.Dictionary, 'ZZZ') # leak test + self.assertEqual(env1, env1copy) # Ensure that lists and dictionaries are deep copied, but not instances - class TestA: - pass + with self.subTest(): + + class TestA: + pass - env1 = self.TestEnvironment(XXX=TestA(), YYY=[1, 2, 3], ZZZ={1: 2, 3: 4}) - env2 = env1.Clone() - env2.Dictionary('YYY').append(4) - env2.Dictionary('ZZZ')[5] = 6 - assert env1.Dictionary('XXX') is env2.Dictionary('XXX') - assert 4 in env2.Dictionary('YYY') - assert 4 not in env1.Dictionary('YYY') - assert 5 in env2.Dictionary('ZZZ') - assert 5 not in env1.Dictionary('ZZZ') - - # - env1 = self.TestEnvironment(BUILDERS={'b1': Builder()}) - assert hasattr(env1, 'b1'), "env1.b1 was not set" - assert env1.b1.object == env1, "b1.object doesn't point to env1" - env2 = env1.Clone(BUILDERS = {'b2' : Builder()}) - assert env2 != env1 - assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1" - assert env1.b1.object == env1, "b1.object was changed" - assert not hasattr(env2, 'b1'), "b1 was not cleared from env2" - assert hasattr(env2, 'b2'), "env2.b2 was not set" - assert env2.b2.object == env2, "b2.object doesn't point to env2" + env1 = self.TestEnvironment( + XXX=TestA(), + YYY=[1, 2, 3], + ZZZ={1: 2, 3: 4} + ) + env2 = env1.Clone() + env2.Dictionary('YYY').append(4) + env2.Dictionary('ZZZ')[5] = 6 + self.assertIs(env1.Dictionary('XXX'), env2.Dictionary('XXX')) + self.assertIn(4, env2.Dictionary('YYY')) + self.assertNotIn(4, env1.Dictionary('YYY')) + self.assertIn(5, env2.Dictionary('ZZZ')) + self.assertNotIn(5, env1.Dictionary('ZZZ')) + + # We also need to look at the special cases in semi_deepcopy() + # used when cloning - these should not leak to the original either + with self.subTest(): + env1 = self.TestEnvironment( + XXX=deque([1, 2, 3]), + YYY=UL([1, 2, 3]), + ZZZ=UD({1: 2, 3: 4}), + ) + env2 = env1.Clone() + env2.Dictionary('XXX').append(4) + env2.Dictionary('YYY').append(4) + env2.Dictionary('ZZZ')[5] = 6 + self.assertIn(4, env2.Dictionary('XXX')) + self.assertNotIn(4, env1.Dictionary('XXX')) + self.assertIn(4, env2.Dictionary('YYY')) + self.assertNotIn(4, env1.Dictionary('YYY')) + self.assertIn(5, env2.Dictionary('ZZZ')) + self.assertNotIn(5, env1.Dictionary('ZZZ')) + + # BUILDERS is special... + with self.subTest(): + env1 = self.TestEnvironment(BUILDERS={'b1': Builder()}) + assert hasattr(env1, 'b1'), "env1.b1 was not set" + assert env1.b1.object == env1, "b1.object doesn't point to env1" + env2 = env1.Clone(BUILDERS = {'b2' : Builder()}) + assert env2 != env1 + assert hasattr(env1, 'b1'), "b1 was mistakenly cleared from env1" + assert env1.b1.object == env1, "b1.object was changed" + assert not hasattr(env2, 'b1'), "b1 was not cleared from env2" + assert hasattr(env2, 'b2'), "env2.b2 was not set" + assert env2.b2.object == env2, "b2.object doesn't point to env2" # Ensure that specifying new tools in a copied environment works. - def foo(env): env['FOO'] = 1 - def bar(env): env['BAR'] = 2 - def baz(env): env['BAZ'] = 3 - env1 = self.TestEnvironment(tools=[foo]) - env2 = env1.Clone() - env3 = env1.Clone(tools=[bar, baz]) - - assert env1.get('FOO') == 1 - assert env1.get('BAR') is None - assert env1.get('BAZ') is None - assert env2.get('FOO') == 1 - assert env2.get('BAR') is None - assert env2.get('BAZ') is None - assert env3.get('FOO') == 1 - assert env3.get('BAR') == 2 - assert env3.get('BAZ') == 3 + with self.subTest(): + + def foo(env): + env['FOO'] = 1 + + def bar(env): + env['BAR'] = 2 + + def baz(env): + env['BAZ'] = 3 + + env1 = self.TestEnvironment(tools=[foo]) + env2 = env1.Clone() + env3 = env1.Clone(tools=[bar, baz]) + + assert env1.get('FOO') == 1 + assert env1.get('BAR') is None + assert env1.get('BAZ') is None + assert env2.get('FOO') == 1 + assert env2.get('BAR') is None + assert env2.get('BAZ') is None + assert env3.get('FOO') == 1 + assert env3.get('BAR') == 2 + assert env3.get('BAZ') == 3 # Ensure that recursive variable substitution when copying # environments works properly. - env1 = self.TestEnvironment(CCFLAGS = '-DFOO', XYZ = '-DXYZ') - env2 = env1.Clone(CCFLAGS = '$CCFLAGS -DBAR', - XYZ = ['-DABC', 'x $XYZ y', '-DDEF']) - x = env2.get('CCFLAGS') - assert x == '-DFOO -DBAR', x - x = env2.get('XYZ') - assert x == ['-DABC', 'x -DXYZ y', '-DDEF'], x + with self.subTest(): + env1 = self.TestEnvironment(CCFLAGS='-DFOO', XYZ='-DXYZ') + env2 = env1.Clone( + CCFLAGS='$CCFLAGS -DBAR', XYZ=['-DABC', 'x $XYZ y', '-DDEF'] + ) + x = env2.get('CCFLAGS') + assert x == '-DFOO -DBAR', x + x = env2.get('XYZ') + assert x == ['-DABC', 'x -DXYZ y', '-DDEF'], x # Ensure that special properties of a class don't get # lost on copying. - env1 = self.TestEnvironment(FLAGS = CLVar('flag1 flag2')) - x = env1.get('FLAGS') - assert x == ['flag1', 'flag2'], x - env2 = env1.Clone() - env2.Append(FLAGS = 'flag3 flag4') - x = env2.get('FLAGS') - assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x - x = env1.get('FLAGS') - assert x == ['flag1', 'flag2'], x + with self.subTest(): + env1 = self.TestEnvironment(FLAGS=CLVar('flag1 flag2')) + x = env1.get('FLAGS') + assert x == ['flag1', 'flag2'], x + env2 = env1.Clone() + env2.Append(FLAGS='flag3 flag4') + x = env2.get('FLAGS') + assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x + x = env1.get('FLAGS') + assert x == ['flag1', 'flag2'], x # Ensure that appending directly to a copied CLVar # doesn't modify the original. - env1 = self.TestEnvironment(FLAGS = CLVar('flag1 flag2')) - x = env1.get('FLAGS') - assert x == ['flag1', 'flag2'], x - env2 = env1.Clone() - env2['FLAGS'] += ['flag3', 'flag4'] - x = env2.get('FLAGS') - assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x - x = env1.get('FLAGS') - assert x == ['flag1', 'flag2'], x + with self.subTest(): + env1 = self.TestEnvironment(FLAGS=CLVar('flag1 flag2')) + x = env1.get('FLAGS') + assert x == ['flag1', 'flag2'], x + env2 = env1.Clone() + env2['FLAGS'] += ['flag3', 'flag4'] + x = env2.get('FLAGS') + assert x == ['flag1', 'flag2', 'flag3', 'flag4'], x + x = env1.get('FLAGS') + assert x == ['flag1', 'flag2'], x # Test that the environment stores the toolpath and # re-uses it for copies. - test = TestCmd.TestCmd(workdir = '') + with self.subTest(): + test = TestCmd.TestCmd(workdir='') - test.write('xxx.py', """\ + test.write('xxx.py', """\ def exists(env): return True def generate(env): env['XXX'] = 'one' """) - test.write('yyy.py', """\ + test.write('yyy.py', """\ def exists(env): return True def generate(env): env['YYY'] = 'two' """) - env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')]) - assert env['XXX'] == 'one', env['XXX'] - env = env.Clone(tools=['yyy']) - assert env['YYY'] == 'two', env['YYY'] - + env = self.TestEnvironment(tools=['xxx'], toolpath=[test.workpath('')]) + assert env['XXX'] == 'one', env['XXX'] + env = env.Clone(tools=['yyy']) + assert env['YYY'] == 'two', env['YYY'] # Test that - real_value = [4] + with self.subTest(): + real_value = [4] - def my_tool(env, rv=real_value): - assert env['KEY_THAT_I_WANT'] == rv[0] - env['KEY_THAT_I_WANT'] = rv[0] + 1 + def my_tool(env, rv=real_value): + assert env['KEY_THAT_I_WANT'] == rv[0] + env['KEY_THAT_I_WANT'] = rv[0] + 1 - env = self.TestEnvironment() + env = self.TestEnvironment() - real_value[0] = 5 - env = env.Clone(KEY_THAT_I_WANT=5, tools=[my_tool]) - assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT'] + real_value[0] = 5 + env = env.Clone(KEY_THAT_I_WANT=5, tools=[my_tool]) + assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT'] - real_value[0] = 6 - env = env.Clone(KEY_THAT_I_WANT=6, tools=[my_tool]) - assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT'] + real_value[0] = 6 + env = env.Clone(KEY_THAT_I_WANT=6, tools=[my_tool]) + assert env['KEY_THAT_I_WANT'] == real_value[0], env['KEY_THAT_I_WANT'] # test for pull request #150 - env = self.TestEnvironment() - env._dict.pop('BUILDERS') - assert ('BUILDERS' in env) is False - env2 = env.Clone() + with self.subTest(): + env = self.TestEnvironment() + env._dict.pop('BUILDERS') + assert ('BUILDERS' in env) is False + env2 = env.Clone() def test_Detect(self): """Test Detect()ing tools""" diff --git a/SCons/Util/__init__.py b/SCons/Util/__init__.py index 0281e1e17..ffc636414 100644 --- a/SCons/Util/__init__.py +++ b/SCons/Util/__init__.py @@ -32,7 +32,7 @@ import os import re import sys import time -from collections import UserDict, UserList, OrderedDict +from collections import UserDict, UserList, OrderedDict, deque from contextlib import suppress from types import MethodType, FunctionType from typing import Optional, Union @@ -527,7 +527,7 @@ def semi_deepcopy(obj): if isinstance(obj, UserDict): return obj.__class__(semi_deepcopy_dict(obj)) - if isinstance(obj, UserList): + if isinstance(obj, (UserList, deque)): return obj.__class__(_semi_deepcopy_list(obj)) return obj -- cgit v1.2.1 From 3dc74b18eccbd9561128ed1c608a13009a39915c Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 6 Mar 2023 23:11:13 -0500 Subject: added example code which demonstrates the problem introduced in 4.5.0 and fixed in 4.5.1 --- SCons/EnvironmentTests.py | 18 +++++++++--------- SCons/Util/__init__.py | 1 + 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'SCons') diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index 0f429b492..fb089b1a5 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -1869,15 +1869,15 @@ def exists(env): ZZZ=UD({1: 2, 3: 4}), ) env2 = env1.Clone() - env2.Dictionary('XXX').append(4) - env2.Dictionary('YYY').append(4) - env2.Dictionary('ZZZ')[5] = 6 - self.assertIn(4, env2.Dictionary('XXX')) - self.assertNotIn(4, env1.Dictionary('XXX')) - self.assertIn(4, env2.Dictionary('YYY')) - self.assertNotIn(4, env1.Dictionary('YYY')) - self.assertIn(5, env2.Dictionary('ZZZ')) - self.assertNotIn(5, env1.Dictionary('ZZZ')) + env2['XXX'].append(4) + env2['YYY'].append(4) + env2['ZZZ'][5] = 6 + self.assertIn(4, env2['XXX']) + self.assertNotIn(4, env1['XXX']) + self.assertIn(4, env2['YYY']) + self.assertNotIn(4, env1['YYY']) + self.assertIn(5, env2['ZZZ']) + self.assertNotIn(5, env1['ZZZ']) # BUILDERS is special... with self.subTest(): diff --git a/SCons/Util/__init__.py b/SCons/Util/__init__.py index ffc636414..2760298b5 100644 --- a/SCons/Util/__init__.py +++ b/SCons/Util/__init__.py @@ -516,6 +516,7 @@ _semi_deepcopy_dispatch = { tuple: _semi_deepcopy_tuple, } + def semi_deepcopy(obj): copier = _semi_deepcopy_dispatch.get(type(obj)) if copier: -- cgit v1.2.1 From 9bc9994b984112f4d90d390988c349b0c8fe9d8c Mon Sep 17 00:00:00 2001 From: William Deegan Date: Mon, 6 Mar 2023 23:45:02 -0500 Subject: 4.5.1 release items --- SCons/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'SCons') diff --git a/SCons/__init__.py b/SCons/__init__.py index 7cb697d2c..f53583b12 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ -__version__="4.5.0" +__version__="4.5.1" __copyright__="Copyright (c) 2001 - 2023 The SCons Foundation" __developer__="bdbaddog" -__date__="Sun, 05 Mar 2023 16:59:21 -0400" +__date__="Mon, 06 Mar 2023 23:32:38 -0400" __buildsys__="M1DOG2021" -__revision__="2be4e5dc83319222cc725d13f6e98e033c042197" -__build__="2be4e5dc83319222cc725d13f6e98e033c042197" +__revision__="49578b34582d9e92dac7d713a8e58599ae35aa63" +__build__="49578b34582d9e92dac7d713a8e58599ae35aa63" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file -- cgit v1.2.1 From a4ab466c6df5bd3187e78c36bfa8f68e1fb7659e Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Thu, 9 Mar 2023 12:05:47 -0700 Subject: Fix problem when MergeFlags adds to existing CPPDEFINES MergeFlags has a post-processing step if the *unique* flag evaluates True which loops through and removes the duplicates. This step uses slicing (for v in orig[::-1]), which fails if the item being cleaned is a deque - which CPPDEFINES can now be. It would also cause the deque to be replaced with a list. Detect this case and handle separately. Note the same post-processing step assures each modified object will be replaced - Override(parse_flags=xxx) silently counted on this so it does not end up sharing variables with the overridden env. This situation remains, and is accounted for by the patch. Unit test and e2e tests are extended to check that MergeFlags can now add correctly, and that Override leaves the variables independent, not shared. Fixes #4231 Signed-off-by: Mats Wichmann --- SCons/Environment.py | 19 ++++++++++++++++++- SCons/EnvironmentTests.py | 23 ++++++++++++++--------- 2 files changed, 32 insertions(+), 10 deletions(-) (limited to 'SCons') diff --git a/SCons/Environment.py b/SCons/Environment.py index 9140d2726..bd94832a1 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -1043,6 +1043,12 @@ class SubstitutionEnvironment: 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). @@ -1077,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: @@ -1095,6 +1111,7 @@ class SubstitutionEnvironment: for v in orig[::-1]: if v not in t: t.insert(0, v) + self[key] = t @@ -1419,7 +1436,7 @@ class Base(SubstitutionEnvironment): if key == 'CPPDEFINES': _add_cppdefines(self._dict, val) continue - + try: orig = self._dict[key] except KeyError: diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index fb089b1a5..81143d5c0 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -902,6 +902,11 @@ sys.exit(0) assert env['A'] == ['aaa'], env['A'] assert env['B'] == ['b', 'bb', 'bbb'], env['B'] + # issue #4231: CPPDEFINES can be a deque, tripped up merge logic + env = Environment(CPPDEFINES=deque(['aaa', 'bbb'])) + env.MergeFlags({'CPPDEFINES': 'ccc'}) + self.assertEqual(env['CPPDEFINES'], deque(['aaa', 'bbb', 'ccc'])) + # issue #3665: if merging dict which is a compound object # (i.e. value can be lists, etc.), the value object should not # be modified. per the issue, this happened if key not in env. @@ -2167,7 +2172,7 @@ def generate(env): ('-isystem', '/usr/include/foo2'), ('-idirafter', '/usr/include/foo3'), '+DD64'], env['CCFLAGS'] - assert env['CPPDEFINES'] == ['FOO', ['BAR', 'value']], env['CPPDEFINES'] + self.assertEqual(list(env['CPPDEFINES']), ['FOO', ['BAR', 'value']]) assert env['CPPFLAGS'] == ['', '-Wp,-cpp'], env['CPPFLAGS'] assert env['CPPPATH'] == ['string', '/usr/include/fum', 'bar'], env['CPPPATH'] assert env['FRAMEWORKPATH'] == ['fwd1', 'fwd2', 'fwd3'], env['FRAMEWORKPATH'] @@ -3662,10 +3667,10 @@ def generate(env): env = Environment(tools=[], CCFLAGS=None, parse_flags = '-Y') assert env['CCFLAGS'] == ['-Y'], env['CCFLAGS'] - env = Environment(tools=[], CPPDEFINES = 'FOO', parse_flags = '-std=c99 -X -DBAR') + env = Environment(tools=[], CPPDEFINES='FOO', parse_flags='-std=c99 -X -DBAR') assert env['CFLAGS'] == ['-std=c99'], env['CFLAGS'] assert env['CCFLAGS'] == ['-X'], env['CCFLAGS'] - assert env['CPPDEFINES'] == ['FOO', 'BAR'], env['CPPDEFINES'] + self.assertEqual(list(env['CPPDEFINES']), ['FOO', 'BAR']) def test_clone_parse_flags(self): """Test the env.Clone() parse_flags argument""" @@ -3687,8 +3692,7 @@ def generate(env): assert 'CCFLAGS' not in env assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS'] assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES'] - assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES'] - + self.assertEqual(list(env2['CPPDEFINES']), ['FOO','BAR']) class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): @@ -3978,15 +3982,16 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert env['CCFLAGS'] is None, env['CCFLAGS'] assert env2['CCFLAGS'] == ['-Y'], env2['CCFLAGS'] - env = SubstitutionEnvironment(CPPDEFINES = 'FOO') - env2 = env.Override({'parse_flags' : '-std=c99 -X -DBAR'}) + env = SubstitutionEnvironment(CPPDEFINES='FOO') + env2 = env.Override({'parse_flags': '-std=c99 -X -DBAR'}) assert 'CFLAGS' not in env assert env2['CFLAGS'] == ['-std=c99'], env2['CFLAGS'] assert 'CCFLAGS' not in env assert env2['CCFLAGS'] == ['-X'], env2['CCFLAGS'] + # make sure they are independent + self.assertIsNot(env['CPPDEFINES'], env2['CPPDEFINES']) assert env['CPPDEFINES'] == 'FOO', env['CPPDEFINES'] - assert env2['CPPDEFINES'] == ['FOO','BAR'], env2['CPPDEFINES'] - + self.assertEqual(list(env2['CPPDEFINES']), ['FOO','BAR']) class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): -- cgit v1.2.1 From 7dfbbcf697f47680a101d846f836e85bc14eef13 Mon Sep 17 00:00:00 2001 From: William Deegan Date: Tue, 21 Mar 2023 12:14:48 -0400 Subject: Updates for 4.5.2. Added zipapp package to scons-locals --- SCons/__init__.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'SCons') diff --git a/SCons/__init__.py b/SCons/__init__.py index f53583b12..12be8e6c4 100644 --- a/SCons/__init__.py +++ b/SCons/__init__.py @@ -1,9 +1,9 @@ -__version__="4.5.1" +__version__="4.5.2" __copyright__="Copyright (c) 2001 - 2023 The SCons Foundation" __developer__="bdbaddog" -__date__="Mon, 06 Mar 2023 23:32:38 -0400" +__date__="Tue, 21 Mar 2023 12:11:27 -0400" __buildsys__="M1DOG2021" -__revision__="49578b34582d9e92dac7d713a8e58599ae35aa63" -__build__="49578b34582d9e92dac7d713a8e58599ae35aa63" +__revision__="120fd4f633e9ef3cafbc0fec35306d7555ffd1db" +__build__="120fd4f633e9ef3cafbc0fec35306d7555ffd1db" # make sure compatibility is always in place import SCons.compat # noqa \ No newline at end of file -- cgit v1.2.1 From fd166f513214e81d3622485128739354dfa11a24 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 21 Mar 2023 13:30:36 -0600 Subject: Fix dictifyCPPDEFINES handlong of macro strings CPPDEFINES can contain name=value strings, either a single one, or one or more in a sequence type. After conversion (subsequent Append/Prepend to CPPDEFINES), these will be stored as tuples, but it is possible to hit cases where the type conversion has never been triggered. The C Scanner has its own routine to process CPPDEFINES, and missed these cases, which are now handled. The testcases in issue 4193 which showed this problem are now included in the C scanner unit tests, and the test for dictifyCPPDEFINES is expanded to check these two forms. Fixes #4193 Signed-off-by: Mats Wichmann --- SCons/Scanner/C.py | 21 +++++++++-- SCons/Scanner/CTests.py | 98 ++++++++++++++++++++++++++++++++++--------------- 2 files changed, 85 insertions(+), 34 deletions(-) (limited to 'SCons') diff --git a/SCons/Scanner/C.py b/SCons/Scanner/C.py index a066104e5..418454ff6 100644 --- a/SCons/Scanner/C.py +++ b/SCons/Scanner/C.py @@ -64,22 +64,35 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): def dictify_CPPDEFINES(env) -> dict: """Returns CPPDEFINES converted to a dict.""" cppdefines = env.get('CPPDEFINES', {}) + result = {} if cppdefines is None: - return {} + return result if SCons.Util.is_Sequence(cppdefines): - result = {} for c in cppdefines: if SCons.Util.is_Sequence(c): try: result[c[0]] = c[1] except IndexError: - # it could be a one-item sequence + # could be a one-item sequence result[c[0]] = None + elif SCons.Util.is_String(c): + try: + name, value = c.split('=') + result[name] = value + except ValueError: + result[c] = None else: + # don't really know what to do here result[c] = None return result + if SCons.Util.is_String(cppdefines): + try: + name, value = cppdefines.split('=') + return {name: value} + except ValueError: + return {cppdefines: None} if not SCons.Util.is_Dict(cppdefines): - return {cppdefines : None} + return {cppdefines: None} return cppdefines class SConsCPPScannerWrapper: diff --git a/SCons/Scanner/CTests.py b/SCons/Scanner/CTests.py index 14e156e71..e9780d0fc 100644 --- a/SCons/Scanner/CTests.py +++ b/SCons/Scanner/CTests.py @@ -91,6 +91,27 @@ int main(void) } """) +# include using a macro, defined in source file +test.write('f9a.c', """\ +#define HEADER "f9.h" +#include HEADER + +int main(void) +{ + return 0; +} +""") + +# include using a macro, not defined in source file +test.write('f9b.c', """\ +#include HEADER + +int main(void) +{ + return 0; +} +""") + # for Emacs -> " @@ -99,7 +120,7 @@ test.subdir('d1', ['d1', 'd2']) headers = ['f1.h','f2.h', 'f3-test.h', 'fi.h', 'fj.h', 'never.h', 'd1/f1.h', 'd1/f2.h', 'd1/f3-test.h', 'd1/fi.h', 'd1/fj.h', 'd1/d2/f1.h', 'd1/d2/f2.h', 'd1/d2/f3-test.h', - 'd1/d2/f4.h', 'd1/d2/fi.h', 'd1/d2/fj.h'] + 'd1/d2/f4.h', 'd1/d2/fi.h', 'd1/d2/fj.h', 'f9.h'] for h in headers: test.write(h, " ") @@ -224,7 +245,7 @@ def deps_match(self, deps, headers): global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) - self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) + self.assertTrue(scanned == expect, f"expect {expect} != scanned {scanned}") # define some tests: @@ -443,7 +464,7 @@ class CScannerTestCase15(unittest.TestCase): env = DummyEnvironment(CPPSUFFIXES = suffixes) s = SCons.Scanner.C.CScanner() for suffix in suffixes: - assert suffix in s.get_skeys(env), "%s not in skeys" % suffix + assert suffix in s.get_skeys(env), f"{suffix} not in skeys" class CConditionalScannerTestCase1(unittest.TestCase): @@ -490,6 +511,29 @@ class CConditionalScannerTestCase3(unittest.TestCase): headers = ['d1/f1.h'] deps_match(self, deps, headers) + +class CConditionalScannerTestCase4(unittest.TestCase): + def runTest(self): + """Test that dependency is detected if #include uses a macro.""" + + # first try the macro defined in the source file + with self.subTest(): + env = DummyEnvironment() + s = SCons.Scanner.C.CConditionalScanner() + deps = s(env.File('f9a.c'), env, s.path(env)) + headers = ['f9.h'] + deps_match(self, deps, headers) + + # then try the macro defined on the command line + with self.subTest(): + env = DummyEnvironment(CPPDEFINES='HEADER=\\"f9.h\\"') + #env = DummyEnvironment(CPPDEFINES=['HEADER=\\"f9.h\\"']) + s = SCons.Scanner.C.CConditionalScanner() + deps = s(env.File('f9b.c'), env, s.path(env)) + headers = ['f9.h'] + deps_match(self, deps, headers) + + class dictify_CPPDEFINESTestCase(unittest.TestCase): def runTest(self): """Make sure single-item tuples convert correctly. @@ -497,35 +541,29 @@ class dictify_CPPDEFINESTestCase(unittest.TestCase): This is a regression test: AppendUnique turns sequences into lists of tuples, and dictify could gack on these. """ - env = DummyEnvironment(CPPDEFINES=(("VALUED_DEFINE", 1), ("UNVALUED_DEFINE", ))) - d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'VALUED_DEFINE': 1, 'UNVALUED_DEFINE': None} - assert d == expect - -def suite(): - suite = unittest.TestSuite() - suite.addTest(CScannerTestCase1()) - suite.addTest(CScannerTestCase2()) - suite.addTest(CScannerTestCase3()) - suite.addTest(CScannerTestCase4()) - suite.addTest(CScannerTestCase5()) - suite.addTest(CScannerTestCase6()) - suite.addTest(CScannerTestCase8()) - suite.addTest(CScannerTestCase9()) - suite.addTest(CScannerTestCase10()) - suite.addTest(CScannerTestCase11()) - suite.addTest(CScannerTestCase12()) - suite.addTest(CScannerTestCase13()) - suite.addTest(CScannerTestCase14()) - suite.addTest(CScannerTestCase15()) - suite.addTest(CConditionalScannerTestCase1()) - suite.addTest(CConditionalScannerTestCase2()) - suite.addTest(CConditionalScannerTestCase3()) - suite.addTest(dictify_CPPDEFINESTestCase()) - return suite + with self.subTest(): + env = DummyEnvironment(CPPDEFINES=[("VALUED_DEFINE", 1), ("UNVALUED_DEFINE", )]) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {'VALUED_DEFINE': 1, 'UNVALUED_DEFINE': None} + self.assertEqual(d, expect) + + # string-valued define in a sequence + with self.subTest(): + env = DummyEnvironment(CPPDEFINES=["STRING=VALUE"]) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {'STRING': 'VALUE'} + self.assertEqual(d, expect) + + # string-valued define by itself + with self.subTest(): + env = DummyEnvironment(CPPDEFINES="STRING=VALUE") + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {'STRING': 'VALUE'} + self.assertEqual(d, expect) + if __name__ == "__main__": - TestUnit.run(suite()) + unittest.main() # Local Variables: # tab-width:4 -- cgit v1.2.1 From 0d7dbd4b904dc6392851060d070244219cdd567d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Wed, 22 Mar 2023 07:45:42 -0600 Subject: dictify_CPPDEFINES: also handle single tuple * Single-tuple CPPDEFINES was not handled. * Add some more unit tests. * Add some comments - that we need to keep in sync with processDefines, but don't actually call it (the routine *could* be rewritten to process the result of processDefines instead of the bare CPPDEFINES, but currently doesn't do that). Signed-off-by: Mats Wichmann --- SCons/Scanner/C.py | 37 ++++++++++++++++++++++++++++++++----- SCons/Scanner/CTests.py | 45 ++++++++++++++++++++++++++++----------------- 2 files changed, 60 insertions(+), 22 deletions(-) (limited to 'SCons') diff --git a/SCons/Scanner/C.py b/SCons/Scanner/C.py index 418454ff6..31ab7e62e 100644 --- a/SCons/Scanner/C.py +++ b/SCons/Scanner/C.py @@ -21,7 +21,12 @@ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. -"""Dependency scanner for C/C++ code.""" +"""Dependency scanner for C/C++ code. + +Two scanners are defined here: the default CScanner, and the optional +CConditionalScanner, which must be explicitly selected by calling +add_scanner() for each affected suffix. +""" import SCons.Node.FS import SCons.cpp @@ -62,11 +67,30 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): return '' def dictify_CPPDEFINES(env) -> dict: - """Returns CPPDEFINES converted to a dict.""" + """Returns CPPDEFINES converted to a dict. + + This should be similar to :func:`~SCons.Defaults.processDefines`. + Unfortunately, we can't do the simple thing of calling that routine and + passing the result to the dict() constructor, because it turns the defines + into a list of "name=value" pairs, which the dict constructor won't + consume correctly. Also cannot just call dict on CPPDEFINES itself - it's + fine if it's stored in the converted form (currently deque of tuples), but + CPPDEFINES could be in other formats too. + + So we have to do all the work here - keep concepts in sync with + ``processDefines``. + """ cppdefines = env.get('CPPDEFINES', {}) result = {} if cppdefines is None: return result + + if SCons.Util.is_Tuple(cppdefines): + try: + return {cppdefines[0]: cppdefines[1]} + except IndexError: + return {cppdefines[0]: None} + if SCons.Util.is_Sequence(cppdefines): for c in cppdefines: if SCons.Util.is_Sequence(c): @@ -85,15 +109,18 @@ def dictify_CPPDEFINES(env) -> dict: # don't really know what to do here result[c] = None return result + if SCons.Util.is_String(cppdefines): try: name, value = cppdefines.split('=') return {name: value} except ValueError: return {cppdefines: None} - if not SCons.Util.is_Dict(cppdefines): - return {cppdefines: None} - return cppdefines + + if SCons.Util.is_Dict(cppdefines): + return cppdefines + + return {cppdefines: None} class SConsCPPScannerWrapper: """The SCons wrapper around a cpp.py scanner. diff --git a/SCons/Scanner/CTests.py b/SCons/Scanner/CTests.py index e9780d0fc..0f62198d6 100644 --- a/SCons/Scanner/CTests.py +++ b/SCons/Scanner/CTests.py @@ -516,16 +516,14 @@ class CConditionalScannerTestCase4(unittest.TestCase): def runTest(self): """Test that dependency is detected if #include uses a macro.""" - # first try the macro defined in the source file - with self.subTest(): + with self.subTest("macro defined in the source file"): env = DummyEnvironment() s = SCons.Scanner.C.CConditionalScanner() deps = s(env.File('f9a.c'), env, s.path(env)) headers = ['f9.h'] deps_match(self, deps, headers) - # then try the macro defined on the command line - with self.subTest(): + with self.subTest("macro defined on the command line"): env = DummyEnvironment(CPPDEFINES='HEADER=\\"f9.h\\"') #env = DummyEnvironment(CPPDEFINES=['HEADER=\\"f9.h\\"']) s = SCons.Scanner.C.CConditionalScanner() @@ -536,29 +534,42 @@ class CConditionalScannerTestCase4(unittest.TestCase): class dictify_CPPDEFINESTestCase(unittest.TestCase): def runTest(self): - """Make sure single-item tuples convert correctly. + """Make sure CPPDEFINES converts correctly. - This is a regression test: AppendUnique turns sequences into - lists of tuples, and dictify could gack on these. + Various types and combinations of types could fail if not handled + specifically by dictify_CPPDEFINES - this is a regression test. """ - with self.subTest(): - env = DummyEnvironment(CPPDEFINES=[("VALUED_DEFINE", 1), ("UNVALUED_DEFINE", )]) + with self.subTest("tuples in a sequence, including one without value"): + env = DummyEnvironment(CPPDEFINES=[("VALUED", 1), ("UNVALUED",)]) d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'VALUED_DEFINE': 1, 'UNVALUED_DEFINE': None} + expect = {"VALUED": 1, "UNVALUED": None} self.assertEqual(d, expect) - # string-valued define in a sequence - with self.subTest(): - env = DummyEnvironment(CPPDEFINES=["STRING=VALUE"]) + with self.subTest("tuple-valued define by itself"): + env = DummyEnvironment(CPPDEFINES=("STRING", "VALUE")) d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'STRING': 'VALUE'} + expect = {"STRING": "VALUE"} self.assertEqual(d, expect) - # string-valued define by itself - with self.subTest(): + with self.subTest("string-valued define in a sequence"): + env = DummyEnvironment(CPPDEFINES=[("STRING=VALUE")]) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {"STRING": "VALUE"} + self.assertEqual(d, expect) + + with self.subTest("string-valued define by itself"): env = DummyEnvironment(CPPDEFINES="STRING=VALUE") d = SCons.Scanner.C.dictify_CPPDEFINES(env) - expect = {'STRING': 'VALUE'} + expect = {"STRING": "VALUE"} + self.assertEqual(d, expect) + + from collections import deque + with self.subTest("compound CPPDEFINES in internal format"): + env = DummyEnvironment( + CPPDEFINES=deque([("STRING", "VALUE"), ("UNVALUED",)]) + ) + d = SCons.Scanner.C.dictify_CPPDEFINES(env) + expect = {"STRING": "VALUE", "UNVALUED": None} self.assertEqual(d, expect) -- cgit v1.2.1 From 6ce33bdadec1cf558a6d0df27a6a083516d6cf23 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 20 Feb 2023 13:26:05 -0700 Subject: Minor cleanup ValidateOptions doc/code/test Some nearby things in Main.py as well: - docstrings polished a bit, minor linting - move the list of predefined SConstruct file names into a constant defined at the top of the file, so it's a little less hidden, in the unlikely case of future changes. Manpage text and example revised a bit. Signed-off-by: Mats Wichmann --- SCons/Script/Main.py | 96 ++++++++++++++++++++++++-------------- SCons/Script/Main.xml | 127 ++++++++++++++++++++++++++++---------------------- 2 files changed, 133 insertions(+), 90 deletions(-) (limited to 'SCons') diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index d4228facb..e34301eb6 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -31,13 +31,8 @@ some other module. If it's specific to the "scons" script invocation, it goes here. """ -# these define the range of versions SCons supports -minimum_python_version = (3, 6, 0) -deprecated_python_version = (3, 6, 0) - import SCons.compat -import atexit import importlib.util import os import re @@ -46,6 +41,7 @@ import time import traceback import platform import threading +from typing import Optional, List import SCons.CacheDir import SCons.Debug @@ -66,6 +62,20 @@ import SCons.Script.Interactive from SCons import __version__ as SConsVersion +# these define the range of versions SCons supports +minimum_python_version = (3, 6, 0) +deprecated_python_version = (3, 6, 0) + +# ordered list of SConsctruct names to look for if there is no -f flag +KNOWN_SCONSTRUCT_NAMES = [ + 'SConstruct', + 'Sconstruct', + 'sconstruct', + 'SConstruct.py', + 'Sconstruct.py', + 'sconstruct.py', +] + # Global variables first_command_start = None last_command_end = None @@ -284,7 +294,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): node = buildError.node if not SCons.Util.is_List(node): - node = [ node ] + node = [node] nodename = ', '.join(map(str, node)) errfmt = "scons: *** [%s] %s\n" @@ -460,24 +470,29 @@ def python_version_deprecated(version=sys.version_info): class FakeOptionParser: - """ - A do-nothing option parser, used for the initial OptionsParser variable. + """A do-nothing option parser, used for the initial OptionsParser value. During normal SCons operation, the OptionsParser is created right - away by the main() function. Certain tests scripts however, can + away by the main() function. Certain test scripts however, can introspect on different Tool modules, the initialization of which can try to add a new, local option to an otherwise uninitialized OptionsParser object. This allows that introspection to happen without blowing up. - """ + class FakeOptionValues: def __getattr__(self, attr): return None + values = FakeOptionValues() + + # TODO: to quiet checkers, FakeOptionParser should also define + # raise_exception_on_error, preserve_unknown_options, largs and parse_args + def add_local_option(self, *args, **kw): pass + OptionsParser = FakeOptionParser() def AddOption(*args, **kw): @@ -492,22 +507,26 @@ def GetOption(name): def SetOption(name, value): return OptionsParser.values.set_option(name, value) - -def ValidateOptions(throw_exception=False) -> None: +def ValidateOptions(throw_exception: bool = False) -> None: """Validate options passed to SCons on the command line. - If you call this after you set all your command line options with AddOption(), - it will verify that all command line options are valid. - So if you added an option --xyz and you call SCons with --xyy you can cause + Checks that all options given on the command line are known to this + instance of SCons. Call after all of the cli options have been set + up through :func:`AddOption` calls. For example, if you added an + option ``--xyz`` and you call SCons with ``--xyy`` you can cause SCons to issue an error message and exit by calling this function. - :param bool throw_exception: (Optional) Should this function raise an error if there's an invalid option on the command line, or issue a message and exit with error status. + Arguments: + throw_exception: if an invalid option is present on the command line, + raises an exception if this optional parameter evaluates true; + if false (the default), issue a message and exit with error status. - :raises SConsBadOptionError: If throw_exception is True and there are invalid options on command line. + Raises: + SConsBadOptionError: If *throw_exception* is true and there are invalid + options on the command line. .. versionadded:: 4.5.0 """ - OptionsParser.raise_exception_on_error = throw_exception OptionsParser.preserve_unknown_options = False OptionsParser.parse_args(OptionsParser.largs, OptionsParser.values) @@ -641,13 +660,23 @@ def _scons_internal_error(): traceback.print_exc() sys.exit(2) -def _SConstruct_exists(dirname='', repositories=[], filelist=None): - """This function checks that an SConstruct file exists in a directory. - If so, it returns the path of the file. By default, it checks the - current directory. +def _SConstruct_exists( + dirname: str, repositories: List[str], filelist: List[str] +) -> Optional[str]: + """Check that an SConstruct file exists in a directory. + + Arguments: + dirname: the directory to search. If empty, look in cwd. + repositories: a list of repositories to search in addition to the + project directory tree. + filelist: names of SConstruct file(s) to search for. + If empty list, use the built-in list of names. + + Returns: + The path to the located SConstruct file, or ``None``. """ if not filelist: - filelist = ['SConstruct', 'Sconstruct', 'sconstruct', 'SConstruct.py', 'Sconstruct.py', 'sconstruct.py'] + filelist = KNOWN_SCONSTRUCT_NAMES for file in filelist: sfile = os.path.join(dirname, file) if os.path.isfile(sfile): @@ -679,14 +708,14 @@ def _set_debug_values(options): SCons.Warnings.warn(SCons.Warnings.NoObjectCountWarning, msg) if "dtree" in debug_values: options.tree_printers.append(TreePrinter(derived=True)) - options.debug_explain = ("explain" in debug_values) + options.debug_explain = "explain" in debug_values if "findlibs" in debug_values: SCons.Scanner.Prog.print_find_libs = "findlibs" - options.debug_includes = ("includes" in debug_values) - print_memoizer = ("memoizer" in debug_values) + options.debug_includes = "includes" in debug_values + print_memoizer = "memoizer" in debug_values if "memory" in debug_values: memory_stats.enable(sys.stdout) - print_objects = ("objects" in debug_values) + print_objects = "objects" in debug_values if print_objects: SCons.Debug.track_instances = True if "presub" in debug_values: @@ -919,9 +948,9 @@ def _main(parser): target_top = None if options.climb_up: target_top = '.' # directory to prepend to targets - while script_dir and not _SConstruct_exists(script_dir, - options.repository, - options.file): + while script_dir and not _SConstruct_exists( + script_dir, options.repository, options.file + ): script_dir, last_part = os.path.split(script_dir) if last_part: target_top = os.path.join(last_part, target_top) @@ -951,8 +980,7 @@ def _main(parser): if options.file: scripts.extend(options.file) if not scripts: - sfile = _SConstruct_exists(repositories=options.repository, - filelist=options.file) + sfile = _SConstruct_exists("", options.repository, options.file) if sfile: scripts.append(sfile) @@ -1011,8 +1039,8 @@ def _main(parser): # Next, set up the variables that hold command-line arguments, # so the SConscript files that we read and execute have access to them. # TODO: for options defined via AddOption which take space-separated - # option-args, the option-args will collect into targets here, - # because we don't yet know to do any different. + # option-args, the option-args will collect into targets here, + # because we don't yet know to do any different. targets = [] xmit_args = [] for a in parser.largs: diff --git a/SCons/Script/Main.xml b/SCons/Script/Main.xml index 2070c36b0..379d5347e 100644 --- a/SCons/Script/Main.xml +++ b/SCons/Script/Main.xml @@ -749,7 +749,7 @@ Sets &scons; option variable name to value. These options are all also settable via command-line options but the variable name -may differ from the command-line option name - +may differ from the command-line option name - see the table for correspondences. A value set via command-line option will take precedence over one set with &f-SetOption;, which @@ -946,64 +946,79 @@ SetOption('max_drift', 0) - - - ([throw_exception=False]) - - - - - Check that all the options specified on the command line are either defined by SCons itself - or defined by calls to &f-link-AddOption;. - - - This function should only be called after the last &f-link-AddOption; call in your &SConscript; - logic. - - - Be aware that some tools call &f-link-AddOption;, if you are getting error messages for arguments - that they add, you will need to ensure that you load those tools before you call &f-ValidateOptions;. - - - If there are any command line options not defined, calling this function will cause SCons to issue an - error message and then exit with an error exit - status. - If the optional throw_exception is True, &f-ValidateOptions; will raise a - SConsBadOptionError - exception. This would allow the calling - &SConscript; logic can catch that exception and handle invalid options itself. - - - - Example: - - - + + ([throw_exception=False]) + + + + Check that all the options specified on the command line are either + &SCons; built-in options or defined via calls to &f-link-AddOption;. + &SCons; will eventually fail on unknown options anyway, but calling + this function allows the build to "fail fast" before executing + expensive logic later in the build. + + + + This function should only be called after the last &f-AddOption; + call in your &SConscript; logic. + Be aware that some tools call &f-AddOption;, if you are getting + error messages for arguments that they add, you will need to ensure + that those tools are loaded before calling &f-ValidateOptions;. + + + + If there are any unknown command line options, &f-ValidateOptions; + prints an error message and exits with an error exit status. + If the optional throw_exception argument is + True (default is False), + a SConsBadOptionError is raised, + giving an opportunity for the &SConscript; logic to catch that + exception and handle invalid options appropriately. Note that + this exception name needs to be imported (see the example below). + + + + A common build problem is typos (or thinkos) - a user enters an option + that is just a little off the expected value, or perhaps a different + word with a similar meaning. It may be useful to abort the build + before going too far down the wrong path. For example: + + + +$ scons --compilers=mingw # the correct flag is --compiler + + + + Here &SCons; could go off and run a bunch of configure steps with + the default value of --compiler, since the + incorrect command line did not actually supply a value to it, + costing developer time to track down why the configure logic + made the "wrong" choices. This example shows catching this: + + + +from SCons.Script.SConsOptions import SConsBadOptionError + +AddOption( + '--compiler', + dest='compiler', + action='store', + default='gcc', + type='string', +) + +# ... other SConscript logic ... + try: ValidateOptions(throw_exception=True) except SConsBadOptionError as e: - print("Parser is SConsOptionParser:%s" % (isinstance(e.parser, SConsOptionParser))) - print("Message is :%s" % e.opt_str) + print(f"ValidateOptions detects a fail: ", e.opt_str) Exit(3) - - - - This function is useful to force SCons to fail fast before you execute any expensive logic later in your - build logic. - For example if you specify build options via any flags, a simple typo could yield the incorrect build - option throughout your entire build. - - -scons --compilers=mingw (the correct flag is --compiler) - - - Could cause SCons to run configure steps with the incorrect compiler. Costing developer time trying to - track down why the configure logic failed with a compiler which should work. - - - New in version 4.5.0 - - - + + + New in version 4.5.0 + + + -- cgit v1.2.1 From 9594422c63ea550ea941b88ec43e856de764ce7b Mon Sep 17 00:00:00 2001 From: Joseph Brill <48932340+jcbrill@users.noreply.github.com> Date: Fri, 14 Apr 2023 13:30:27 -0400 Subject: MSCommon: minor updates to README.rst [skip ci] Changes: * Fix typographical error (missing word). * Add lines between literal block markers and indented text. * Expand build tools lists in Visual Studio table. --- SCons/Tool/MSCommon/README.rst | 44 +++++++++++++++++++++++++----------------- 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'SCons') diff --git a/SCons/Tool/MSCommon/README.rst b/SCons/Tool/MSCommon/README.rst index 36e58aad4..5ab07ad63 100644 --- a/SCons/Tool/MSCommon/README.rst +++ b/SCons/Tool/MSCommon/README.rst @@ -40,7 +40,7 @@ The following issues are known to exist: * The code to suppress the "No versions of the MSVC compiler were found" warning for the default environment was moved from ``MSCommon/vc.py`` to ``MSCommon/MSVC/SetupEnvDefault.py``. - There very few, if any, existing unit tests. Now that the code is isolated in its own + There are very few, if any, existing unit tests. Now that the code is isolated in its own module with a limited API, unit tests may be easier to implement. @@ -59,6 +59,7 @@ This is a proxy for using the toolset version for selection until that functiona Example usage: :: + for version in [ '14.3', '14.2', @@ -90,6 +91,7 @@ Example usage: Example output fragment :: + Build: _build003 {'MSVC_VERSION': '14.3', 'MSVC_TOOLSET_VERSION': '14.29.30133'} Where: C:\Software\MSVS-2022-143-Com\VC\Tools\MSVC\14.29.30133\bin\HostX64\x64\cl.exe Where: C:\Software\MSVS-2022-143-Com\Common7\Tools\guidgen.exe @@ -138,6 +140,7 @@ for build failures. Refer to the documentation for details. Change the default policy: :: + from SCons.Tool.MSCommon import msvc_set_scripterror_policy msvc_set_scripterror_policy('Warning') @@ -169,6 +172,7 @@ detection of installed msvc instances. Windows command-line sample invocations: :: + @rem 64-Bit Windows "%ProgramFiles(x86)%\Microsoft Visual Studio\Installer\vswhere.exe" -all -sort -prerelease -products * -legacy -format json >MYVSWHEREOUTPUT.json @@ -241,6 +245,7 @@ toolset specification should be omitted entirely. Local installation and summary test results: :: + VS2022\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt 14.31.31103 @@ -249,6 +254,7 @@ Local installation and summary test results: Toolset version summary: :: + 14.31.31103 Environment() 14.31.31103 Environment(MSVC_TOOLSET_VERSION=None) @@ -263,6 +269,7 @@ Toolset version summary: VS2022\\Common7\\Tools\\vsdevcmd\\ext\\vcvars.bat usage fragment: :: + @echo -vcvars_ver=version : Version of VC++ Toolset to select @echo ** [Default] : If -vcvars_ver=version is NOT specified, the toolset specified by @echo [VSInstallDir]\VC\Auxiliary\Build\Microsoft.VCToolsVersion.v143.default.txt will be used. @@ -283,6 +290,7 @@ VS2022\\Common7\\Tools\\vsdevcmd\\ext\\vcvars.bat usage fragment: VS2022 batch file fragment to determine the default toolset version: :: + @REM Add MSVC set "__VCVARS_DEFAULT_CONFIG_FILE=%VCINSTALLDIR%Auxiliary\Build\Microsoft.VCToolsVersion.default.txt" @@ -349,33 +357,33 @@ v60 6.0 12.0 60 Product Versions ---------------- -======== ===== ========= ============ +======== ===== ========= ====================== Product VSVER SDK BuildTools -======== ===== ========= ============ -2022 17.0 10.0, 8.1 v143 .. v140 --------- ----- --------- ------------ -2019 16.0 10.0, 8.1 v142 .. v140 --------- ----- --------- ------------ -2017 15.0 10.0, 8.1 v141 .. v140 --------- ----- --------- ------------ +======== ===== ========= ====================== +2022 17.0 10.0, 8.1 v143, v142, v141, v140 +-------- ----- --------- ---------------------- +2019 16.0 10.0, 8.1 v142, v141, v140 +-------- ----- --------- ---------------------- +2017 15.0 10.0, 8.1 v141, v140 +-------- ----- --------- ---------------------- 2015 14.0 10.0, 8.1 v140 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2013 12.0 v120 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2012 11.0 v110 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2010 10.0 v100 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2008 9.0 v90 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2005 8.0 v80 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2003.NET 7.1 v71 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 2002.NET 7.0 v70 --------- ----- --------- ------------ +-------- ----- --------- ---------------------- 6.0 6.0 v60 -======== ===== ========= ============ +======== ===== ========= ====================== SCons Implementation Notes -- cgit v1.2.1 From 1a103470a13a83590b3fc06e8779494e2b99751d Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Mon, 1 May 2023 11:54:48 -0600 Subject: Add some cheap return and parameter annotations Use: https://github.com/JelleZijlstra/autotyping to add "safe" return annotations. Where a parameter has a default value that is an obvious scalar type (bool, int, str, etc.) add those annotations as well. Also fixed two small bugs that popped up when sanity-checking with mypy. One in FortranCommon, where a return had been previously annotated to be a tuple of Action, which should be ActionBase - Action is the factory function, not the base class. The other was a typo in the error raised in _add_cppdefines - the message was formatted with the value of "define" which should have been "defines". Signed-off-by: Mats Wichmann --- SCons/Action.py | 44 +-- SCons/ActionTests.py | 316 +++++++++--------- SCons/Builder.py | 42 +-- SCons/BuilderTests.py | 144 ++++----- SCons/CacheDir.py | 10 +- SCons/CacheDirTests.py | 44 +-- SCons/Conftest.py | 12 +- SCons/Debug.py | 24 +- SCons/Defaults.py | 16 +- SCons/DefaultsTests.py | 12 +- SCons/Environment.py | 122 +++---- SCons/EnvironmentTests.py | 388 +++++++++++------------ SCons/EnvironmentValues.py | 8 +- SCons/EnvironmentValuesTest.py | 2 +- SCons/Errors.py | 8 +- SCons/ErrorsTests.py | 4 +- SCons/Executor.py | 64 ++-- SCons/ExecutorTests.py | 68 ++-- SCons/Memoize.py | 14 +- SCons/MemoizeTests.py | 8 +- SCons/Node/Alias.py | 16 +- SCons/Node/AliasTests.py | 16 +- SCons/Node/FS.py | 166 +++++----- SCons/Node/FSTests.py | 240 +++++++------- SCons/Node/NodeTests.py | 190 +++++------ SCons/Node/Python.py | 14 +- SCons/Node/PythonTests.py | 26 +- SCons/Node/__init__.py | 122 +++---- SCons/PathList.py | 6 +- SCons/PathListTests.py | 28 +- SCons/Platform/PlatformTests.py | 18 +- SCons/Platform/__init__.py | 8 +- SCons/Platform/aix.py | 2 +- SCons/Platform/cygwin.py | 2 +- SCons/Platform/darwin.py | 2 +- SCons/Platform/hpux.py | 2 +- SCons/Platform/irix.py | 2 +- SCons/Platform/os2.py | 2 +- SCons/Platform/posix.py | 2 +- SCons/Platform/sunos.py | 2 +- SCons/Platform/virtualenv.py | 8 +- SCons/Platform/virtualenvTests.py | 36 +-- SCons/Platform/win32.py | 4 +- SCons/SConf.py | 116 +++---- SCons/SConfTests.py | 82 ++--- SCons/SConsign.py | 38 +-- SCons/SConsignTests.py | 34 +- SCons/Scanner/C.py | 12 +- SCons/Scanner/CTests.py | 44 +-- SCons/Scanner/D.py | 2 +- SCons/Scanner/DTests.py | 28 +- SCons/Scanner/DirTests.py | 8 +- SCons/Scanner/Fortran.py | 4 +- SCons/Scanner/FortranTests.py | 44 +-- SCons/Scanner/IDLTests.py | 36 +-- SCons/Scanner/Java.py | 2 +- SCons/Scanner/JavaTests.py | 36 +-- SCons/Scanner/LaTeX.py | 10 +- SCons/Scanner/LaTeXTests.py | 12 +- SCons/Scanner/ProgTests.py | 32 +- SCons/Scanner/PythonTests.py | 38 +-- SCons/Scanner/RCTests.py | 12 +- SCons/Scanner/ScannerTests.py | 92 +++--- SCons/Scanner/__init__.py | 20 +- SCons/Script/Interactive.py | 24 +- SCons/Script/Main.py | 98 +++--- SCons/Script/SConsOptions.py | 22 +- SCons/Script/SConscript.py | 22 +- SCons/Script/__init__.py | 16 +- SCons/Subst.py | 62 ++-- SCons/SubstTests.py | 110 +++---- SCons/Taskmaster/Job.py | 42 +-- SCons/Taskmaster/JobTests.py | 76 ++--- SCons/Taskmaster/TaskmasterTests.py | 90 +++--- SCons/Taskmaster/__init__.py | 46 +-- SCons/Tool/386asm.py | 2 +- SCons/Tool/DCommon.py | 4 +- SCons/Tool/FortranCommon.py | 8 +- SCons/Tool/FortranCommonTests.py | 10 +- SCons/Tool/GettextCommon.py | 14 +- SCons/Tool/JavaCommon.py | 28 +- SCons/Tool/JavaCommonTests.py | 40 +-- SCons/Tool/MSCommon/MSVC/ConfigTests.py | 10 +- SCons/Tool/MSCommon/MSVC/Dispatcher.py | 8 +- SCons/Tool/MSCommon/MSVC/DispatcherTests.py | 24 +- SCons/Tool/MSCommon/MSVC/PolicyTests.py | 30 +- SCons/Tool/MSCommon/MSVC/Registry.py | 8 +- SCons/Tool/MSCommon/MSVC/RegistryTests.py | 14 +- SCons/Tool/MSCommon/MSVC/ScriptArguments.py | 22 +- SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py | 26 +- SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py | 10 +- SCons/Tool/MSCommon/MSVC/UtilTests.py | 20 +- SCons/Tool/MSCommon/MSVC/WinSDK.py | 10 +- SCons/Tool/MSCommon/MSVC/WinSDKTests.py | 24 +- SCons/Tool/MSCommon/MSVC/__init__.py | 4 +- SCons/Tool/MSCommon/arch.py | 2 +- SCons/Tool/MSCommon/common.py | 8 +- SCons/Tool/MSCommon/sdk.py | 8 +- SCons/Tool/MSCommon/vc.py | 14 +- SCons/Tool/MSCommon/vcTests.py | 52 +-- SCons/Tool/MSCommon/vs.py | 10 +- SCons/Tool/PharLapCommon.py | 2 +- SCons/Tool/ToolTests.py | 14 +- SCons/Tool/__init__.py | 22 +- SCons/Tool/aixcc.py | 2 +- SCons/Tool/aixcxx.py | 2 +- SCons/Tool/aixf77.py | 2 +- SCons/Tool/aixlink.py | 2 +- SCons/Tool/applelink.py | 8 +- SCons/Tool/ar.py | 2 +- SCons/Tool/asm.py | 2 +- SCons/Tool/bcc32.py | 2 +- SCons/Tool/cc.py | 4 +- SCons/Tool/clang.py | 2 +- SCons/Tool/clangxx.py | 2 +- SCons/Tool/compilation_db.py | 12 +- SCons/Tool/cvf.py | 2 +- SCons/Tool/cxx.py | 4 +- SCons/Tool/cyglink.py | 6 +- SCons/Tool/default.py | 4 +- SCons/Tool/dmd.py | 2 +- SCons/Tool/docbook/__init__.py | 18 +- SCons/Tool/dvi.py | 4 +- SCons/Tool/dvipdf.py | 4 +- SCons/Tool/dvips.py | 2 +- SCons/Tool/f03.py | 2 +- SCons/Tool/f08.py | 2 +- SCons/Tool/f77.py | 2 +- SCons/Tool/f90.py | 2 +- SCons/Tool/f95.py | 2 +- SCons/Tool/filesystem.py | 6 +- SCons/Tool/fortran.py | 2 +- SCons/Tool/g77.py | 2 +- SCons/Tool/gas.py | 2 +- SCons/Tool/gcc.py | 2 +- SCons/Tool/gdc.py | 2 +- SCons/Tool/gettext_tool.py | 2 +- SCons/Tool/gfortran.py | 2 +- SCons/Tool/gnulink.py | 2 +- SCons/Tool/gs.py | 2 +- SCons/Tool/gxx.py | 2 +- SCons/Tool/hpcc.py | 2 +- SCons/Tool/hpcxx.py | 2 +- SCons/Tool/hplink.py | 2 +- SCons/Tool/icc.py | 2 +- SCons/Tool/ifl.py | 2 +- SCons/Tool/ifort.py | 2 +- SCons/Tool/ilink.py | 2 +- SCons/Tool/ilink32.py | 2 +- SCons/Tool/install.py | 12 +- SCons/Tool/intelc.py | 2 +- SCons/Tool/ipkg.py | 2 +- SCons/Tool/jar.py | 2 +- SCons/Tool/javac.py | 8 +- SCons/Tool/javacTests.py | 28 +- SCons/Tool/javah.py | 4 +- SCons/Tool/latex.py | 2 +- SCons/Tool/ldc.py | 2 +- SCons/Tool/lex.py | 2 +- SCons/Tool/link.py | 2 +- SCons/Tool/linkCommon/LoadableModule.py | 4 +- SCons/Tool/linkCommon/SharedLibrary.py | 4 +- SCons/Tool/linkCommon/__init__.py | 8 +- SCons/Tool/linkCommon/linkCommmonTests.py | 4 +- SCons/Tool/linkloc.py | 4 +- SCons/Tool/m4.py | 2 +- SCons/Tool/masm.py | 2 +- SCons/Tool/midl.py | 2 +- SCons/Tool/mingw.py | 2 +- SCons/Tool/msgfmt.py | 2 +- SCons/Tool/msginit.py | 2 +- SCons/Tool/msgmerge.py | 2 +- SCons/Tool/mslib.py | 2 +- SCons/Tool/mslink.py | 2 +- SCons/Tool/mssdk.py | 2 +- SCons/Tool/msvc.py | 4 +- SCons/Tool/msvs.py | 70 ++-- SCons/Tool/msvsTests.py | 36 +-- SCons/Tool/mwcc.py | 8 +- SCons/Tool/mwld.py | 2 +- SCons/Tool/nasm.py | 2 +- SCons/Tool/ninja/Methods.py | 12 +- SCons/Tool/ninja/NinjaState.py | 10 +- SCons/Tool/ninja/Overrides.py | 8 +- SCons/Tool/ninja/Utils.py | 12 +- SCons/Tool/ninja/__init__.py | 8 +- SCons/Tool/ninja/ninja_daemon_build.py | 2 +- SCons/Tool/ninja/ninja_run_daemon.py | 2 +- SCons/Tool/ninja/ninja_scons_daemon.py | 18 +- SCons/Tool/packaging/__init__.py | 12 +- SCons/Tool/packaging/ipk.py | 2 +- SCons/Tool/packaging/msi.py | 16 +- SCons/Tool/packaging/rpm.py | 2 +- SCons/Tool/pdf.py | 6 +- SCons/Tool/pdflatex.py | 2 +- SCons/Tool/pdftex.py | 2 +- SCons/Tool/python.py | 4 +- SCons/Tool/qt.py | 2 +- SCons/Tool/qt3.py | 4 +- SCons/Tool/rmic.py | 4 +- SCons/Tool/rpcgen.py | 2 +- SCons/Tool/rpm.py | 4 +- SCons/Tool/rpmutils.py | 8 +- SCons/Tool/sgiar.py | 2 +- SCons/Tool/sgicc.py | 2 +- SCons/Tool/sgicxx.py | 2 +- SCons/Tool/sgilink.py | 2 +- SCons/Tool/sunar.py | 2 +- SCons/Tool/suncc.py | 2 +- SCons/Tool/suncxx.py | 2 +- SCons/Tool/sunf77.py | 2 +- SCons/Tool/sunf90.py | 2 +- SCons/Tool/sunf95.py | 2 +- SCons/Tool/sunlink.py | 2 +- SCons/Tool/swig.py | 6 +- SCons/Tool/tar.py | 2 +- SCons/Tool/tex.py | 12 +- SCons/Tool/textfile.py | 8 +- SCons/Tool/tlib.py | 2 +- SCons/Tool/wix.py | 2 +- SCons/Tool/wixTests.py | 2 +- SCons/Tool/xgettext.py | 6 +- SCons/Tool/yacc.py | 2 +- SCons/Tool/zip.py | 6 +- SCons/Util/__init__.py | 56 ++-- SCons/Util/envs.py | 10 +- SCons/Util/hashes.py | 6 +- SCons/Util/types.py | 12 +- SCons/UtilTests.py | 154 ++++----- SCons/Utilities/ConfigureCache.py | 2 +- SCons/Utilities/sconsign.py | 16 +- SCons/Variables/BoolVariableTests.py | 6 +- SCons/Variables/EnumVariable.py | 2 +- SCons/Variables/EnumVariableTests.py | 10 +- SCons/Variables/ListVariable.py | 4 +- SCons/Variables/ListVariableTests.py | 6 +- SCons/Variables/PackageVariableTests.py | 6 +- SCons/Variables/PathVariableTests.py | 4 +- SCons/Variables/VariablesTests.py | 44 +-- SCons/Variables/__init__.py | 4 +- SCons/Warnings.py | 8 +- SCons/WarningsTests.py | 8 +- SCons/compat/__init__.py | 2 +- SCons/cpp.py | 44 +-- SCons/cppTests.py | 46 +-- SCons/dblite.py | 16 +- SCons/exitfuncs.py | 4 +- 247 files changed, 2539 insertions(+), 2537 deletions(-) (limited to 'SCons') diff --git a/SCons/Action.py b/SCons/Action.py index 1f5e5483f..3f1a24ecc 100644 --- a/SCons/Action.py +++ b/SCons/Action.py @@ -597,8 +597,8 @@ class _ActionAction(ActionBase): """Base class for actions that create output objects.""" def __init__(self, cmdstr=_null, strfunction=_null, varlist=(), presub=_null, chdir=None, exitstatfunc=None, - batch_key=None, targets='$TARGETS', - **kw): + batch_key=None, targets: str='$TARGETS', + **kw) -> None: self.cmdstr = cmdstr if strfunction is not _null: if strfunction is None: @@ -625,7 +625,7 @@ class _ActionAction(ActionBase): batch_key = default_batch_key SCons.Util.AddMethod(self, batch_key, 'batch_key') - def print_cmd_line(self, s, target, source, env): + def print_cmd_line(self, s, target, source, env) -> None: """ In python 3, and in some of our tests, sys.stdout is a String io object, and it takes unicode strings only @@ -787,7 +787,7 @@ def _resolve_shell_env(env, target, source): return ENV -def _subproc(scons_env, cmd, error='ignore', **kw): +def _subproc(scons_env, cmd, error: str='ignore', **kw): """Wrapper for subprocess which pulls from construction env. Use for calls to subprocess which need to interpolate values from @@ -814,7 +814,7 @@ def _subproc(scons_env, cmd, error='ignore', **kw): if error == 'raise': raise # return a dummy Popen instance that only returns error class dummyPopen: - def __init__(self, e): + def __init__(self, e) -> None: self.exception = e # Add the following two to enable using the return value as a context manager # for example @@ -824,7 +824,7 @@ def _subproc(scons_env, cmd, error='ignore', **kw): def __enter__(self): return self - def __exit__(self, *args): + def __exit__(self, *args) -> None: pass def communicate(self, input=None): @@ -835,8 +835,8 @@ def _subproc(scons_env, cmd, error='ignore', **kw): stdin = None class f: - def read(self): return '' - def readline(self): return '' + def read(self) -> str: return '' + def readline(self) -> str: return '' def __iter__(self): return iter(()) stdout = stderr = f() pobj = dummyPopen(e) @@ -851,7 +851,7 @@ def _subproc(scons_env, cmd, error='ignore', **kw): class CommandAction(_ActionAction): """Class for command-execution actions.""" - def __init__(self, cmd, **kw): + def __init__(self, cmd, **kw) -> None: # Cmd can actually be a list or a single item; if it's a # single item it should be the command string to execute; if a # list then it should be the words of the command string to @@ -870,12 +870,12 @@ class CommandAction(_ActionAction): "a single command") self.cmd_list = cmd - def __str__(self): + def __str__(self) -> str: if is_List(self.cmd_list): return ' '.join(map(str, self.cmd_list)) return str(self.cmd_list) - def process(self, target, source, env, executor=None, overrides=False): + def process(self, target, source, env, executor=None, overrides: bool=False): if executor: result = env.subst_list(self.cmd_list, 0, executor=executor, overrides=overrides) else: @@ -896,7 +896,7 @@ class CommandAction(_ActionAction): pass return result, ignore, silent - def strfunction(self, target, source, env, executor=None, overrides=False): + def strfunction(self, target, source, env, executor=None, overrides: bool=False): if self.cmdstr is None: return None if self.cmdstr is not _null: @@ -1099,7 +1099,7 @@ class CommandAction(_ActionAction): class CommandGeneratorAction(ActionBase): """Class for command-generator actions.""" - def __init__(self, generator, kw): + def __init__(self, generator, kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.CommandGeneratorAction') self.generator = generator self.gen_kw = kw @@ -1124,7 +1124,7 @@ class CommandGeneratorAction(ActionBase): raise SCons.Errors.UserError("Object returned from command generator: %s cannot be used to create an Action." % repr(ret)) return gen_cmd - def __str__(self): + def __str__(self) -> str: try: env = self.presub_env except AttributeError: @@ -1191,7 +1191,7 @@ class LazyAction(CommandGeneratorAction, CommandAction): an action based on what's in the construction variable. """ - def __init__(self, var, kw): + def __init__(self, var, kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.LazyAction') CommandAction.__init__(self, '${'+var+'}', **kw) self.var = SCons.Util.to_String(var) @@ -1232,7 +1232,7 @@ class LazyAction(CommandGeneratorAction, CommandAction): class FunctionAction(_ActionAction): """Class for Python function actions.""" - def __init__(self, execfunction, kw): + def __init__(self, execfunction, kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.FunctionAction') self.execfunction = execfunction @@ -1293,7 +1293,7 @@ class FunctionAction(_ActionAction): sstr = array(source) return "%s(%s, %s)" % (name, tstr, sstr) - def __str__(self): + def __str__(self) -> str: name = self.function_name() if name == 'ActionCaller': return str(self.execfunction) @@ -1354,7 +1354,7 @@ class FunctionAction(_ActionAction): class ListAction(ActionBase): """Class for lists of other actions.""" - def __init__(self, actionlist): + def __init__(self, actionlist) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Action.ListAction') def list_of_actions(x): if isinstance(x, ActionBase): @@ -1369,7 +1369,7 @@ class ListAction(ActionBase): def genstring(self, target, source, env): return '\n'.join([a.genstring(target, source, env) for a in self.list]) - def __str__(self): + def __str__(self) -> str: return '\n'.join(map(str, self.list)) def presub_lines(self, env): @@ -1418,7 +1418,7 @@ class ActionCaller: but what it's really doing is hanging on to the arguments until we have a target, source and env to use for the expansion. """ - def __init__(self, parent, args, kw): + def __init__(self, parent, args, kw) -> None: self.parent = parent self.args = args self.kw = kw @@ -1476,7 +1476,7 @@ class ActionCaller: kw = self.subst_kw(target, source, env) return self.parent.strfunc(*args, **kw) - def __str__(self): + def __str__(self) -> str: return self.parent.strfunc(*self.args, **self.kw) @@ -1489,7 +1489,7 @@ class ActionFactory: called with and give them to the ActionCaller object we create, so it can hang onto them until it needs them. """ - def __init__(self, actfunc, strfunc, convert=lambda x: x): + def __init__(self, actfunc, strfunc, convert=lambda x: x) -> None: self.actfunc = actfunc self.strfunc = strfunc self.convert = convert diff --git a/SCons/ActionTests.py b/SCons/ActionTests.py index 88bb36fc2..2e6204e7a 100644 --- a/SCons/ActionTests.py +++ b/SCons/ActionTests.py @@ -27,12 +27,12 @@ # contents, so try to minimize changes by defining them here, before we # even import anything. -def GlobalFunc(): +def GlobalFunc() -> None: pass class GlobalActFunc: - def __call__(self): + def __call__(self) -> None: pass @@ -105,7 +105,7 @@ sys.stdout = io.StringIO() class CmdStringHolder: - def __init__(self, cmd, literal=None): + def __init__(self, cmd, literal=None) -> None: self.data = str(cmd) self.literal = literal @@ -132,7 +132,7 @@ class CmdStringHolder: class Environment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self.d = {} self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] @@ -142,23 +142,23 @@ class Environment: self.d[k] = v # Just use the underlying scons_subst*() utility methods. - def subst(self, strSubst, raw=0, target=[], source=[], conv=None, overrides=False): + def subst(self, strSubst, raw: int=0, target=[], source=[], conv=None, overrides: bool=False): return SCons.Subst.scons_subst(strSubst, self, raw, target, source, self.d, conv=conv, overrides=overrides) subst_target_source = subst - def subst_list(self, strSubst, raw=0, target=[], source=[], conv=None, overrides=False): + def subst_list(self, strSubst, raw: int=0, target=[], source=[], conv=None, overrides: bool=False): return SCons.Subst.scons_subst_list(strSubst, self, raw, target, source, self.d, conv=conv, overrides=overrides) def __getitem__(self, item): return self.d[item] - def __setitem__(self, item, value): + def __setitem__(self, item, value) -> None: self.d[item] = value - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.d def get(self, key, value=None): @@ -188,13 +188,13 @@ class Environment: class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name def str_for_display(self): return '"' + self.name + '"' - def __str__(self): + def __str__(self) -> str: return self.name def rfile(self): @@ -213,7 +213,7 @@ _python_ = test.escape(python) _null = SCons.Action._null -def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw): +def test_varlist(pos_call, str_call, cmd, cmdstrfunc, **kw) -> None: def call_action(a, pos_call=pos_call, str_call=str_call, kw=kw): a = SCons.Action.Action(*a, **kw) # returned object must provide these entry points @@ -260,7 +260,7 @@ def test_positional_args(pos_callback, cmd, **kw): if not isinstance(act, SCons.Action._ActionAction): # only valid cmdstrfunc is None - def none(a): + def none(a) -> None: pass test_varlist(pos_callback, none, cmd, None, **kw) @@ -273,22 +273,22 @@ def test_positional_args(pos_callback, cmd, **kw): assert act.exitstatfunc is SCons.Action.default_exitstatfunc, \ act.exitstatfunc - def cmdstr(a): + def cmdstr(a) -> None: assert hasattr(a, 'strfunction') assert a.cmdstr == 'cmdstr', a.cmdstr test_varlist(pos_callback, cmdstr, cmd, 'cmdstr', **kw) - def fun(): + def fun() -> None: pass - def strfun(a, fun=fun): + def strfun(a, fun=fun) -> None: assert a.strfunction is fun, a.strfunction assert a.cmdstr == _null, a.cmdstr test_varlist(pos_callback, strfun, cmd, fun, **kw) - def none(a): + def none(a) -> None: assert hasattr(a, 'strfunction') assert a.cmdstr is None, a.cmdstr @@ -310,13 +310,13 @@ def test_positional_args(pos_callback, cmd, **kw): class ActionTestCase(unittest.TestCase): """Test the Action() factory function""" - def test_FunctionAction(self): + def test_FunctionAction(self) -> None: """Test the Action() factory's creation of FunctionAction objects.""" - def foo(): + def foo() -> None: pass - def func_action(a, foo=foo): + def func_action(a, foo=foo) -> None: assert isinstance(a, SCons.Action.FunctionAction), a assert a.execfunction == foo, a.execfunction @@ -324,10 +324,10 @@ class ActionTestCase(unittest.TestCase): # a singleton list returns the contained action test_positional_args(func_action, [foo]) - def test_CommandAction(self): + def test_CommandAction(self) -> None: """Test the Action() factory's creation of CommandAction objects.""" - def cmd_action(a): + def cmd_action(a) -> None: assert isinstance(a, SCons.Action.CommandAction), a assert a.cmd_list == "string", a.cmd_list @@ -335,13 +335,13 @@ class ActionTestCase(unittest.TestCase): # a singleton list returns the contained action test_positional_args(cmd_action, ["string"]) - def line_action(a): + def line_action(a) -> None: assert isinstance(a, SCons.Action.CommandAction), a assert a.cmd_list == ["explicit", "command", "line"], a.cmd_list test_positional_args(line_action, [["explicit", "command", "line"]]) - def test_ListAction(self): + def test_ListAction(self) -> None: """Test the Action() factory's creation of ListAction objects.""" a1 = SCons.Action.Action(["x", "y", "z", ["a", "b", "c"]]) @@ -366,7 +366,7 @@ class ActionTestCase(unittest.TestCase): assert isinstance(a2.list[2], SCons.Action.CommandAction), a2.list[2] assert a2.list[2].cmd_list == "z", a2.list[2].cmd_list - def foo(): + def foo() -> None: pass a3 = SCons.Action.Action(["x", foo, "z"]) @@ -399,21 +399,21 @@ class ActionTestCase(unittest.TestCase): assert a5.list[1].cmd_list == "y", a5.list[1].cmd_list assert a5.list[1].strfunction == foo, a5.list[1].strfunction - def test_CommandGeneratorAction(self): + def test_CommandGeneratorAction(self) -> None: """Test the Action factory's creation of CommandGeneratorAction objects.""" - def foo(): pass + def foo() -> None: pass - def gen_action(a, foo=foo): + def gen_action(a, foo=foo) -> None: assert isinstance(a, SCons.Action.CommandGeneratorAction), a assert a.generator is foo, a.generator test_positional_args(gen_action, foo, generator=1) - def test_LazyCmdGeneratorAction(self): + def test_LazyCmdGeneratorAction(self) -> None: """Test the Action factory's creation of lazy CommandGeneratorAction objects.""" - def lazy_action(a): + def lazy_action(a) -> None: assert isinstance(a, SCons.Action.LazyAction), a assert a.var == "FOO", a.var assert a.cmd_list == "${FOO}", a.cmd_list @@ -421,7 +421,7 @@ class ActionTestCase(unittest.TestCase): test_positional_args(lazy_action, "$FOO") test_positional_args(lazy_action, "${FOO}") - def test_no_action(self): + def test_no_action(self) -> None: """Test when the Action() factory can't create an action object.""" try: @@ -431,7 +431,7 @@ class ActionTestCase(unittest.TestCase): else: assert 0, "Should have thrown a TypeError creating Action from an int." - def test_reentrance(self): + def test_reentrance(self) -> None: """Test the Action factory when the action is already an Action object.""" a1 = SCons.Action.Action("foo") @@ -441,16 +441,16 @@ class ActionTestCase(unittest.TestCase): class _ActionActionTestCase(unittest.TestCase): - def test__init__(self): + def test__init__(self) -> None: """Test creation of _ActionAction objects.""" - def func1(): + def func1() -> None: pass - def func2(): + def func2() -> None: pass - def func3(): + def func3() -> None: pass a = SCons.Action._ActionAction() @@ -517,7 +517,7 @@ class _ActionActionTestCase(unittest.TestCase): def test_dup_keywords(self): """Test handling of both cmdstr and strfunction arguments.""" - def func(): + def func() -> None: pass try: @@ -529,7 +529,7 @@ class _ActionActionTestCase(unittest.TestCase): else: raise Exception("did not catch expected UserError") - def test___cmp__(self): + def test___cmp__(self) -> None: """Test Action comparison.""" a1 = SCons.Action.Action("x") @@ -539,13 +539,13 @@ class _ActionActionTestCase(unittest.TestCase): assert a1 != a3 assert a2 != a3 - def test_print_cmd_lines(self): + def test_print_cmd_lines(self) -> None: """Test the print_cmd_lines() method.""" save_stdout = sys.stdout try: - def execfunc(target, source, env): + def execfunc(target, source, env) -> None: pass a = SCons.Action.Action(execfunc) @@ -559,7 +559,7 @@ class _ActionActionTestCase(unittest.TestCase): finally: sys.stdout = save_stdout - def test___call__(self): + def test___call__(self) -> None: """Test calling an Action.""" save_stdout = sys.stdout @@ -576,19 +576,19 @@ class _ActionActionTestCase(unittest.TestCase): try: env = Environment() - def execfunc(target, source, env): + def execfunc(target, source, env) -> int: assert isinstance(target, list), type(target) assert isinstance(source, list), type(source) return 7 a = SCons.Action.Action(execfunc) - def firstfunc(target, source, env): + def firstfunc(target, source, env) -> int: assert isinstance(target, list), type(target) assert isinstance(source, list), type(source) return 0 - def lastfunc(target, source, env): + def lastfunc(target, source, env) -> int: assert isinstance(target, list), type(target) assert isinstance(source, list), type(source) return 9 @@ -733,7 +733,7 @@ class _ActionActionTestCase(unittest.TestCase): result = [] - def my_print_cmd_line(s, target, source, env, result=result): + def my_print_cmd_line(s, target, source, env, result=result) -> None: result.append(s) env['PRINT_CMD_LINE_FUNC'] = my_print_cmd_line @@ -747,7 +747,7 @@ class _ActionActionTestCase(unittest.TestCase): SCons.Action.print_actions_presub = save_print_actions_presub SCons.Action.execute_actions = save_execute_actions - def test_presub_lines(self): + def test_presub_lines(self) -> None: """Test the presub_lines() method.""" env = Environment() @@ -759,7 +759,7 @@ class _ActionActionTestCase(unittest.TestCase): s = a.presub_lines(env) assert s == ['y', 'z'], s - def func(): + def func() -> None: pass a = SCons.Action.Action(func) @@ -781,7 +781,7 @@ class _ActionActionTestCase(unittest.TestCase): s = a.presub_lines(Environment(ACT='expanded action')) assert s == ['expanded action'], s - def test_add(self): + def test_add(self) -> None: """Test adding Actions to stuff.""" # Adding actions to other Actions or to stuff that can @@ -869,7 +869,7 @@ class _ActionActionTestCase(unittest.TestCase): class CommandActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a command Action.""" a = SCons.Action.CommandAction(["xyzzy"]) @@ -880,7 +880,7 @@ class CommandActionTestCase(unittest.TestCase): assert a.cmd_list == ["abra"], a.cmd_list assert a.cmdstr == "cadabra", a.cmdstr - def test___str__(self): + def test___str__(self) -> None: """Test fetching the pre-substitution string for command Actions.""" env = Environment() @@ -894,7 +894,7 @@ class CommandActionTestCase(unittest.TestCase): s = str(act) assert s == "xyzzy $TARGET $SOURCE $TARGETS $SOURCES", s - def test_genstring(self): + def test_genstring(self) -> None: """Test the genstring() method for command Actions.""" env = Environment() @@ -931,7 +931,7 @@ class CommandActionTestCase(unittest.TestCase): s = act.genstring([t1, t2], [s1, s2], env) assert s == expect, s - def test_strfunction(self): + def test_strfunction(self) -> None: """Test fetching the string representation of command Actions.""" env = Environment() @@ -993,7 +993,7 @@ class CommandActionTestCase(unittest.TestCase): s = act.strfunction([t1, t2], [s1, s2], env) assert s == 'cmdstr\tt1 t2\ns1 s2 ', s - def sf(target, source, env): + def sf(target, source, env) -> str: return "sf was called" act = SCons.Action.CommandAction('foo', strfunction=sf) @@ -1001,35 +1001,35 @@ class CommandActionTestCase(unittest.TestCase): assert s == "sf was called", s class actclass1: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: pass - def __call__(self): + def __call__(self) -> int: return 1 class actclass2: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: self.strfunction = 5 - def __call__(self): + def __call__(self) -> int: return 2 class actclass3: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: pass - def __call__(self): + def __call__(self) -> int: return 3 - def strfunction(self, targets, sources, env): + def strfunction(self, targets, sources, env) -> str: return 'actclass3 on %s to get %s' % (str(sources[0]), str(targets[0])) class actclass4: - def __init__(self, targets, sources, env): + def __init__(self, targets, sources, env) -> None: pass - def __call__(self): + def __call__(self) -> int: return 4 strfunction = None @@ -1082,7 +1082,7 @@ class CommandActionTestCase(unittest.TestCase): s = act.strfunction([], [], env) assert s == "foo bar", s - def test_execute(self): + def test_execute(self) -> None: """Test execution of command Actions.""" try: @@ -1156,10 +1156,10 @@ class CommandActionTestCase(unittest.TestCase): assert c == "act.py: 'out5' 'XYZZY'\nact.py: 'xyzzy5'\n", c class Obj: - def __init__(self, str): + def __init__(self, str) -> None: self._str = str - def __str__(self): + def __str__(self) -> str: return self._str def rfile(self): @@ -1238,16 +1238,16 @@ class CommandActionTestCase(unittest.TestCase): r = act([], [], env) assert r == 0, r - def test_set_handler(self): + def test_set_handler(self) -> None: """Test setting the command handler...""" class Test: - def __init__(self): + def __init__(self) -> None: self.executed = 0 t = Test() - def func(sh, escape, cmd, args, env, test=t): + def func(sh, escape, cmd, args, env, test=t) -> int: test.executed = args test.shell = sh return 0 @@ -1256,16 +1256,16 @@ class CommandActionTestCase(unittest.TestCase): return '**' + cmd + '**' class LiteralStr: - def __init__(self, x): + def __init__(self, x) -> None: self.data = x - def __str__(self): + def __str__(self) -> str: return self.data def escape(self, escape_func): return escape_func(self.data) - def is_literal(self): + def is_literal(self) -> int: return 1 a = SCons.Action.CommandAction(["xyzzy"]) @@ -1289,10 +1289,10 @@ class CommandActionTestCase(unittest.TestCase): a([], [], e) assert t.executed == ['**xyzzy**'], t.executed - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a command Action.""" - def CmdGen(target, source, env, for_signature): + def CmdGen(target, source, env, for_signature) -> str: assert for_signature return "%s %s" % \ (env["foo"], env["bar"]) @@ -1308,7 +1308,7 @@ class CommandActionTestCase(unittest.TestCase): # Make sure that CommandActions use an Environment's # subst_target_source() method for substitution. class SpecialEnvironment(Environment): - def subst_target_source(self, strSubst, raw=0, target=[], source=[]): + def subst_target_source(self, strSubst, raw: int=0, target=[], source=[]): return 'subst_target_source: ' + strSubst c = a.get_contents(target=DummyNode('ttt'), source=DummyNode('sss'), @@ -1361,7 +1361,7 @@ class CommandActionTestCase(unittest.TestCase): c = a.get_contents(target=t, source=s, env=env) assert c == b"s4 s5", c - def test_get_implicit_deps(self): + def test_get_implicit_deps(self) -> None: """Test getting the implicit dependencies of a command Action.""" class SpecialEnvironment(Environment): @@ -1407,19 +1407,19 @@ class CommandGeneratorActionTestCase(unittest.TestCase): return SCons.Action.CommandGeneratorAction(act, kw) - def test___init__(self): + def test___init__(self) -> None: """Test creation of a command generator Action.""" - def f(target, source, env): + def f(target, source, env) -> None: pass a = self.factory(f) assert a.generator == f - def test___str__(self): + def test___str__(self) -> None: """Test the pre-substitution strings for command generator Actions.""" - def f(target, source, env, for_signature, self=self): + def f(target, source, env, for_signature, self=self) -> str: # See if "env" is really a construction environment (or # looks like one) by accessing the FindIxes attribute. # (The Tool/mingw.py module has a generator that uses this, @@ -1433,10 +1433,10 @@ class CommandGeneratorActionTestCase(unittest.TestCase): s = str(a) assert s == 'FOO', s - def test_genstring(self): + def test_genstring(self) -> None: """Test the command generator Action genstring() method.""" - def f(target, source, env, for_signature, self=self): + def f(target, source, env, for_signature, self=self) -> str: dummy = env['dummy'] self.dummy = dummy return "$FOO $TARGET $SOURCE $TARGETS $SOURCES" @@ -1447,17 +1447,17 @@ class CommandGeneratorActionTestCase(unittest.TestCase): assert self.dummy == 1, self.dummy assert s == "$FOO $TARGET $SOURCE $TARGETS $SOURCES", s - def test_execute(self): + def test_execute(self) -> None: """Test executing a command generator Action.""" - def f(target, source, env, for_signature, self=self): + def f(target, source, env, for_signature, self=self) -> str: dummy = env['dummy'] self.dummy = dummy s = env.subst("$FOO") assert s == 'foo baz\nbar ack', s return "$FOO" - def func_action(target, source, env, self=self): + def func_action(target, source, env, self=self) -> None: dummy = env['dummy'] s = env.subst('$foo') assert s == 'bar', s @@ -1466,7 +1466,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): def f2(target, source, env, for_signature, f=func_action): return f - def ch(sh, escape, cmd, args, env, self=self): + def ch(sh, escape, cmd, args, env, self=self) -> None: self.cmd.append(cmd) self.args.append(args) @@ -1489,7 +1489,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): del self.dummy class DummyFile: - def __init__(self, t): + def __init__(self, t) -> None: self.t = t def rfile(self): @@ -1499,14 +1499,14 @@ class CommandGeneratorActionTestCase(unittest.TestCase): def get_subst_proxy(self): return self - def f3(target, source, env, for_signature): + def f3(target, source, env, for_signature) -> str: return '' c = self.factory(f3) c(target=[], source=DummyFile(self), env=Environment()) assert self.rfile_called - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a command generator Action.""" def f(target, source, env, for_signature): @@ -1516,7 +1516,7 @@ class CommandGeneratorActionTestCase(unittest.TestCase): return [["guux", foo, "$(", "$ignore", "$)", bar, '${test("$( foo $bar $)")}']] - def test(mystr): + def test(mystr) -> str: assert mystr == "$( foo $bar $)", mystr return "test" @@ -1526,10 +1526,10 @@ class CommandGeneratorActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c == b"guux FFF BBB test", c - def test_get_contents_of_function_action(self): + def test_get_contents_of_function_action(self) -> None: """Test contents of a CommandGeneratorAction-generated FunctionAction.""" - def LocalFunc(): + def LocalFunc() -> None: pass # Since the python bytecode has per version differences, we need different expected results per version @@ -1586,19 +1586,19 @@ class CommandGeneratorActionTestCase(unittest.TestCase): class FunctionActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a function Action.""" - def func1(): + def func1() -> None: pass - def func2(): + def func2() -> None: pass - def func3(): + def func3() -> None: pass - def func4(): + def func4() -> None: pass a = SCons.Action.FunctionAction(func1, {}) @@ -1609,10 +1609,10 @@ class FunctionActionTestCase(unittest.TestCase): assert a.execfunction == func2, a.execfunction assert a.strfunction == func3, a.strfunction - def test___str__(self): + def test___str__(self) -> None: """Test the __str__() method for function Actions.""" - def func1(): + def func1() -> None: pass a = SCons.Action.FunctionAction(func1, {}) @@ -1620,19 +1620,19 @@ class FunctionActionTestCase(unittest.TestCase): assert s == "func1(target, source, env)", s class class1: - def __call__(self): + def __call__(self) -> None: pass a = SCons.Action.FunctionAction(class1(), {}) s = str(a) assert s == "class1(target, source, env)", s - def test_execute(self): + def test_execute(self) -> None: """Test executing a function Action.""" self.inc = 0 - def f(target, source, env): + def f(target, source, env) -> int: s = env['s'] s.inc = s.inc + 1 s.target = target @@ -1650,7 +1650,7 @@ class FunctionActionTestCase(unittest.TestCase): global count count = 0 - def function1(target, source, env): + def function1(target, source, env) -> int: global count count = count + 1 for t in target: @@ -1669,7 +1669,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c == "function1\n", c class class1a: - def __init__(self, target, source, env): + def __init__(self, target, source, env) -> None: with open(env['out'], 'w') as f: f.write("class1a\n") @@ -1680,7 +1680,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c == "class1a\n", c class class1b: - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> int: with open(env['out'], 'w') as f: f.write("class1b\n") return 2 @@ -1691,7 +1691,7 @@ class FunctionActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "class1b\n", c - def build_it(target, source, env, executor=None, self=self): + def build_it(target, source, env, executor=None, self=self) -> int: self.build_it = 1 return 0 @@ -1706,10 +1706,10 @@ class FunctionActionTestCase(unittest.TestCase): assert self.build_it assert self.string_it - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a function Action.""" - def LocalFunc(): + def LocalFunc() -> None: pass func_matches = { @@ -1775,7 +1775,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c in matches_foo, repr(c) class Foo: - def get_contents(self, target, source, env): + def get_contents(self, target, source, env) -> bytes: return b'xyzzy' a = factory(Foo()) @@ -1783,7 +1783,7 @@ class FunctionActionTestCase(unittest.TestCase): assert c == b'xyzzy', repr(c) class LocalClass: - def LocalMethod(self): + def LocalMethod(self) -> None: pass lc = LocalClass() @@ -1793,10 +1793,10 @@ class FunctionActionTestCase(unittest.TestCase): c == meth_matches[sys.version_info[:2]] ), f"Got\n{c!r}\nExpected one of \n" + repr(meth_matches[sys.version_info[:2]]) - def test_strfunction(self): + def test_strfunction(self) -> None: """Test the FunctionAction.strfunction() method.""" - def func(): + def func() -> None: pass def factory(act, **kw): @@ -1817,10 +1817,10 @@ class FunctionActionTestCase(unittest.TestCase): class ListActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a list of subsidiary Actions.""" - def func(): + def func() -> None: pass a = SCons.Action.ListAction(["x", func, ["y", "z"]]) @@ -1829,26 +1829,26 @@ class ListActionTestCase(unittest.TestCase): assert isinstance(a.list[2], SCons.Action.ListAction) assert a.list[2].list[0].cmd_list == 'y' - def test___str__(self): + def test___str__(self) -> None: """Test the __str__() method for a list of subsidiary Actions.""" - def f(target, source, env): + def f(target, source, env) -> None: pass - def g(target, source, env): + def g(target, source, env) -> None: pass a = SCons.Action.ListAction([f, g, "XXX", f]) s = str(a) assert s == "f(target, source, env)\ng(target, source, env)\nXXX\nf(target, source, env)", s - def test_genstring(self): + def test_genstring(self) -> None: """Test the genstring() method for a list of subsidiary Actions.""" - def f(target, source, env): + def f(target, source, env) -> None: pass - def g(target, source, env, for_signature): + def g(target, source, env, for_signature) -> str: return 'generated %s %s' % (target[0], source[0]) g = SCons.Action.Action(g, generator=1) @@ -1856,11 +1856,11 @@ class ListActionTestCase(unittest.TestCase): s = a.genstring(['foo.x'], ['bar.y'], Environment()) assert s == "f(target, source, env)\ngenerated foo.x bar.y\nXXX\nf(target, source, env)", s - def test_execute(self): + def test_execute(self) -> None: """Test executing a list of subsidiary Actions.""" self.inc = 0 - def f(target, source, env): + def f(target, source, env) -> None: s = env['s'] s.inc = s.inc + 1 @@ -1870,19 +1870,19 @@ class ListActionTestCase(unittest.TestCase): cmd2 = r'%s %s %s syzygy' % (_python_, act_py, outfile) - def function2(target, source, env): + def function2(target, source, env) -> int: with open(env['out'], 'a') as f: f.write("function2\n") return 0 class class2a: - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> int: with open(env['out'], 'a') as f: f.write("class2a\n") return 0 class class2b: - def __init__(self, target, source, env): + def __init__(self, target, source, env) -> None: with open(env['out'], 'a') as f: f.write("class2b\n") @@ -1892,12 +1892,12 @@ class ListActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'syzygy'\nfunction2\nclass2a\nclass2b\n", c - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a list of subsidiary Actions.""" self.foo = 0 - def gen(target, source, env, for_signature): + def gen(target, source, env, for_signature) -> str: s = env['s'] s.foo = 1 return "y" @@ -1911,7 +1911,7 @@ class ListActionTestCase(unittest.TestCase): class LazyActionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of a lazy-evaluation Action.""" # Environment variable references should create a special type @@ -1925,10 +1925,10 @@ class LazyActionTestCase(unittest.TestCase): assert isinstance(a10, SCons.Action.LazyAction), a10 assert a10.var == 'FOO', a10.var - def test_genstring(self): + def test_genstring(self) -> None: """Test the lazy-evaluation Action genstring() method.""" - def f(target, source, env): + def f(target, source, env) -> None: pass a = SCons.Action.Action('$BAR') @@ -1939,10 +1939,10 @@ class LazyActionTestCase(unittest.TestCase): s = a.genstring([], [], env=env2) assert s == 'xxx', s - def test_execute(self): + def test_execute(self) -> None: """Test executing a lazy-evaluation Action.""" - def f(target, source, env): + def f(target, source, env) -> int: s = env['s'] s.test = 1 return 0 @@ -1955,7 +1955,7 @@ class LazyActionTestCase(unittest.TestCase): c = test.read(outfile, 'r') assert c == "act.py: 'lazy'\n", c - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of a lazy-evaluation Action.""" a = SCons.Action.Action("${FOO}") @@ -1963,10 +1963,10 @@ class LazyActionTestCase(unittest.TestCase): c = a.get_contents(target=[], source=[], env=env) assert c == b"This is a test", c - def test_get_contents_of_function_action(self): + def test_get_contents_of_function_action(self) -> None: """Test fetching the contents of a lazy-evaluation FunctionAction.""" - def LocalFunc(): + def LocalFunc() -> None: pass func_matches = { @@ -2018,7 +2018,7 @@ class LazyActionTestCase(unittest.TestCase): class ActionCallerTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of an ActionCaller""" ac = SCons.Action.ActionCaller(1, [2, 3], {'FOO': 4, 'BAR': 5}) @@ -2026,13 +2026,13 @@ class ActionCallerTestCase(unittest.TestCase): assert ac.args == [2, 3], ac.args assert ac.kw == {'FOO': 4, 'BAR': 5}, ac.kw - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the contents of an ActionCaller""" - def strfunc(): + def strfunc() -> None: pass - def LocalFunc(): + def LocalFunc() -> None: pass matches = { @@ -2063,7 +2063,7 @@ class ActionCallerTestCase(unittest.TestCase): ) class LocalActFunc: - def __call__(self): + def __call__(self) -> None: pass af = SCons.Action.ActionFactory(GlobalActFunc(), strfunc) @@ -2093,15 +2093,15 @@ class ActionCallerTestCase(unittest.TestCase): assert c in ("", "", ""), repr(c) # ^^ class str for python3 - def test___call__(self): + def test___call__(self) -> None: """Test calling an ActionCaller""" actfunc_args = [] - def actfunc(a1, a2, a3, args=actfunc_args): + def actfunc(a1, a2, a3, args=actfunc_args) -> None: args.extend([a1, a2, a3]) - def strfunc(a1, a2, a3): + def strfunc(a1, a2, a3) -> None: pass e = Environment(FOO=2, BAR=5) @@ -2121,15 +2121,15 @@ class ActionCallerTestCase(unittest.TestCase): assert actfunc_args[2] is e, actfunc_args del actfunc_args[:] - def test_strfunction(self): + def test_strfunction(self) -> None: """Test calling the ActionCaller strfunction() method""" strfunc_args = [] - def actfunc(a1, a2, a3, a4): + def actfunc(a1, a2, a3, a4) -> None: pass - def strfunc(a1, a2, a3, a4, args=strfunc_args): + def strfunc(a1, a2, a3, a4, args=strfunc_args) -> None: args.extend([a1, a2, a3, a4]) af = SCons.Action.ActionFactory(actfunc, strfunc) @@ -2145,29 +2145,29 @@ class ActionCallerTestCase(unittest.TestCase): class ActionFactoryTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test creation of an ActionFactory""" - def actfunc(): + def actfunc() -> None: pass - def strfunc(): + def strfunc() -> None: pass ac = SCons.Action.ActionFactory(actfunc, strfunc) assert ac.actfunc is actfunc, ac.actfunc assert ac.strfunc is strfunc, ac.strfunc - def test___call__(self): + def test___call__(self) -> None: """Test calling whatever's returned from an ActionFactory""" actfunc_args = [] strfunc_args = [] - def actfunc(a1, a2, a3, args=actfunc_args): + def actfunc(a1, a2, a3, args=actfunc_args) -> None: args.extend([a1, a2, a3]) - def strfunc(a1, a2, a3, args=strfunc_args): + def strfunc(a1, a2, a3, args=strfunc_args) -> None: args.extend([a1, a2, a3]) af = SCons.Action.ActionFactory(actfunc, strfunc) @@ -2177,7 +2177,7 @@ class ActionFactoryTestCase(unittest.TestCase): class ActionCompareTestCase(unittest.TestCase): - def test_1_solo_name(self): + def test_1_solo_name(self) -> None: """Test Lazy Cmd Generator Action get_name alone. Basically ensures we can locate the builder, comparing it to @@ -2188,7 +2188,7 @@ class ActionCompareTestCase(unittest.TestCase): name = bar.get_name(env) assert name == 'BAR', name - def test_2_multi_name(self): + def test_2_multi_name(self) -> None: """Test LazyCmdGenerator Action get_name multi builders. Ensure that we can compare builders (and thereby actions) to @@ -2204,7 +2204,7 @@ class ActionCompareTestCase(unittest.TestCase): name = bar.get_name(env) assert name == 'BAR', name - def test_3_dict_names(self): + def test_3_dict_names(self) -> None: """Test Action/Suffix dicts with get_name. Verifies that Action/Suffix dictionaries work correctly, @@ -2226,16 +2226,16 @@ class ActionCompareTestCase(unittest.TestCase): class TestClass: """A test class used by ObjectContentsTestCase.test_object_contents""" - def __init__(self): + def __init__(self) -> None: self.a = "a" self.b = "b" - def method(self, arg): + def method(self, arg) -> None: pass class ObjectContentsTestCase(unittest.TestCase): - def test_function_contents(self): + def test_function_contents(self) -> None: """Test that Action._function_contents works""" def func1(a, b, c): @@ -2263,7 +2263,7 @@ class ObjectContentsTestCase(unittest.TestCase): expected[sys.version_info[:2]] ) - def test_object_contents(self): + def test_object_contents(self) -> None: """Test that Action._object_contents works""" # See definition above @@ -2305,7 +2305,7 @@ class ObjectContentsTestCase(unittest.TestCase): expected[sys.version_info[:2]] ) - def test_code_contents(self): + def test_code_contents(self) -> None: """Test that Action._code_contents works""" code = compile("print('Hello, World!')", '', 'exec') diff --git a/SCons/Builder.py b/SCons/Builder.py index ab51c3225..bdedc3a2a 100644 --- a/SCons/Builder.py +++ b/SCons/Builder.py @@ -130,14 +130,14 @@ class DictCmdGenerator(SCons.Util.Selector): to return the proper action based on the file suffix of the source file.""" - def __init__(self, mapping=None, source_ext_match=True): + def __init__(self, mapping=None, source_ext_match: bool=True) -> None: super().__init__(mapping) self.source_ext_match = source_ext_match def src_suffixes(self): return list(self.keys()) - def add_action(self, suffix, action): + def add_action(self, suffix, action) -> None: """Add a suffix-action pair to the mapping. """ self[suffix] = action @@ -222,12 +222,12 @@ class OverrideWarner(UserDict): can actually invoke multiple builders. This class only emits the warnings once, no matter how many Builders are invoked. """ - def __init__(self, mapping): + def __init__(self, mapping) -> None: super().__init__(mapping) if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.OverrideWarner') self.already_warned = None - def warn(self): + def warn(self) -> None: if self.already_warned: return for k in self.keys(): @@ -335,7 +335,7 @@ class EmitterProxy: look there at actual build time to see if it holds a callable. If so, we will call that as the actual emitter.""" - def __init__(self, var): + def __init__(self, var) -> None: self.var = SCons.Util.to_String(var) def __call__(self, target, source, env): @@ -375,23 +375,23 @@ class BuilderBase: """ def __init__(self, action = None, - prefix = '', - suffix = '', - src_suffix = '', + prefix: str = '', + suffix: str = '', + src_suffix: str = '', target_factory = None, source_factory = None, target_scanner = None, source_scanner = None, emitter = None, - multi = 0, + multi: int = 0, env = None, - single_source = 0, + single_source: int = 0, name = None, chdir = _null, - is_explicit = 1, + is_explicit: int = 1, src_builder = None, - ensure_suffix = False, - **overrides): + ensure_suffix: bool = False, + **overrides) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.BuilderBase') self._memo = {} self.action = action @@ -439,7 +439,7 @@ class BuilderBase: src_builder = [ src_builder ] self.src_builder = src_builder - def __bool__(self): + def __bool__(self) -> bool: raise InternalError("Do not test for the Node.builder attribute directly; use Node.has_builder() instead") def get_name(self, env): @@ -471,7 +471,7 @@ class BuilderBase: suffixes = [] return match_splitext(path, suffixes) - def _adjustixes(self, files, pre, suf, ensure_suffix=False): + def _adjustixes(self, files, pre, suf, ensure_suffix: bool=False): if not files: return [] result = [] @@ -673,7 +673,7 @@ class BuilderBase: prefix = prefix(env, sources) return env.subst(prefix) - def set_suffix(self, suffix): + def set_suffix(self, suffix) -> None: if not callable(suffix): suffix = self.adjust_suffix(suffix) self.suffix = suffix @@ -684,7 +684,7 @@ class BuilderBase: suffix = suffix(env, sources) return env.subst(suffix) - def set_src_suffix(self, src_suffix): + def set_src_suffix(self, src_suffix) -> None: if not src_suffix: src_suffix = [] elif not SCons.Util.is_List(src_suffix): @@ -698,7 +698,7 @@ class BuilderBase: return '' return ret[0] - def add_emitter(self, suffix, emitter): + def add_emitter(self, suffix, emitter) -> None: """Add a suffix-emitter mapping to this Builder. This assumes that emitter has been initialized with an @@ -708,7 +708,7 @@ class BuilderBase: """ self.emitter[suffix] = emitter - def add_src_builder(self, builder): + def add_src_builder(self, builder) -> None: """ Add a new Builder to the list of src_builders. @@ -875,7 +875,7 @@ class CompositeBuilder(SCons.Util.Proxy): to the DictCmdGenerator's add_action() method. """ - def __init__(self, builder, cmdgen): + def __init__(self, builder, cmdgen) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Builder.CompositeBuilder') super().__init__(builder) @@ -885,7 +885,7 @@ class CompositeBuilder(SCons.Util.Proxy): __call__ = SCons.Util.Delegate('__call__') - def add_action(self, suffix, action): + def add_action(self, suffix, action) -> None: self.cmdgen.add_action(suffix, action) self.set_src_suffix(self.cmdgen.src_suffixes()) diff --git a/SCons/BuilderTests.py b/SCons/BuilderTests.py index 636534f04..3ba5285cd 100644 --- a/SCons/BuilderTests.py +++ b/SCons/BuilderTests.py @@ -27,7 +27,7 @@ import SCons.compat # Where this is defined in the file seems to affect its # byte-code contents, so try to minimize changes by # defining it here, before we even import anything. -def Func(): +def Func() -> None: pass from collections import UserList @@ -70,7 +70,7 @@ scons_env = SCons.Environment.Environment() env_arg2nodes_called = None class Environment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self.d = {} self.d['SHELL'] = scons_env['SHELL'] self.d['SPAWN'] = scons_env['SPAWN'] @@ -87,11 +87,11 @@ class Environment: def substitute(m, d=self.d): return d.get(m.group(1), '') return re.sub(r'\$(\w+)', substitute, s) - def subst_target_source(self, string, raw=0, target=None, + def subst_target_source(self, string, raw: int=0, target=None, source=None, dict=None, conv=None): return SCons.Subst.scons_subst(string, self, raw, target, source, dict, conv) - def subst_list(self, string, raw=0, target=None, source=None, conv=None): + def subst_list(self, string, raw: int=0, target=None, source=None, conv=None): return SCons.Subst.scons_subst_list(string, self, raw, target, source, {}, {}, conv) def arg2nodes(self, args, factory, **kw): @@ -111,13 +111,13 @@ class Environment: return self.scanner def Dictionary(self): return {} - def autogenerate(self, dir=''): + def autogenerate(self, dir: str=''): return {} - def __setitem__(self, item, var): + def __setitem__(self, item, var) -> None: self.d[item] = var def __getitem__(self, item): return self.d[item] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.d def keys(self): return list(self.d.keys()) @@ -128,7 +128,7 @@ class Environment: env.d.update(overrides) env.scanner = self.scanner return env - def _update(self, dict): + def _update(self, dict) -> None: self.d.update(dict) def items(self): return list(self.d.items()) @@ -144,15 +144,15 @@ class Environment: return self.scanner == other.scanner or self.d == other.d class MyAction: - def __init__(self, action): + def __init__(self, action) -> None: self.action = action - def __call__(self, *args, **kw): + def __call__(self, *args, **kw) -> None: pass def get_executor(self, env, overrides, tlist, slist, executor_kw): return ['executor'] + [self.action] class MyNode_without_target_from_source: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self.sources = [] self.builder = None @@ -162,19 +162,19 @@ class MyNode_without_target_from_source: return os.path.splitext(self.name)[1] def disambiguate(self): return self - def __str__(self): + def __str__(self) -> str: return self.name - def builder_set(self, builder): + def builder_set(self, builder) -> None: self.builder = builder - def has_builder(self): + def has_builder(self) -> bool: return self.builder is not None - def set_explicit(self, is_explicit): + def set_explicit(self, is_explicit) -> None: self.is_explicit = is_explicit def has_explicit_builder(self): return self.is_explicit - def env_set(self, env, safe=0): + def env_set(self, env, safe: int=0) -> None: self.env = env - def add_source(self, source): + def add_source(self, source) -> None: self.sources.extend(source) def scanner_key(self): return self.name @@ -184,9 +184,9 @@ class MyNode_without_target_from_source: return env def get_build_env(self): return self.executor.get_build_env() - def set_executor(self, executor): + def set_executor(self, executor) -> None: self.executor = executor - def get_executor(self, create=1): + def get_executor(self, create: int=1): return self.executor class MyNode(MyNode_without_target_from_source): @@ -195,7 +195,7 @@ class MyNode(MyNode_without_target_from_source): class BuilderTestCase(unittest.TestCase): - def test__init__(self): + def test__init__(self) -> None: """Test simple Builder creation """ builder = SCons.Builder.Builder(action="foo") @@ -204,7 +204,7 @@ class BuilderTestCase(unittest.TestCase): x = builder.overrides['OVERRIDE'] assert x == 'x', x - def test__bool__(self): + def test__bool__(self) -> None: """Test a builder raising an exception when __bool__ is called. """ # basic test: explicitly call it @@ -339,7 +339,7 @@ class BuilderTestCase(unittest.TestCase): p = target.sources[0].get_internal_path() assert p == os.path.join('src_dir', 'n22'), p - def test_mistaken_variables(self): + def test_mistaken_variables(self) -> None: """Test keyword arguments that are often mistakes """ import SCons.Warnings @@ -348,7 +348,7 @@ class BuilderTestCase(unittest.TestCase): save_warn = SCons.Warnings.warn warned = [] - def my_warn(exception, warning, warned=warned): + def my_warn(exception, warning, warned=warned) -> None: warned.append(warning) SCons.Warnings.warn = my_warn @@ -368,7 +368,7 @@ class BuilderTestCase(unittest.TestCase): finally: SCons.Warnings.warn = save_warn - def test_action(self): + def test_action(self) -> None: """Test Builder creation Verify that we can retrieve the supplied action attribute. @@ -376,7 +376,7 @@ class BuilderTestCase(unittest.TestCase): builder = SCons.Builder.Builder(action="foo") assert builder.action.cmd_list == "foo" - def func(): + def func() -> None: pass builder = SCons.Builder.Builder(action=func) assert isinstance(builder.action, SCons.Action.FunctionAction) @@ -385,16 +385,16 @@ class BuilderTestCase(unittest.TestCase): # point in the future. assert builder.action.execfunction == func - def test_generator(self): + def test_generator(self) -> None: """Test Builder creation given a generator function.""" - def generator(): + def generator() -> None: pass builder = SCons.Builder.Builder(generator=generator) assert builder.action.generator == generator - def test_cmp(self): + def test_cmp(self) -> None: """Test simple comparisons of Builder objects """ b1 = SCons.Builder.Builder(src_suffix = '.o') @@ -404,7 +404,7 @@ class BuilderTestCase(unittest.TestCase): assert b1 != b3 assert b2 != b3 - def test_target_factory(self): + def test_target_factory(self) -> None: """Test a Builder that creates target nodes of a specified class """ class Foo: @@ -416,7 +416,7 @@ class BuilderTestCase(unittest.TestCase): assert builder.target_factory is FooFactory assert builder.source_factory is not FooFactory - def test_source_factory(self): + def test_source_factory(self) -> None: """Test a Builder that creates source nodes of a specified class """ class Foo: @@ -428,7 +428,7 @@ class BuilderTestCase(unittest.TestCase): assert builder.target_factory is not FooFactory assert builder.source_factory is FooFactory - def test_splitext(self): + def test_splitext(self) -> None: """Test the splitext() method attached to a Builder.""" b = SCons.Builder.Builder() assert b.splitext('foo') == ('foo','') @@ -436,14 +436,14 @@ class BuilderTestCase(unittest.TestCase): assert b.splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'),'') class MyBuilder(SCons.Builder.BuilderBase): - def splitext(self, path): + def splitext(self, path) -> str: return "called splitext()" b = MyBuilder() ret = b.splitext('xyz.c') assert ret == "called splitext()", ret - def test_adjust_suffix(self): + def test_adjust_suffix(self) -> None: """Test how a Builder adjusts file suffixes """ b = SCons.Builder.Builder() @@ -452,14 +452,14 @@ class BuilderTestCase(unittest.TestCase): assert b.adjust_suffix('$foo') == '$foo' class MyBuilder(SCons.Builder.BuilderBase): - def adjust_suffix(self, suff): + def adjust_suffix(self, suff) -> str: return "called adjust_suffix()" b = MyBuilder() ret = b.adjust_suffix('.foo') assert ret == "called adjust_suffix()", ret - def test_prefix(self): + def test_prefix(self) -> None: """Test Builder creation with a specified target prefix Make sure that there is no '.' separator appended. @@ -515,7 +515,7 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(my_env, target = None, source = 'f6.zzz')[0] assert tgt.get_internal_path() == 'emit-f6', tgt.get_internal_path() - def test_set_suffix(self): + def test_set_suffix(self) -> None: """Test the set_suffix() method""" b = SCons.Builder.Builder(action='') env = Environment(XSUFFIX = '.x') @@ -531,7 +531,7 @@ class BuilderTestCase(unittest.TestCase): s = b.get_suffix(env) assert s == '.x', s - def test_src_suffix(self): + def test_src_suffix(self) -> None: """Test Builder creation with a specified source file suffix Make sure that the '.' separator is appended to the @@ -565,7 +565,7 @@ class BuilderTestCase(unittest.TestCase): b5 = SCons.Builder.Builder(action = { '.y' : ''}) assert b5.src_suffixes(env) == ['.y'], b5.src_suffixes(env) - def test_srcsuffix_nonext(self): + def test_srcsuffix_nonext(self) -> None: """Test target generation from non-extension source suffixes""" env = Environment() b6 = SCons.Builder.Builder(action = '', @@ -592,7 +592,7 @@ class BuilderTestCase(unittest.TestCase): tgt = b9(env, target=None, source='foo_altsrc.b') assert str(tgt[0]) == 'foo.c', str(tgt[0]) - def test_src_suffix_expansion(self): + def test_src_suffix_expansion(self) -> None: """Test handling source suffixes when an expansion is involved""" env = Environment(OBJSUFFIX = '.obj') @@ -607,7 +607,7 @@ class BuilderTestCase(unittest.TestCase): s = list(map(str, tgt[0].sources)) assert s == ['foo.obj'], s - def test_suffix(self): + def test_suffix(self) -> None: """Test Builder creation with a specified target suffix Make sure that the '.' separator is appended to the @@ -658,9 +658,9 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(my_env, target = None, source = 'f6.zzz')[0] assert tgt.get_internal_path() == 'f6.emit', tgt.get_internal_path() - def test_single_source(self): + def test_single_source(self) -> None: """Test Builder with single_source flag set""" - def func(target, source, env): + def func(target, source, env) -> None: """create the file""" with open(str(target[0]), "w"): pass @@ -715,9 +715,9 @@ class BuilderTestCase(unittest.TestCase): assert 0 - def test_lists(self): + def test_lists(self) -> None: """Testing handling lists of targets and source""" - def function2(target, source, env, tlist = [outfile, outfile2], **kw): + def function2(target, source, env, tlist = [outfile, outfile2], **kw) -> int: for t in target: with open(str(t), 'w') as f: f.write("function2\n") @@ -748,7 +748,7 @@ class BuilderTestCase(unittest.TestCase): sub1_out = test.workpath('sub1', 'out') sub2_out = test.workpath('sub2', 'out') - def function3(target, source, env, tlist = [sub1_out, sub2_out]): + def function3(target, source, env, tlist = [sub1_out, sub2_out]) -> int: for t in target: with open(str(t), 'w') as f: f.write("function3\n") @@ -773,7 +773,7 @@ class BuilderTestCase(unittest.TestCase): assert os.path.exists(test.workpath('sub1')) assert os.path.exists(test.workpath('sub2')) - def test_src_builder(self): + def test_src_builder(self) -> None: """Testing Builders with src_builder""" # These used to be MultiStepBuilder objects until we # eliminated it as a separate class @@ -829,7 +829,7 @@ class BuilderTestCase(unittest.TestCase): s = list(map(str, tgt.sources[0].sources[0].sources)) assert s == ['test.i'], s - def test_target_scanner(self): + def test_target_scanner(self) -> None: """Testing ability to set target and source scanners through a builder.""" global instanced class TestScanner: @@ -855,12 +855,12 @@ class BuilderTestCase(unittest.TestCase): assert tgt.builder.target_scanner == tscan, tgt.builder.target_scanner assert tgt.builder.source_scanner == tscan, tgt.builder.source_scanner - def test_actual_scanner(self): + def test_actual_scanner(self) -> None: """Test usage of actual Scanner objects.""" import SCons.Scanner - def func(self): + def func(self) -> None: pass scanner = SCons.Scanner.ScannerBase(func, name='fooscan') @@ -872,17 +872,17 @@ class BuilderTestCase(unittest.TestCase): assert b1 == b2 assert b1 != b3 - def test_src_scanner(self): + def test_src_scanner(self) -> None: """Testing ability to set a source file scanner through a builder.""" class TestScanner: - def key(self, env): + def key(self, env) -> str: return 'TestScannerkey' def instance(self, env): return self def select(self, node): return self name = 'TestScanner' - def __str__(self): + def __str__(self) -> str: return self.name scanner = TestScanner() @@ -904,12 +904,12 @@ class BuilderTestCase(unittest.TestCase): # An Environment that has suffix-specified SCANNERS should # provide a source scanner to the target. class EnvTestScanner: - def key(self, env): + def key(self, env) -> str: return '.y' def instance(self, env): return self name = 'EnvTestScanner' - def __str__(self): + def __str__(self) -> str: return self.name def select(self, node): return self @@ -962,7 +962,7 @@ class BuilderTestCase(unittest.TestCase): - def test_Builder_API(self): + def test_Builder_API(self) -> None: """Test Builder interface. Some of this is tested elsewhere in this file, but this is a @@ -1135,9 +1135,9 @@ class BuilderTestCase(unittest.TestCase): assert r == ['.src_sfx1', '.src_sfx2'], r - def test_Builder_Args(self): + def test_Builder_Args(self) -> None: """Testing passing extra args to a builder.""" - def buildFunc(target, source, env, s=self): + def buildFunc(target, source, env, s=self) -> None: s.foo=env['foo'] s.bar=env['bar'] assert env['CC'] == 'mycc' @@ -1150,7 +1150,7 @@ class BuilderTestCase(unittest.TestCase): assert self.foo == 1, self.foo assert self.bar == 2, self.bar - def test_emitter(self): + def test_emitter(self) -> None: """Test emitter functions.""" def emit(target, source, env): foo = env.get('foo', 0) @@ -1214,7 +1214,7 @@ class BuilderTestCase(unittest.TestCase): assert 'baz' in list(map(str, tgt.sources)), list(map(str, tgt.sources)) assert 'bar' in list(map(str, tgt.sources)), list(map(str, tgt.sources)) - def test_emitter_preserve_builder(self): + def test_emitter_preserve_builder(self) -> None: """Test an emitter not overwriting a newly-set builder""" env = Environment() @@ -1236,7 +1236,7 @@ class BuilderTestCase(unittest.TestCase): assert tgt.builder is builder, tgt.builder assert node.builder is new_builder, node.builder - def test_emitter_suffix_map(self): + def test_emitter_suffix_map(self) -> None: """Test mapping file suffixes to emitter functions""" env = Environment() @@ -1270,7 +1270,7 @@ class BuilderTestCase(unittest.TestCase): tgt = builder(env, None, source='ccc.4c')[0] assert str(tgt) == 'emit4c-ccc', str(tgt) - def test_emitter_function_list(self): + def test_emitter_function_list(self) -> None: """Test lists of emitter functions""" env = Environment() @@ -1309,7 +1309,7 @@ class BuilderTestCase(unittest.TestCase): tgts = list(map(str, tgts)) assert tgts == ['target-2', 'emit2a-aaa', 'emit2b-aaa'], tgts - def test_emitter_TARGET_SOURCE(self): + def test_emitter_TARGET_SOURCE(self) -> None: """Test use of $TARGET and $SOURCE in emitter results""" env = SCons.Environment.Environment() @@ -1329,7 +1329,7 @@ class BuilderTestCase(unittest.TestCase): assert targets == ['TTT', 'SSS.s1', 'TTT.t1'], targets assert sources == ['SSS', 'TTT.t2', 'SSS.s2'], targets - def test_no_target(self): + def test_no_target(self) -> None: """Test deducing the target from the source.""" env = Environment() @@ -1385,7 +1385,7 @@ class BuilderTestCase(unittest.TestCase): assert str(tgt.sources[0]) == 'i0.w', list(map(str, tgt.sources)) assert str(tgt.sources[1]) == 'i1.y', list(map(str, tgt.sources)) - def test_get_name(self): + def test_get_name(self) -> None: """Test getting name of builder. Each type of builder should return its environment-specific @@ -1445,8 +1445,8 @@ class BuilderTestCase(unittest.TestCase): class CompositeBuilderTestCase(unittest.TestCase): - def setUp(self): - def func_action(target, source, env): + def setUp(self) -> None: + def func_action(target, source, env) -> int: return 0 builder = SCons.Builder.Builder(action={ '.foo' : func_action, @@ -1455,7 +1455,7 @@ class CompositeBuilderTestCase(unittest.TestCase): self.func_action = func_action self.builder = builder - def test___init__(self): + def test___init__(self) -> None: """Test CompositeBuilder creation""" env = Environment() builder = SCons.Builder.Builder(action={}) @@ -1466,7 +1466,7 @@ class CompositeBuilderTestCase(unittest.TestCase): assert isinstance(builder, SCons.Builder.CompositeBuilder) assert isinstance(builder.action, SCons.Action.CommandGeneratorAction) - def test_target_action(self): + def test_target_action(self) -> None: """Test CompositeBuilder setting of target builder actions""" env = Environment() builder = self.builder @@ -1479,7 +1479,7 @@ class CompositeBuilderTestCase(unittest.TestCase): assert isinstance(tgt.builder, SCons.Builder.BuilderBase) assert tgt.builder.action is builder.action - def test_multiple_suffix_error(self): + def test_multiple_suffix_error(self) -> None: """Test the CompositeBuilder multiple-source-suffix error""" env = Environment() builder = self.builder @@ -1494,7 +1494,7 @@ class CompositeBuilderTestCase(unittest.TestCase): expect = "While building `['test3']' from `test1.foo': Cannot build multiple sources with different extensions: .bar, .foo" assert str(err) == expect, err - def test_source_ext_match(self): + def test_source_ext_match(self) -> None: """Test the CompositeBuilder source_ext_match argument""" env = Environment() func_action = self.func_action @@ -1505,7 +1505,7 @@ class CompositeBuilderTestCase(unittest.TestCase): tgt = builder(env, target='test3', source=['test2.bar', 'test1.foo'])[0] tgt.build() - def test_suffix_variable(self): + def test_suffix_variable(self) -> None: """Test CompositeBuilder defining action suffixes through a variable""" env = Environment(BAR_SUFFIX = '.BAR2', FOO_SUFFIX = '.FOO2') func_action = self.func_action @@ -1532,7 +1532,7 @@ class CompositeBuilderTestCase(unittest.TestCase): flag = 1 assert flag, "UserError should be thrown when we call a builder with ambigous suffixes." - def test_src_builder(self): + def test_src_builder(self) -> None: """Test CompositeBuilder's use of a src_builder""" env = Environment() diff --git a/SCons/CacheDir.py b/SCons/CacheDir.py index 70c4f38a8..12f1d5493 100644 --- a/SCons/CacheDir.py +++ b/SCons/CacheDir.py @@ -43,7 +43,7 @@ cache_show = False cache_readonly = False cache_tmp_uuid = uuid.uuid4().hex -def CacheRetrieveFunc(target, source, env): +def CacheRetrieveFunc(target, source, env) -> int: t = target[0] fs = t.fs cd = env.get_CacheDir() @@ -133,7 +133,7 @@ CachePush = SCons.Action.Action(CachePushFunc, None) class CacheDir: - def __init__(self, path): + def __init__(self, path) -> None: """ Initialize a CacheDir object. @@ -192,12 +192,12 @@ class CacheDir: msg = "Failed to read cache configuration for " + path raise SCons.Errors.SConsEnvironmentError(msg) - def CacheDebug(self, fmt, target, cachefile): + def CacheDebug(self, fmt, target, cachefile) -> None: if cache_debug != self.current_cache_debug: if cache_debug == '-': self.debugFP = sys.stdout elif cache_debug: - def debug_cleanup(debugFP): + def debug_cleanup(debugFP) -> None: debugFP.close() self.debugFP = open(cache_debug, 'w') @@ -270,7 +270,7 @@ class CacheDir: cachedir = os.path.join(self.path, subdir) return cachedir, os.path.join(cachedir, sig) - def retrieve(self, node): + def retrieve(self, node) -> bool: """ This method is called from multiple threads in a parallel build, so only do thread safe stuff here. Do thread unsafe stuff in diff --git a/SCons/CacheDirTests.py b/SCons/CacheDirTests.py index c4a0ed7c1..cc7563d87 100644 --- a/SCons/CacheDirTests.py +++ b/SCons/CacheDirTests.py @@ -35,7 +35,7 @@ import SCons.CacheDir built_it = None class Action: - def __call__(self, targets, sources, env, **kw): + def __call__(self, targets, sources, env, **kw) -> int: global built_it if kw.get('execute', 1): built_it = 1 @@ -46,7 +46,7 @@ class Action: return bytearray('','utf-8') class Builder: - def __init__(self, environment, action): + def __init__(self, environment, action) -> None: self.env = environment self.action = action self.overrides = {} @@ -54,7 +54,7 @@ class Builder: self.target_scanner = None class Environment: - def __init__(self, cachedir): + def __init__(self, cachedir) -> None: self.cachedir = cachedir def Override(self, overrides): return self @@ -65,7 +65,7 @@ class BaseTestCase(unittest.TestCase): """ Base fixtures common to our other unittest classes. """ - def setUp(self): + def setUp(self) -> None: self.test = TestCmd(workdir='') import SCons.Node.FS @@ -82,7 +82,7 @@ class BaseTestCase(unittest.TestCase): #node.binfo.ninfo.bsig = bsig return node - def tearDown(self): + def tearDown(self) -> None: os.remove(os.path.join(self._CacheDir.path, 'config')) os.rmdir(self._CacheDir.path) # Should that be shutil.rmtree? @@ -91,7 +91,7 @@ class CacheDirTestCase(BaseTestCase): """ Test calling CacheDir code directly. """ - def test_cachepath(self): + def test_cachepath(self) -> None: """Test the cachepath() method""" # Verify how the cachepath() method determines the name @@ -117,15 +117,15 @@ class ExceptionTestCase(unittest.TestCase): # Don't inherit from BaseTestCase, we're by definition trying to # break things so we really want a clean slate for each test. - def setUp(self): + def setUp(self) -> None: self.tmpdir = tempfile.mkdtemp() self._CacheDir = SCons.CacheDir.CacheDir(self.tmpdir) - def tearDown(self): + def tearDown(self) -> None: shutil.rmtree(self.tmpdir) @unittest.skipIf(sys.platform.startswith("win"), "This fixture will not trigger an OSError on Windows") - def test_throws_correct_on_OSError(self): + def test_throws_correct_on_OSError(self) -> None: """Test that the correct error is thrown when cache directory cannot be created.""" privileged_dir = os.path.join(self.tmpdir, "privileged") try: @@ -140,11 +140,11 @@ class ExceptionTestCase(unittest.TestCase): shutil.rmtree(privileged_dir) - def test_throws_correct_when_failed_to_write_configfile(self): + def test_throws_correct_when_failed_to_write_configfile(self) -> None: class Unserializable: """A class which the JSON should not be able to serialize""" - def __init__(self, oldconfig): + def __init__(self, oldconfig) -> None: self.something = 1 # Make the object unserializable # Pretend to be the old config just enough self.__dict__["prefix_len"] = oldconfig["prefix_len"] @@ -155,7 +155,7 @@ class ExceptionTestCase(unittest.TestCase): else: return None - def __setitem__(self, name, value): + def __setitem__(self, name, value) -> None: self.__dict__[name] = value oldconfig = self._CacheDir.config @@ -171,7 +171,7 @@ class ExceptionTestCase(unittest.TestCase): except SCons.Errors.SConsEnvironmentError as e: assert str(e) == "Failed to write cache configuration for {}".format(self._CacheDir.path) - def test_raise_environment_error_on_invalid_json(self): + def test_raise_environment_error_on_invalid_json(self) -> None: config_file = os.path.join(self._CacheDir.path, "config") with open(config_file, "r") as cfg: content = cfg.read() @@ -195,19 +195,19 @@ class FileTestCase(BaseTestCase): # when the CacheDir support was refactored into its own module. # Look in the history for Node/FSTests.py if any of this needs # to be re-examined. - def retrieve_succeed(self, target, source, env, execute=1): + def retrieve_succeed(self, target, source, env, execute: int=1) -> int: self.retrieved.append(target) return 0 - def retrieve_fail(self, target, source, env, execute=1): + def retrieve_fail(self, target, source, env, execute: int=1) -> int: self.retrieved.append(target) return 1 - def push(self, target, source, env): + def push(self, target, source, env) -> int: self.pushed.append(target) return 0 - def test_CacheRetrieve(self): + def test_CacheRetrieve(self) -> None: """Test the CacheRetrieve() function""" save_CacheRetrieve = SCons.CacheDir.CacheRetrieve @@ -235,7 +235,7 @@ class FileTestCase(BaseTestCase): finally: SCons.CacheDir.CacheRetrieve = save_CacheRetrieve - def test_CacheRetrieveSilent(self): + def test_CacheRetrieveSilent(self) -> None: """Test the CacheRetrieveSilent() function""" save_CacheRetrieveSilent = SCons.CacheDir.CacheRetrieveSilent @@ -264,7 +264,7 @@ class FileTestCase(BaseTestCase): finally: SCons.CacheDir.CacheRetrieveSilent = save_CacheRetrieveSilent - def test_CachePush(self): + def test_CachePush(self) -> None: """Test the CachePush() function""" save_CachePush = SCons.CacheDir.CachePush @@ -299,7 +299,7 @@ class FileTestCase(BaseTestCase): finally: SCons.CacheDir.CachePush = save_CachePush - def test_warning(self): + def test_warning(self) -> None: """Test raising a warning if we can't copy a file to cache.""" test = TestCmd(workdir='') @@ -309,7 +309,7 @@ class FileTestCase(BaseTestCase): raise OSError shutil.copy2 = copy2 save_mkdir = os.mkdir - def mkdir(dir, mode=0): + def mkdir(dir, mode: int=0) -> None: pass os.mkdir = mkdir old_warn_exceptions = SCons.Warnings.warningAsException(1) @@ -333,7 +333,7 @@ class FileTestCase(BaseTestCase): SCons.Warnings.warningAsException(old_warn_exceptions) SCons.Warnings.suppressWarningClass(SCons.Warnings.CacheWriteErrorWarning) - def test_no_strfunction(self): + def test_no_strfunction(self) -> None: """Test handling no strfunction() for an action.""" save_CacheRetrieveSilent = SCons.CacheDir.CacheRetrieveSilent diff --git a/SCons/Conftest.py b/SCons/Conftest.py index 3c52ef462..3541bce0a 100644 --- a/SCons/Conftest.py +++ b/SCons/Conftest.py @@ -215,7 +215,7 @@ int main(void) _YesNoResult(context, ret, None, text) return ret -def _check_empty_program(context, comp, text, language, use_shared = False): +def _check_empty_program(context, comp, text, language, use_shared: bool = False): """Return 0 on success, 1 otherwise.""" if comp not in context.env or not context.env[comp]: # The compiler construction variable is not set or empty @@ -626,8 +626,8 @@ int main(void) { return ret def CheckLib(context, libs, func_name = None, header = None, - extra_libs = None, call = None, language = None, autoadd = 1, - append=True, unique=False): + extra_libs = None, call = None, language = None, autoadd: int = 1, + append: bool=True, unique: bool=False): """ Configure check for a C or C++ libraries "libs". Searches through the list of libraries, until one is found where the test succeeds. @@ -753,7 +753,7 @@ def CheckProg(context, prog_name): # END OF PUBLIC FUNCTIONS # -def _YesNoResult(context, ret, key, text, comment = None): +def _YesNoResult(context, ret, key, text, comment = None) -> None: r""" Handle the result of a test with a "yes" or "no" result. @@ -772,7 +772,7 @@ def _YesNoResult(context, ret, key, text, comment = None): context.Display("yes\n") -def _Have(context, key, have, comment = None): +def _Have(context, key, have, comment = None) -> None: r""" Store result of a test in context.havedict and context.headerfilename. @@ -815,7 +815,7 @@ def _Have(context, key, have, comment = None): context.config_h = context.config_h + lines -def _LogFailed(context, text, msg): +def _LogFailed(context, text, msg) -> None: """ Write to the log about a failed program. Add line numbers, so that error messages can be understood. diff --git a/SCons/Debug.py b/SCons/Debug.py index fa077436c..000ebd554 100644 --- a/SCons/Debug.py +++ b/SCons/Debug.py @@ -42,7 +42,7 @@ track_instances = False # List of currently tracked classes tracked_classes = {} -def logInstanceCreation(instance, name=None): +def logInstanceCreation(instance, name=None) -> None: if name is None: name = instance.__class__.__name__ if name not in tracked_classes: @@ -60,15 +60,15 @@ def string_to_classes(s): else: return s.split() -def fetchLoggedInstances(classes="*"): +def fetchLoggedInstances(classes: str="*"): classnames = string_to_classes(classes) return [(cn, len(tracked_classes[cn])) for cn in classnames] -def countLoggedInstances(classes, file=sys.stdout): +def countLoggedInstances(classes, file=sys.stdout) -> None: for classname in string_to_classes(classes): file.write("%s: %d\n" % (classname, len(tracked_classes[classname]))) -def listLoggedInstances(classes, file=sys.stdout): +def listLoggedInstances(classes, file=sys.stdout) -> None: for classname in string_to_classes(classes): file.write('\n%s:\n' % classname) for ref in tracked_classes[classname]: @@ -79,7 +79,7 @@ def listLoggedInstances(classes, file=sys.stdout): if obj is not None: file.write(' %s\n' % repr(obj)) -def dumpLoggedInstances(classes, file=sys.stdout): +def dumpLoggedInstances(classes, file=sys.stdout) -> None: for classname in string_to_classes(classes): file.write('\n%s:\n' % classname) for ref in tracked_classes[classname]: @@ -99,7 +99,7 @@ if sys.platform[:5] == "linux": return int(mstr) elif sys.platform[:6] == 'darwin': #TODO really get memory stats for OS X - def memory(): + def memory() -> int: return 0 elif sys.platform == 'win32': from SCons.compat.win32 import get_peak_memory_usage @@ -108,7 +108,7 @@ else: try: import resource except ImportError: - def memory(): + def memory() -> int: return 0 else: def memory(): @@ -132,7 +132,7 @@ def caller_stack(): caller_bases = {} caller_dicts = {} -def caller_trace(back=0): +def caller_trace(back: int=0) -> None: """ Trace caller stack and save info into global dicts, which are printed automatically at the end of SCons execution. @@ -153,7 +153,7 @@ def caller_trace(back=0): callee = caller # print a single caller and its callers, if any -def _dump_one_caller(key, file, level=0): +def _dump_one_caller(key, file, level: int=0) -> None: leader = ' '*level for v,c in sorted([(-v,c) for c,v in caller_dicts[key].items()]): file.write("%s %6d %s:%d(%s)\n" % ((leader,-v) + func_shorten(c[-3:]))) @@ -161,7 +161,7 @@ def _dump_one_caller(key, file, level=0): _dump_one_caller(c, file, level+1) # print each call tree -def dump_caller_counts(file=sys.stdout): +def dump_caller_counts(file=sys.stdout) -> None: for k in sorted(caller_bases.keys()): file.write("Callers of %s:%d(%s), %d calls:\n" % (func_shorten(k) + (caller_bases[k],))) @@ -196,7 +196,7 @@ TimeStampDefault = False StartTime = time.perf_counter() PreviousTime = StartTime -def Trace(msg, tracefile=None, mode='w', tstamp=False): +def Trace(msg, tracefile=None, mode: str='w', tstamp: bool=False) -> None: """Write a trace message. Write messages when debugging which do not interfere with stdout. @@ -217,7 +217,7 @@ def Trace(msg, tracefile=None, mode='w', tstamp=False): global TimeStampDefault global PreviousTime - def trace_cleanup(traceFP): + def trace_cleanup(traceFP) -> None: traceFP.close() if tracefile is None: diff --git a/SCons/Defaults.py b/SCons/Defaults.py index b21ce4c4a..15041a5ce 100644 --- a/SCons/Defaults.py +++ b/SCons/Defaults.py @@ -164,7 +164,7 @@ def get_paths_str(dest) -> str: If *dest* is a list, manually converts each elem to a string. """ - def quote(arg): + def quote(arg) -> str: return f'"{arg}"' if is_List(dest): @@ -256,7 +256,7 @@ Chmod = ActionFactory(chmod_func, chmod_strfunc) -def copy_func(dest, src, symlinks=True) -> int: +def copy_func(dest, src, symlinks: bool=True) -> int: """Implementation of the Copy action function. Copies *src* to *dest*. If *src* is a list, *dest* must be @@ -308,7 +308,7 @@ def copy_func(dest, src, symlinks=True) -> int: return 0 -def copy_strfunc(dest, src, symlinks=True) -> str: +def copy_strfunc(dest, src, symlinks: bool=True) -> str: """strfunction for the Copy action function.""" return f'Copy({get_paths_str(dest)}, {get_paths_str(src)})' @@ -316,7 +316,7 @@ def copy_strfunc(dest, src, symlinks=True) -> str: Copy = ActionFactory(copy_func, copy_strfunc) -def delete_func(dest, must_exist=False) -> None: +def delete_func(dest, must_exist: bool=False) -> None: """Implementation of the Delete action function. Lets the Python :func:`os.unlink` raise an error if *dest* does not exist, @@ -338,7 +338,7 @@ def delete_func(dest, must_exist=False) -> None: os.unlink(entry) -def delete_strfunc(dest, must_exist=False) -> str: +def delete_strfunc(dest, must_exist: bool=False) -> str: """strfunction for the Delete action function.""" return f'Delete({get_paths_str(dest)})' @@ -392,7 +392,7 @@ Touch = ActionFactory(touch_func, lambda file: f'Touch({get_paths_str(file)})') # Internal utility functions # pylint: disable-msg=too-many-arguments -def _concat(prefix, items_iter, suffix, env, f=lambda x: x, target=None, source=None, affect_signature=True): +def _concat(prefix, items_iter, suffix, env, f=lambda x: x, target=None, source=None, affect_signature: bool=True): """ Creates a new list from 'items_iter' by first interpolating each element in the list using the 'env' dictionary and then calling f on the @@ -602,7 +602,7 @@ class NullCmdGenerator: env["LINKCOM"] = "${DO_NOTHING('$LINK $SOURCES $TARGET')}" """ - def __init__(self, cmd): + def __init__(self, cmd) -> None: self.cmd = cmd def __call__(self, target, source, env, for_signature=None): @@ -622,7 +622,7 @@ class Variable_Method_Caller: create new environment objects to hold the variables.) """ - def __init__(self, variable, method): + def __init__(self, variable, method) -> None: self.variable = variable self.method = method diff --git a/SCons/DefaultsTests.py b/SCons/DefaultsTests.py index b23f3285e..a59b8b009 100644 --- a/SCons/DefaultsTests.py +++ b/SCons/DefaultsTests.py @@ -32,7 +32,7 @@ from SCons.Errors import UserError class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) @@ -48,7 +48,7 @@ class DummyEnvironment(collections.UserDict): class DefaultsTestCase(unittest.TestCase): - def test_mkdir_func0(self): + def test_mkdir_func0(self) -> None: test = TestCmd.TestCmd(workdir='') test.subdir('sub') subdir2 = test.workpath('sub', 'dir1', 'dir2') @@ -56,7 +56,7 @@ class DefaultsTestCase(unittest.TestCase): mkdir_func(subdir2) mkdir_func(subdir2) # 2nd time should be OK too - def test_mkdir_func1(self): + def test_mkdir_func1(self) -> None: test = TestCmd.TestCmd(workdir='') test.subdir('sub') subdir1 = test.workpath('sub', 'dir1') @@ -66,7 +66,7 @@ class DefaultsTestCase(unittest.TestCase): mkdir_func(subdir2) mkdir_func(subdir1) - def test_mkdir_func2(self): + def test_mkdir_func2(self) -> None: test = TestCmd.TestCmd(workdir='') test.subdir('sub') subdir1 = test.workpath('sub', 'dir1') @@ -84,7 +84,7 @@ class DefaultsTestCase(unittest.TestCase): else: self.fail("expected OSError") - def test__defines_no_target_or_source_arg(self): + def test__defines_no_target_or_source_arg(self) -> None: """ Verify that _defines() function can handle either or neither source or target being specified @@ -106,7 +106,7 @@ class DefaultsTestCase(unittest.TestCase): z = _defines('-D', ['AAB', 'BAB', 'CAB'], 'XYZAB', env, 'XYZ', 'abc') self.assertEqual(z, ['-DAABXYZAB', '-DBABXYZAB', '-DCABXYZAB']) - def test_processDefines(self): + def test_processDefines(self) -> None: """Verify correct handling in processDefines.""" env = DummyEnvironment() diff --git a/SCons/Environment.py b/SCons/Environment.py index bd94832a1..b074af77d 100644 --- a/SCons/Environment.py +++ b/SCons/Environment.py @@ -87,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( @@ -99,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: @@ -145,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) @@ -167,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() @@ -305,7 +305,7 @@ def _add_cppdefines( elif is_Tuple(defines): if len(defines) > 2: raise SCons.Errors.UserError( - f"Invalid tuple in CPPDEFINES: {define!r}, must be a two-tuple" + f"Invalid tuple in CPPDEFINES: {defines!r}, must be a two-tuple" ) env_dict[key] = deque([defines]) elif is_List(defines): @@ -438,10 +438,10 @@ class BuilderWrapper(MethodWrapper): source = [source] return super().__call__(target, source, *args, **kw) - def __repr__(self): + def __repr__(self) -> str: return '' % repr(self.name) - def __str__(self): + def __str__(self) -> str: return self.__repr__() def __getattr__(self, name): @@ -452,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': @@ -476,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. @@ -488,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: @@ -498,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) @@ -544,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') @@ -556,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 = {} @@ -577,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) @@ -614,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): @@ -682,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 @@ -699,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) @@ -708,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() @@ -799,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, @@ -808,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. @@ -873,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 @@ -887,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) @@ -1035,7 +1035,7 @@ 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. @@ -1166,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, @@ -1304,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. """ @@ -1373,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: @@ -1381,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 @@ -1425,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. @@ -1505,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 @@ -1528,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 @@ -1704,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: @@ -1764,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`` @@ -1790,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" @@ -1834,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. @@ -1902,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 @@ -1926,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 @@ -1969,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. """ @@ -2009,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] @@ -2159,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 @@ -2174,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) @@ -2341,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): @@ -2383,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) @@ -2406,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): @@ -2469,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()) @@ -2527,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: @@ -2551,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. @@ -2588,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'] @@ -2624,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, @@ -2646,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)) @@ -2675,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): @@ -2684,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: diff --git a/SCons/EnvironmentTests.py b/SCons/EnvironmentTests.py index 81143d5c0..e7cb99f34 100644 --- a/SCons/EnvironmentTests.py +++ b/SCons/EnvironmentTests.py @@ -91,16 +91,16 @@ class Builder(SCons.Builder.BuilderBase): """A dummy Builder class for testing purposes. "Building" a target is simply setting a value in the dictionary. """ - def __init__(self, name = None): + def __init__(self, name = None) -> None: self.name = name - def __call__(self, env, target=None, source=None, **kw): + def __call__(self, env, target=None, source=None, **kw) -> None: global called_it called_it['target'] = target called_it['source'] = source called_it.update(kw) - def execute(self, target = None, **kw): + def execute(self, target = None, **kw) -> None: global built_it built_it[target] = 1 @@ -112,11 +112,11 @@ class Scanner: """A dummy Scanner class for testing purposes. "Scanning" a target is simply setting a value in the dictionary. """ - def __init__(self, name, skeys=[]): + def __init__(self, name, skeys=[]) -> None: self.name = name self.skeys = skeys - def __call__(self, filename): + def __call__(self, filename) -> None: global scanned_it scanned_it[filename] = 1 @@ -129,21 +129,21 @@ class Scanner: def get_skeys(self, env): return self.skeys - def __str__(self): + def __str__(self) -> str: return self.name class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return self.name def rfile(self): return self def get_subst_proxy(self): return self -def test_tool( env ): +def test_tool( env ) -> None: env['_F77INCFLAGS'] = '${_concat(INCPREFIX, F77PATH, INCSUFFIX, __env__, RDirs, TARGET, SOURCE, affect_signature=False)}' class TestEnvironmentFixture: @@ -169,12 +169,12 @@ class TestEnvironmentFixture: class SubstitutionTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test initializing a SubstitutionEnvironment.""" env = SubstitutionEnvironment() assert '__env__' not in env - def test___cmp__(self): + def test___cmp__(self) -> None: """Test comparing SubstitutionEnvironments.""" env1 = SubstitutionEnvironment(XXX = 'x') env2 = SubstitutionEnvironment(XXX = 'x') @@ -185,38 +185,38 @@ class SubstitutionTestCase(unittest.TestCase): assert env1 != env3 assert env1 != env4 - def test___delitem__(self): + def test___delitem__(self) -> None: """Test deleting a variable from a SubstitutionEnvironment.""" env1 = SubstitutionEnvironment(XXX = 'x', YYY = 'y') env2 = SubstitutionEnvironment(XXX = 'x') del env1['YYY'] assert env1 == env2 - def test___getitem__(self): + def test___getitem__(self) -> None: """Test fetching a variable from a SubstitutionEnvironment.""" env = SubstitutionEnvironment(XXX = 'x') assert env['XXX'] == 'x', env['XXX'] - def test___setitem__(self): + def test___setitem__(self) -> None: """Test setting a variable in a SubstitutionEnvironment.""" env1 = SubstitutionEnvironment(XXX = 'x') env2 = SubstitutionEnvironment(XXX = 'x', YYY = 'y') env1['YYY'] = 'y' assert env1 == env2 - def test_get(self): + def test_get(self) -> None: """Test the SubstitutionEnvironment get() method.""" env = SubstitutionEnvironment(XXX = 'x') assert env.get('XXX') == 'x', env.get('XXX') assert env.get('YYY') is None, env.get('YYY') - def test_contains(self): + def test_contains(self) -> None: """Test the SubstitutionEnvironment __contains__() method.""" env = SubstitutionEnvironment(XXX = 'x') assert 'XXX' in env assert 'YYY' not in env - def test_keys(self): + def test_keys(self) -> None: """Test the SubstitutionEnvironment keys() method.""" testdata = {'XXX': 'x', 'YYY': 'y'} env = SubstitutionEnvironment(**testdata) @@ -225,7 +225,7 @@ class SubstitutionTestCase(unittest.TestCase): for k in testdata.keys(): assert k in keys, keys - def test_values(self): + def test_values(self) -> None: """Test the SubstitutionEnvironment values() method.""" testdata = {'XXX': 'x', 'YYY': 'y'} env = SubstitutionEnvironment(**testdata) @@ -234,7 +234,7 @@ class SubstitutionTestCase(unittest.TestCase): for v in testdata.values(): assert v in values, values - def test_items(self): + def test_items(self) -> None: """Test the SubstitutionEnvironment items() method.""" testdata = {'XXX': 'x', 'YYY': 'y'} env = SubstitutionEnvironment(**testdata) @@ -243,20 +243,20 @@ class SubstitutionTestCase(unittest.TestCase): for k, v in testdata.items(): assert (k, v) in items, items - def test_setdefault(self): + def test_setdefault(self) -> None: """Test the SubstitutionEnvironment setdefault() method.""" env = SubstitutionEnvironment(XXX = 'x') assert env.setdefault('XXX', 'z') == 'x', env['XXX'] assert env.setdefault('YYY', 'y') == 'y', env['YYY'] assert 'YYY' in env - def test_arg2nodes(self): + def test_arg2nodes(self) -> None: """Test the arg2nodes method.""" env = SubstitutionEnvironment() dict = {} class X(SCons.Node.Node): pass - def Factory(name, directory = None, create = 1, dict=dict, X=X): + def Factory(name, directory = None, create: int = 1, dict=dict, X=X): if name not in dict: dict[name] = X() dict[name].name = name @@ -360,7 +360,7 @@ class SubstitutionTestCase(unittest.TestCase): assert not hasattr(nodes[1], 'bbbb'), nodes[0] assert nodes[1].c == 1, nodes[1] - def test_arg2nodes_target_source(self): + def test_arg2nodes_target_source(self) -> None: """Test the arg2nodes method with target= and source= keywords """ targets = [DummyNode('t1'), DummyNode('t2')] @@ -376,19 +376,19 @@ class SubstitutionTestCase(unittest.TestCase): names = [n.name for n in nodes] assert names == ['t1-a', 's1-b', 't2-c', 's2-d'], names - def test_gvars(self): + def test_gvars(self) -> None: """Test the base class gvars() method""" env = SubstitutionEnvironment() gvars = env.gvars() assert gvars == {}, gvars - def test_lvars(self): + def test_lvars(self) -> None: """Test the base class lvars() method""" env = SubstitutionEnvironment() lvars = env.lvars() assert lvars == {}, lvars - def test_subst(self): + def test_subst(self) -> None: """Test substituting construction variables within strings Check various combinations, including recursive expansion @@ -447,7 +447,7 @@ class SubstitutionTestCase(unittest.TestCase): # This will take some serious surgery to subst() and # subst_list(), so just leave these tests out until we can # do that. - def bar(arg): + def bar(arg) -> None: pass env = SubstitutionEnvironment(BAR=bar, FOO='$BAR') @@ -458,7 +458,7 @@ class SubstitutionTestCase(unittest.TestCase): subst = env.subst('$FOO', call=None) assert subst is bar, subst - def test_subst_kw(self): + def test_subst_kw(self) -> None: """Test substituting construction variables within dictionaries""" env = SubstitutionEnvironment(AAA = 'a', BBB = 'b') kw = env.subst_kw({'$AAA' : 'aaa', 'bbb' : '$BBB'}) @@ -466,7 +466,7 @@ class SubstitutionTestCase(unittest.TestCase): assert kw['a'] == 'aaa', kw['a'] assert kw['bbb'] == 'b', kw['bbb'] - def test_subst_list(self): + def test_subst_list(self) -> None: """Test substituting construction variables in command lists """ env = SubstitutionEnvironment(AAA = 'a', BBB = 'b') @@ -516,7 +516,7 @@ class SubstitutionTestCase(unittest.TestCase): # This will take some serious surgery to subst() and # subst_list(), so just leave these tests out until we can # do that. - def bar(arg): + def bar(arg) -> None: pass env = SubstitutionEnvironment(BAR=bar, FOO='$BAR') @@ -527,21 +527,21 @@ class SubstitutionTestCase(unittest.TestCase): subst = env.subst_list('$FOO', call=None) assert subst is bar, subst - def test_subst_path(self): + def test_subst_path(self) -> None: """Test substituting a path list """ class MyProxy: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def get(self): return self.val + '-proxy' class MyNode: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def get_subst_proxy(self): return self - def __str__(self): + def __str__(self) -> str: return self.val class MyObj: @@ -577,9 +577,9 @@ class SubstitutionTestCase(unittest.TestCase): assert r == ['my1-proxy', 'my2-proxy', n], r class StringableObj: - def __init__(self, s): + def __init__(self, s) -> None: self.s = s - def __str__(self): + def __str__(self) -> str: return self.s env = SubstitutionEnvironment(FOO=StringableObj("foo"), @@ -594,13 +594,13 @@ class SubstitutionTestCase(unittest.TestCase): r = env.subst_path([ "bar/${FOO}/bar", "baz/${BAR}/baz" ]) assert r == [ "bar/foo/bar", "baz/bar/baz" ], r - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test the base environment subst_target_source() method""" env = SubstitutionEnvironment(AAA = 'a', BBB = 'b') mystr = env.subst_target_source("$AAA ${AAA}A $BBBB $BBB") assert mystr == "a aA b", mystr - def test_backtick(self): + def test_backtick(self) -> None: """Test the backtick() method for capturing command output""" env = SubstitutionEnvironment() @@ -665,7 +665,7 @@ sys.exit(0) finally: sys.stderr = save_stderr - def test_AddMethod(self): + def test_AddMethod(self) -> None: """Test the AddMethod() method""" env = SubstitutionEnvironment(FOO = 'foo') @@ -682,7 +682,7 @@ sys.exit(0) r = env.bar() assert r == 'func-foo', r - def func2(self, arg=''): + def func2(self, arg: str=''): return 'func2-' + self['FOO'] + arg env.AddMethod(func2) @@ -715,7 +715,7 @@ sys.exit(0) # Test that clones don't re-bind an attribute that the user set. env1 = Environment(FOO = '1') env1.AddMethod(func2) - def replace_func2(): + def replace_func2() -> str: return 'replace_func2' env1.func2 = replace_func2 env2 = env1.Clone(FOO = '2') @@ -734,7 +734,7 @@ sys.exit(0) assert r == 'func2-2', r - def test_Override(self): + def test_Override(self) -> None: """Test overriding construction variables""" env = SubstitutionEnvironment(ONE=1, TWO=2, THREE=3, FOUR=4) assert env['ONE'] == 1, env['ONE'] @@ -759,7 +759,7 @@ sys.exit(0) assert env2['ONE'] == "won", env2['ONE'] assert env['ONE'] == 1, env['ONE'] - def test_ParseFlags(self): + def test_ParseFlags(self) -> None: """Test the ParseFlags() method """ env = SubstitutionEnvironment() @@ -866,7 +866,7 @@ sys.exit(0) assert d['RPATH'] == ['rpath1', 'rpath2', 'rpath3'], d['RPATH'] - def test_MergeFlags(self): + def test_MergeFlags(self) -> None: """Test the MergeFlags() method.""" env = SubstitutionEnvironment() @@ -936,7 +936,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): 'UNCHANGED_TARGETS', ] - def test___init__(self): + def test___init__(self) -> None: """Test construction Environment creation Create two with identical arguments and check that @@ -949,16 +949,16 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert '__env__' not in env1 assert '__env__' not in env2 - def test_variables(self): + def test_variables(self) -> None: """Test that variables only get applied once.""" class FakeOptions: - def __init__(self, key, val): + def __init__(self, key, val) -> None: self.calls = 0 self.key = key self.val = val def keys(self): return [self.key] - def Update(self, env): + def Update(self, env) -> None: env[self.key] = self.val self.calls = self.calls + 1 @@ -967,7 +967,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert o.calls == 1, o.calls assert env['AAA'] == 'fake_opt', env['AAA'] - def test_get(self): + def test_get(self) -> None: """Test the get() method.""" env = self.TestEnvironment(aaa = 'AAA') @@ -980,7 +980,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): x = env.get('bbb', 'XXX') assert x == 'XXX', x - def test_Builder_calls(self): + def test_Builder_calls(self) -> None: """Test Builder calls through different environments """ global called_it @@ -1008,7 +1008,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): assert called_it['target'] is None, called_it assert called_it['source'] is None, called_it - def test_BuilderWrapper_attributes(self): + def test_BuilderWrapper_attributes(self) -> None: """Test getting and setting of BuilderWrapper attributes.""" b1 = Builder() b2 = Builder() @@ -1034,7 +1034,7 @@ class BaseTestCase(unittest.TestCase,TestEnvironmentFixture): # underlying method it tests (Environment.BuilderWrapper.execute()) # is necessary, but we're leaving the code here for now in case # that's mistaken. - def _DO_NOT_test_Builder_execs(self): + def _DO_NOT_test_Builder_execs(self) -> None: """Test Builder execution through different environments One environment is initialized with a single @@ -1083,7 +1083,7 @@ env4.builder1.env, env3) - def test_Scanners(self): + def test_Scanners(self) -> None: """Test setting SCANNERS in various ways One environment is initialized with a single @@ -1182,7 +1182,7 @@ env4.builder1.env, env3) s = list(map(env.get_scanner, suffixes)) assert s == [None, None, None, None, None], s - def test_ENV(self): + def test_ENV(self) -> None: """Test setting the external ENV in Environments """ env = Environment() @@ -1191,7 +1191,7 @@ env4.builder1.env, env3) env = self.TestEnvironment(ENV = { 'PATH' : '/foo:/bar' }) assert env.Dictionary('ENV')['PATH'] == '/foo:/bar' - def test_ReservedVariables(self): + def test_ReservedVariables(self) -> None: """Test warning generation when reserved variable names are set""" reserved_variables = [ @@ -1222,7 +1222,7 @@ env4.builder1.env, env3) finally: SCons.Warnings.warningAsException(old) - def test_FutureReservedVariables(self): + def test_FutureReservedVariables(self) -> None: """Test warning generation when future reserved variable names are set""" future_reserved_variables = [] @@ -1244,10 +1244,10 @@ env4.builder1.env, env3) finally: SCons.Warnings.warningAsException(old) - def test_IllegalVariables(self): + def test_IllegalVariables(self) -> None: """Test that use of illegal variables raises an exception""" env = Environment() - def test_it(var, env=env): + def test_it(var, env=env) -> None: exc_caught = None try: env[var] = 1 @@ -1260,7 +1260,7 @@ env4.builder1.env, env3) test_it('foo.bar') test_it('foo-bar') - def test_autogenerate(self): + def test_autogenerate(self) -> None: """Test autogenerating variables in a dictionary.""" drive, p = os.path.splitdrive(os.getcwd()) @@ -1349,13 +1349,13 @@ env4.builder1.env, env3) flags = list(map(normalize_if_path, flags)) assert flags == expect, flags - def test_platform(self): + def test_platform(self) -> None: """Test specifying a platform callable when instantiating.""" class platform: - def __str__(self): return "TestPlatform" - def __call__(self, env): env['XYZZY'] = 777 + def __str__(self) -> str: return "TestPlatform" + def __call__(self, env) -> None: env['XYZZY'] = 777 - def tool(env): + def tool(env) -> None: env['SET_TOOL'] = 'initialized' assert env['PLATFORM'] == "TestPlatform" @@ -1364,13 +1364,13 @@ env4.builder1.env, env3) assert env['PLATFORM'] == "TestPlatform" assert env['SET_TOOL'] == "initialized" - def test_Default_PLATFORM(self): + def test_Default_PLATFORM(self) -> None: """Test overriding the default PLATFORM variable""" class platform: - def __str__(self): return "DefaultTestPlatform" - def __call__(self, env): env['XYZZY'] = 888 + def __str__(self) -> str: return "DefaultTestPlatform" + def __call__(self, env) -> None: env['XYZZY'] = 888 - def tool(env): + def tool(env) -> None: env['SET_TOOL'] = 'abcde' assert env['PLATFORM'] == "DefaultTestPlatform" @@ -1388,15 +1388,15 @@ env4.builder1.env, env3) finally: SCons.Defaults.ConstructionEnvironment = save - def test_tools(self): + def test_tools(self) -> None: """Test specifying a tool callable when instantiating.""" - def t1(env): + def t1(env) -> None: env['TOOL1'] = 111 - def t2(env): + def t2(env) -> None: env['TOOL2'] = 222 - def t3(env): + def t3(env) -> None: env['AAA'] = env['XYZ'] - def t4(env): + def t4(env) -> None: env['TOOL4'] = 444 env = self.TestEnvironment(tools = [t1, t2, t3], XYZ = 'aaa') assert env['TOOL1'] == 111, env['TOOL1'] @@ -1421,15 +1421,15 @@ def exists(env): assert env['b'] == 2, env['b'] assert env['c'] == 3, env['c'] - def test_Default_TOOLS(self): + def test_Default_TOOLS(self) -> None: """Test overriding the default TOOLS variable""" - def t5(env): + def t5(env) -> None: env['TOOL5'] = 555 - def t6(env): + def t6(env) -> None: env['TOOL6'] = 666 - def t7(env): + def t7(env) -> None: env['BBB'] = env['XYZ'] - def t8(env): + def t8(env) -> None: env['TOOL8'] = 888 import SCons.Defaults @@ -1447,11 +1447,11 @@ def exists(env): finally: SCons.Defaults.ConstructionEnvironment = save - def test_null_tools(self): + def test_null_tools(self) -> None: """Test specifying a tool of None is OK.""" - def t1(env): + def t1(env) -> None: env['TOOL1'] = 111 - def t2(env): + def t2(env) -> None: env['TOOL2'] = 222 env = self.TestEnvironment(tools = [t1, None, t2], XYZ = 'aaa') assert env['TOOL1'] == 111, env['TOOL1'] @@ -1464,10 +1464,10 @@ def exists(env): assert env['TOOL2'] == 222, env assert env['XYZ'] == 'ddd', env - def test_default_copy_cache(self): + def test_default_copy_cache(self) -> None: copied = False - def copy2(self, src, dst): + def copy2(self, src, dst) -> None: nonlocal copied copied = True @@ -1489,7 +1489,7 @@ def exists(env): SCons.CacheDir.CacheDir.copy_from_cache = save_copy_from_cache SCons.CacheDir.CacheDir.copy_to_cache = save_copy_to_cache - def test_concat(self): + def test_concat(self) -> None: """Test _concat()""" e1 = self.TestEnvironment(PRE='pre', SUF='suf', STR='a b', LIST=['a', 'b']) s = e1.subst @@ -1507,7 +1507,7 @@ def exists(env): assert x == '$( preasuf prebsuf $)', x - def test_concat_nested(self): + def test_concat_nested(self) -> None: """Test _concat() on a nested substitution strings.""" e = self.TestEnvironment(PRE='pre', SUF='suf', L1=['a', 'b'], @@ -1522,7 +1522,7 @@ def exists(env): x = e.subst('$( ${_concat(PRE, L1, SUF, __env__)} $)') assert x == 'preasuf prebsuf precsuf predsuf precsuf predsuf', x - def test_gvars(self): + def test_gvars(self) -> None: """Test the Environment gvars() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y', ZZZ = 'z') gvars = env.gvars() @@ -1530,7 +1530,7 @@ def exists(env): assert gvars['YYY'] == 'y', gvars['YYY'] assert gvars['ZZZ'] == 'z', gvars['ZZZ'] - def test__update(self): + def test__update(self) -> None: """Test the _update() method""" env = self.TestEnvironment(X = 'x', Y = 'y', Z = 'z') assert env['X'] == 'x', env['X'] @@ -1550,7 +1550,7 @@ def exists(env): assert env['SOURCE'] == 's', env['SOURCE'] assert env['SOURCES'] == 'sss', env['SOURCES'] - def test_Append(self): + def test_Append(self) -> None: """Test appending to construction variables in an Environment """ @@ -1679,9 +1679,9 @@ def exists(env): assert result == ['foo', 'bar'], result class C: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return self.name def __eq__(self, other): raise Exception("should not compare") @@ -1708,7 +1708,7 @@ def exists(env): assert hasattr(env4, 'z1') assert hasattr(env4, 'z2') - def test_AppendENVPath(self): + def test_AppendENVPath(self) -> None: """Test appending to an ENV path.""" env1 = self.TestEnvironment( ENV={'PATH': r'C:\dir\num\one;C:\dir\num\two'}, @@ -1738,7 +1738,7 @@ def exists(env): env1.AppendENVPath('PATH', env1.fs.Dir('sub2'), sep=';') assert env1['ENV']['PATH'] == p + ';sub1;sub2', env1['ENV']['PATH'] - def test_AppendUnique(self): + def test_AppendUnique(self) -> None: """Test appending to unique values to construction variables This strips values that are already present when lists are @@ -1815,7 +1815,7 @@ def exists(env): assert isinstance(result, CLVar), repr(result) assert result == ['bar'], result - def test_Clone(self): + def test_Clone(self) -> None: """Test construction environment cloning. The clone should compare equal if there are no overrides. @@ -1900,13 +1900,13 @@ def exists(env): # Ensure that specifying new tools in a copied environment works. with self.subTest(): - def foo(env): + def foo(env) -> None: env['FOO'] = 1 - def bar(env): + def bar(env) -> None: env['BAR'] = 2 - def baz(env): + def baz(env) -> None: env['BAZ'] = 3 env1 = self.TestEnvironment(tools=[foo]) @@ -1989,7 +1989,7 @@ def generate(env): with self.subTest(): real_value = [4] - def my_tool(env, rv=real_value): + def my_tool(env, rv=real_value) -> None: assert env['KEY_THAT_I_WANT'] == rv[0] env['KEY_THAT_I_WANT'] = rv[0] + 1 @@ -2010,7 +2010,7 @@ def generate(env): assert ('BUILDERS' in env) is False env2 = env.Clone() - def test_Detect(self): + def test_Detect(self) -> None: """Test Detect()ing tools""" test = TestCmd.TestCmd(workdir = '') test.subdir('sub1', 'sub2') @@ -2065,7 +2065,7 @@ def generate(env): x = env.Detect('xxx.exe') assert x is None, x - def test_Dictionary(self): + def test_Dictionary(self) -> None: """Test retrieval of known construction variables Fetch them from the Dictionary and check for well-known @@ -2089,7 +2089,7 @@ def generate(env): del env['XXX'] assert 'XXX' not in env.Dictionary() - def test_FindIxes(self): + def test_FindIxes(self) -> None: """Test FindIxes()""" env = self.TestEnvironment(LIBPREFIX='lib', LIBSUFFIX='.a', @@ -2111,7 +2111,7 @@ def generate(env): assert None is env.FindIxes(paths, 'SHLIBPREFIX', 'SHLIBSUFFIX') assert paths[1] == env.FindIxes(paths, 'PREFIX', 'SUFFIX') - def test_ParseConfig(self): + def test_ParseConfig(self) -> None: """Test the ParseConfig() method""" env = self.TestEnvironment(COMMAND='command', ASFLAGS='assembler', @@ -2132,7 +2132,7 @@ def generate(env): Just returns the string it was given. """ - def __init__(self, save_command, output): + def __init__(self, save_command, output) -> None: self.save_command = save_command self.output = output def __call__(self, command): @@ -2198,7 +2198,7 @@ def generate(env): # check that we can pass our own function, # and that it works for both values of unique - def my_function(myenv, flags, unique=True): + def my_function(myenv, flags, unique: bool=True) -> None: import json args = json.loads(flags) @@ -2221,7 +2221,7 @@ def generate(env): assert env2['LIBS'] == ['xxx', 'yyy', 'xxx', 'yyy'], env2['LIBS'] - def test_ParseDepends(self): + def test_ParseDepends(self) -> None: """Test the ParseDepends() method""" test = TestCmd.TestCmd(workdir = '') @@ -2250,7 +2250,7 @@ f5: \ tlist = [] dlist = [] - def my_depends(target, dependency, tlist=tlist, dlist=dlist): + def my_depends(target, dependency, tlist=tlist, dlist=dlist) -> None: tlist.extend(target) dlist.extend(dependency) @@ -2290,7 +2290,7 @@ f5: \ exc_caught = 1 assert exc_caught, "did not catch expected UserError" - def test_Platform(self): + def test_Platform(self) -> None: """Test the Platform() method""" env = self.TestEnvironment(WIN32='win32', NONE='no-such-platform') @@ -2314,7 +2314,7 @@ f5: \ env.Platform('$WIN32') assert env['OBJSUFFIX'] == '.obj', env['OBJSUFFIX'] - def test_Prepend(self): + def test_Prepend(self) -> None: """Test prepending to construction variables in an Environment """ cases = [ @@ -2450,7 +2450,7 @@ f5: \ assert hasattr(env4, 'z1') assert hasattr(env4, 'z2') - def test_PrependENVPath(self): + def test_PrependENVPath(self) -> None: """Test prepending to an ENV path.""" env1 = self.TestEnvironment( ENV={'PATH': r'C:\dir\num\one;C:\dir\num\two'}, @@ -2480,7 +2480,7 @@ f5: \ env1.PrependENVPath('PATH', env1.fs.Dir('sub2'), sep=';') assert env1['ENV']['PATH'] == 'sub2;sub1;' + p, env1['ENV']['PATH'] - def test_PrependUnique(self): + def test_PrependUnique(self) -> None: """Test prepending unique values to construction variables This strips values that are already present when lists are @@ -2551,7 +2551,7 @@ f5: \ assert isinstance(result, CLVar), repr(result) assert result == ['bar'], result - def test_Replace(self): + def test_Replace(self) -> None: """Test replacing construction variables in an Environment After creation of the Environment, of course. @@ -2570,7 +2570,7 @@ f5: \ assert not hasattr(env3, 'b1'), "b1 was not cleared" assert hasattr(env3, 'b2'), "b2 was not set" - def test_ReplaceIxes(self): + def test_ReplaceIxes(self) -> None: """Test ReplaceIxes()""" env = self.TestEnvironment(LIBPREFIX='lib', LIBSUFFIX='.a', @@ -2591,7 +2591,7 @@ f5: \ 'PREFIX', 'SUFFIX', 'LIBPREFIX', 'LIBSUFFIX') - def test_SetDefault(self): + def test_SetDefault(self) -> None: """Test the SetDefault method""" env = self.TestEnvironment(tools = []) env.SetDefault(V1 = 1) @@ -2601,7 +2601,7 @@ f5: \ env.SetDefault(V2 = 1) assert env['V2'] == 2 - def test_Tool(self): + def test_Tool(self) -> None: """Test the Tool() method""" env = self.TestEnvironment(LINK='link', NONE='no-such-tool') @@ -2652,7 +2652,7 @@ def generate(env): env.Tool('yyy') assert env['YYY'] == 'two', env['YYY'] - def test_WhereIs(self): + def test_WhereIs(self) -> None: """Test the WhereIs() method""" test = TestCmd.TestCmd(workdir = '') @@ -2731,7 +2731,7 @@ def generate(env): - def test_Action(self): + def test_Action(self) -> None: """Test the Action() method""" import SCons.Action @@ -2753,13 +2753,13 @@ def generate(env): assert a, a assert a.__class__ is SCons.Action.ListAction, a.__class__ - def func(arg): + def func(arg) -> None: pass a = env.Action(func) assert a, a assert a.__class__ is SCons.Action.FunctionAction, a.__class__ - def test_AddPostAction(self): + def test_AddPostAction(self) -> None: """Test the AddPostAction() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') @@ -2770,7 +2770,7 @@ def generate(env): assert str(n[0]) == 'ggg', n[0] assert str(n[1]) == 'bbb', n[1] - def test_AddPreAction(self): + def test_AddPreAction(self) -> None: """Test the AddPreAction() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') @@ -2781,7 +2781,7 @@ def generate(env): assert str(n[0]) == 'ggg', n[0] assert str(n[1]) == 'bbb', n[1] - def test_Alias(self): + def test_Alias(self) -> None: """Test the Alias() method""" env = self.TestEnvironment(FOO='kkk', BAR='lll', EA='export_alias') @@ -2843,7 +2843,7 @@ def generate(env): s = str(tgt.builder.action) assert s == "action1\naction2\naction3", s - def test_AlwaysBuild(self): + def test_AlwaysBuild(self) -> None: """Test the AlwaysBuild() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') t = env.AlwaysBuild('a', 'b$FOO', ['c', 'd'], '$BAR', @@ -2870,12 +2870,12 @@ def generate(env): assert t[6].get_internal_path() == 'file' assert t[6].always_build - def test_VariantDir(self): + def test_VariantDir(self) -> None: """Test the VariantDir() method""" class MyFS: def Dir(self, name): return name - def VariantDir(self, variant_dir, src_dir, duplicate): + def VariantDir(self, variant_dir, src_dir, duplicate) -> None: self.variant_dir = variant_dir self.src_dir = src_dir self.duplicate = duplicate @@ -2893,7 +2893,7 @@ def generate(env): assert env.fs.src_dir == 'bbbsrc', env.fs.src_dir assert env.fs.duplicate == 0, env.fs.duplicate - def test_Builder(self): + def test_Builder(self) -> None: """Test the Builder() method""" env = self.TestEnvironment(FOO = 'xyzzy') @@ -2906,14 +2906,14 @@ def generate(env): b = env.Builder(action = ['$FOO', 'foo']) assert b is not None, b - def func(arg): + def func(arg) -> None: pass b = env.Builder(action = func) assert b is not None, b b = env.Builder(generator = func) assert b is not None, b - def test_CacheDir(self): + def test_CacheDir(self) -> None: """Test the CacheDir() method""" test = TestCmd.TestCmd(workdir = '') @@ -2943,7 +2943,7 @@ def generate(env): assert not os.path.isfile(test_foo1_config), "No file %s"%test_foo1_config - def test_Clean(self): + def test_Clean(self) -> None: """Test the Clean() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') @@ -2969,7 +2969,7 @@ def generate(env): l = list(map(str, CT[fff])) assert l == ['ddd', 'eee', 'fff'], l - def test_Command(self): + def test_Command(self) -> None: """Test the Command() method.""" env = Environment() t = env.Command(target='foo.out', source=['foo1.in', 'foo2.in'], @@ -2985,7 +2985,7 @@ def generate(env): action='buildbar $target $source')[0] assert 'sub' in [x.get_internal_path() for x in t.sources] - def testFunc(env, target, source): + def testFunc(env, target, source) -> int: assert str(target[0]) == 'foo.out' srcs = list(map(str, source)) assert 'foo1.in' in srcs and 'foo2.in' in srcs, srcs @@ -3002,7 +3002,7 @@ def generate(env): assert 'foo2.in' in [x.get_internal_path() for x in t.sources] x = [] - def test2(baz, x=x): + def test2(baz, x=x) -> None: x.append(baz) env = self.TestEnvironment(TEST2 = test2) t = env.Command(target='baz.out', source='baz.in', @@ -3024,7 +3024,7 @@ def generate(env): source_scanner = 'fake')[0] assert t.builder.source_scanner == 'fake', t.builder.source_scanner - def test_Configure(self): + def test_Configure(self) -> None: """Test the Configure() method""" # Configure() will write to a local temporary file. test = TestCmd.TestCmd(workdir = '') @@ -3035,7 +3035,7 @@ def generate(env): env = self.TestEnvironment(FOO = 'xyzzy') - def func(arg): + def func(arg) -> None: pass c = env.Configure() @@ -3050,7 +3050,7 @@ def generate(env): finally: os.chdir(save) - def test_Depends(self): + def test_Depends(self) -> None: """Test the explicit Depends method.""" env = self.TestEnvironment(FOO = 'xxx', BAR='yyy') env.Dir('dir1') @@ -3082,10 +3082,10 @@ def generate(env): assert d.__class__.__name__ == 'Dir', d.__class__.__name__ assert d.get_internal_path() == 'dir2' - def test_Dir(self): + def test_Dir(self) -> None: """Test the Dir() method""" class MyFS: - def Dir(self, name): + def Dir(self, name) -> str: return 'Dir(%s)' % name env = self.TestEnvironment(FOO = 'foodir', BAR = 'bardir') @@ -3106,7 +3106,7 @@ def generate(env): d = env.Dir(['dir1', 'dir2']) assert d == ['Dir(dir1)', 'Dir(dir2)'], d - def test_NoClean(self): + def test_NoClean(self) -> None: """Test the NoClean() method""" env = self.TestEnvironment(FOO='ggg', BAR='hhh') env.Dir('p_hhhb') @@ -3129,7 +3129,7 @@ def generate(env): assert t[4].get_internal_path() == 'p_ggg' assert t[4].noclean - def test_Dump(self): + def test_Dump(self) -> None: """Test the Dump() method""" env = self.TestEnvironment(FOO = 'foo') @@ -3148,7 +3148,7 @@ def generate(env): else: self.fail("Did not catch expected ValueError.") - def test_Environment(self): + def test_Environment(self) -> None: """Test the Environment() method""" env = self.TestEnvironment(FOO = 'xxx', BAR = 'yyy') @@ -3156,13 +3156,13 @@ def generate(env): assert e2['X'] == 'xxx', e2['X'] assert e2['Y'] == 'yyy', e2['Y'] - def test_Execute(self): + def test_Execute(self) -> None: """Test the Execute() method""" class MyAction: - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: self.args = args - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> str: return "%s executed" % self.args env = Environment() @@ -3171,10 +3171,10 @@ def generate(env): result = env.Execute("foo") assert result == "foo executed", result - def test_Entry(self): + def test_Entry(self) -> None: """Test the Entry() method""" class MyFS: - def Entry(self, name): + def Entry(self, name) -> str: return 'Entry(%s)' % name env = self.TestEnvironment(FOO = 'fooentry', BAR = 'barentry') @@ -3195,10 +3195,10 @@ def generate(env): e = env.Entry(['entry1', 'entry2']) assert e == ['Entry(entry1)', 'Entry(entry2)'], e - def test_File(self): + def test_File(self) -> None: """Test the File() method""" class MyFS: - def File(self, name): + def File(self, name) -> str: return 'File(%s)' % name env = self.TestEnvironment(FOO = 'foofile', BAR = 'barfile') @@ -3219,7 +3219,7 @@ def generate(env): f = env.File(['file1', 'file2']) assert f == ['File(file1)', 'File(file2)'], f - def test_FindFile(self): + def test_FindFile(self) -> None: """Test the FindFile() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') @@ -3228,7 +3228,7 @@ def generate(env): # XXX - def test_Flatten(self): + def test_Flatten(self) -> None: """Test the Flatten() method""" env = Environment() l = env.Flatten([1]) @@ -3236,7 +3236,7 @@ def generate(env): l = env.Flatten([1, [2, [3, [4]]]]) assert l == [1, 2, 3, 4], l - def test_GetBuildPath(self): + def test_GetBuildPath(self) -> None: """Test the GetBuildPath() method.""" env = self.TestEnvironment(MAGIC = 'xyzzy') @@ -3246,7 +3246,7 @@ def generate(env): p = env.GetBuildPath('$MAGIC') assert p == 'xyzzy', p - def test_Ignore(self): + def test_Ignore(self) -> None: """Test the explicit Ignore method.""" env = self.TestEnvironment(FOO='yyy', BAR='zzz') env.Dir('dir1') @@ -3278,7 +3278,7 @@ def generate(env): assert i.__class__.__name__ == 'Dir', i.__class__.__name__ assert i.get_internal_path() == 'dir2' - def test_Literal(self): + def test_Literal(self) -> None: """Test the Literal() method""" env = self.TestEnvironment(FOO='fff', BAR='bbb') list = env.subst_list([env.Literal('$FOO'), '$BAR'])[0] @@ -3286,7 +3286,7 @@ def generate(env): list = env.subst_list(['$FOO', env.Literal('$BAR')])[0] assert list == ['fff', '$BAR'], list - def test_Local(self): + def test_Local(self) -> None: """Test the Local() method.""" env = self.TestEnvironment(FOO='lll') @@ -3297,7 +3297,7 @@ def generate(env): assert str(l[0]) == 'ggg', l[0] assert str(l[1]) == 'lll', l[1] - def test_Precious(self): + def test_Precious(self) -> None: """Test the Precious() method""" env = self.TestEnvironment(FOO='ggg', BAR='hhh') env.Dir('p_hhhb') @@ -3320,7 +3320,7 @@ def generate(env): assert t[4].get_internal_path() == 'p_ggg' assert t[4].precious - def test_Pseudo(self): + def test_Pseudo(self) -> None: """Test the Pseudo() method""" env = self.TestEnvironment(FOO='ggg', BAR='hhh') env.Dir('p_hhhb') @@ -3343,12 +3343,12 @@ def generate(env): assert t[4].get_internal_path() == 'p_ggg' assert t[4].pseudo - def test_Repository(self): + def test_Repository(self) -> None: """Test the Repository() method.""" class MyFS: - def __init__(self): + def __init__(self) -> None: self.list = [] - def Repository(self, *dirs): + def Repository(self, *dirs) -> None: self.list.extend(list(dirs)) def Dir(self, name): return name @@ -3359,9 +3359,9 @@ def generate(env): expect = ['/tmp/foo', '/tmp/rrr', '/tmp/sss/foo'] assert env.fs.list == expect, env.fs.list - def test_Scanner(self): + def test_Scanner(self) -> None: """Test the Scanner() method""" - def scan(node, env, target, arg): + def scan(node, env, target, arg) -> None: pass env = self.TestEnvironment(FOO = scan) @@ -3379,7 +3379,7 @@ def generate(env): s = env.Scanner(function = '$FOO') assert s is not None, s - def test_SConsignFile(self): + def test_SConsignFile(self) -> None: """Test the SConsignFile() method""" import SCons.SConsign @@ -3394,7 +3394,7 @@ def generate(env): try: fnames = [] dbms = [] - def capture(name, dbm_module, fnames=fnames, dbms=dbms): + def capture(name, dbm_module, fnames=fnames, dbms=dbms) -> None: fnames.append(name) dbms.append(dbm_module) @@ -3435,7 +3435,7 @@ def generate(env): finally: SCons.SConsign.File = save_SConsign_File - def test_SideEffect(self): + def test_SideEffect(self) -> None: """Test the SideEffect() method""" env = self.TestEnvironment(LIB='lll', FOO='fff', BAR='bbb') env.File('mylll.pdb') @@ -3480,7 +3480,7 @@ def generate(env): assert len(s) == 0, len(s) assert len(ggg.side_effects) == before, len(ggg.side_effects) - def test_Split(self): + def test_Split(self) -> None: """Test the Split() method""" env = self.TestEnvironment(FOO = 'fff', BAR = 'bbb') s = env.Split("foo bar") @@ -3497,7 +3497,7 @@ def generate(env): assert s == ["fffbbb"], s - def test_Value(self): + def test_Value(self) -> None: """Test creating a Value() object """ env = Environment() @@ -3519,7 +3519,7 @@ def generate(env): assert v4.name == 'name', v4.name - def test_Environment_global_variable(self): + def test_Environment_global_variable(self) -> None: """Test setting Environment variable to an Environment.Base subclass""" class MyEnv(SCons.Environment.Base): def xxx(self, string): @@ -3535,7 +3535,7 @@ def generate(env): f = env.xxx('$FOO') assert f == 'foo', f - def test_bad_keywords(self): + def test_bad_keywords(self) -> None: """Test trying to use reserved keywords in an Environment""" added = [] @@ -3658,7 +3658,7 @@ def generate(env): for x in added + ['OVERRIDE']: assert x in over, bad_msg % x - def test_parse_flags(self): + def test_parse_flags(self) -> None: """Test the Base class parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = Environment(tools=[], parse_flags = '-X') @@ -3672,7 +3672,7 @@ def generate(env): assert env['CCFLAGS'] == ['-X'], env['CCFLAGS'] self.assertEqual(list(env['CPPDEFINES']), ['FOO', 'BAR']) - def test_clone_parse_flags(self): + def test_clone_parse_flags(self) -> None: """Test the env.Clone() parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = Environment(tools = []) @@ -3697,10 +3697,10 @@ def generate(env): class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): - def setUp(self): + def setUp(self) -> None: env = Environment() env._dict = {'XXX' : 'x', 'YYY' : 'y'} - def verify_value(env, key, value, *args, **kwargs): + def verify_value(env, key, value, *args, **kwargs) -> None: """Verifies that key is value on the env this is called with.""" assert env[key] == value env.AddMethod(verify_value) @@ -3711,7 +3711,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): def checkpath(self, node, expect): return str(node) == os.path.normpath(expect) - def test___init__(self): + def test___init__(self) -> None: """Test OverrideEnvironment initialization""" env, env2, env3 = self.envs assert env['XXX'] == 'x', env['XXX'] @@ -3721,7 +3721,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert env2['YYY'] == 'y', env2['YYY'] assert env3['YYY'] == 'y3', env3['YYY'] - def test___delitem__(self): + def test___delitem__(self) -> None: """Test deleting variables from an OverrideEnvironment""" env, env2, env3 = self.envs @@ -3740,7 +3740,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'ZZZ' not in env2, "env2 has ZZZ?" assert 'ZZZ' not in env3, "env3 has ZZZ?" - def test_get(self): + def test_get(self) -> None: """Test the OverrideEnvironment get() method""" env, env2, env3 = self.envs assert env.get('XXX') == 'x', env.get('XXX') @@ -3753,7 +3753,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert env2.get('ZZZ') is None, env2.get('ZZZ') assert env3.get('ZZZ') == 'z3', env3.get('ZZZ') - def test_contains(self): + def test_contains(self) -> None: """Test the OverrideEnvironment __contains__() method""" env, env2, env3 = self.envs assert 'XXX' in env, 'XXX' in env @@ -3766,7 +3766,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'ZZZ' not in env2, 'ZZZ' in env2 assert 'ZZZ' in env3, 'ZZZ' in env3 - def test_Dictionary(self): + def test_Dictionary(self) -> None: """Test the OverrideEnvironment Dictionary() method""" env, env2, env3 = self.envs # nothing overrriden @@ -3788,7 +3788,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): assert 'XXX' not in env2.Dictionary() assert 'XXX' not in env.Dictionary() - def test_items(self): + def test_items(self) -> None: """Test the OverrideEnvironment items() method""" env, env2, env3 = self.envs items = sorted(env.items()) @@ -3798,7 +3798,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): items = sorted(env3.items()) assert items == [('XXX', 'x3'), ('YYY', 'y3'), ('ZZZ', 'z3')], items - def test_keys(self): + def test_keys(self) -> None: """Test the OverrideEnvironment keys() method""" env, env2, env3 = self.envs keys = sorted(env.keys()) @@ -3808,7 +3808,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): keys = sorted(env3.keys()) assert keys == ['XXX', 'YYY', 'ZZZ'], keys - def test_values(self): + def test_values(self) -> None: """Test the OverrideEnvironment values() method""" env, env2, env3 = self.envs values = sorted(env.values()) @@ -3818,7 +3818,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): values = sorted(env3.values()) assert values == ['x3', 'y3', 'z3'], values - def test_setdefault(self): + def test_setdefault(self) -> None: """Test the OverrideEnvironment setdefault() method.""" env, env2, env3 = self.envs # does not set for existing key @@ -3828,7 +3828,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # set did not leak through to base env assert 'ZZZ' not in env - def test_gvars(self): + def test_gvars(self) -> None: """Test the OverrideEnvironment gvars() method""" env, env2, env3 = self.envs gvars = env.gvars() @@ -3838,7 +3838,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): gvars = env3.gvars() assert gvars == {'XXX' : 'x', 'YYY' : 'y'}, gvars - def test_lvars(self): + def test_lvars(self) -> None: """Test the OverrideEnvironment lvars() method""" env, env2, env3 = self.envs lvars = env.lvars() @@ -3848,7 +3848,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): lvars = env3.lvars() assert lvars == {'XXX' : 'x3', 'YYY' : 'y3', 'ZZZ' : 'z3'}, lvars - def test_Replace(self): + def test_Replace(self) -> None: """Test the OverrideEnvironment Replace() method""" env, env2, env3 = self.envs assert env['XXX'] == 'x', env['XXX'] @@ -3895,7 +3895,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # """Test the OverrideEnvironment Clone() method""" # pass - def test_FindIxes(self): + def test_FindIxes(self) -> None: """Test the OverrideEnvironment FindIxes() method""" env, env2, env3 = self.envs x = env.FindIxes(['xaaay'], 'XXX', 'YYY') @@ -3905,7 +3905,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.FindIxes(['x3aaay3'], 'XXX', 'YYY') assert x == 'x3aaay3', x - def test_ReplaceIxes(self): + def test_ReplaceIxes(self) -> None: """Test the OverrideEnvironment ReplaceIxes() method""" env, env2, env3 = self.envs x = env.ReplaceIxes('xaaay', 'XXX', 'YYY', 'YYY', 'XXX') @@ -3921,14 +3921,14 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): # """Test the OverrideEnvironment WhereIs() method""" # pass - def test_PseudoBuilderInherits(self): + def test_PseudoBuilderInherits(self) -> None: """Test that pseudo-builders inherit the overrided values.""" env, env2, env3 = self.envs env.verify_value('XXX', 'x') env2.verify_value('XXX', 'x2') env3.verify_value('XXX', 'x3') - def test_Dir(self): + def test_Dir(self) -> None: """Test the OverrideEnvironment Dir() method""" env, env2, env3 = self.envs x = env.Dir('ddir/$XXX') @@ -3938,7 +3938,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.Dir('ddir/$XXX') assert self.checkpath(x, 'ddir/x3'), str(x) - def test_Entry(self): + def test_Entry(self) -> None: """Test the OverrideEnvironment Entry() method""" env, env2, env3 = self.envs x = env.Entry('edir/$XXX') @@ -3948,7 +3948,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.Entry('edir/$XXX') assert self.checkpath(x, 'edir/x3'), str(x) - def test_File(self): + def test_File(self) -> None: """Test the OverrideEnvironment File() method""" env, env2, env3 = self.envs x = env.File('fdir/$XXX') @@ -3958,7 +3958,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.File('fdir/$XXX') assert self.checkpath(x, 'fdir/x3'), str(x) - def test_Split(self): + def test_Split(self) -> None: """Test the OverrideEnvironment Split() method""" env, env2, env3 = self.envs env['AAA'] = '$XXX $YYY $ZZZ' @@ -3969,7 +3969,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): x = env3.Split('$AAA') assert x == ['x3', 'y3', 'z3'], x - def test_parse_flags(self): + def test_parse_flags(self) -> None: """Test the OverrideEnvironment parse_flags argument""" # all we have to show is that it gets to MergeFlags internally env = SubstitutionEnvironment() @@ -3996,7 +3996,7 @@ class OverrideEnvironmentTestCase(unittest.TestCase,TestEnvironmentFixture): class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): - def test___init__(self): + def test___init__(self) -> None: """Test NoSubstitutionProxy initialization""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4006,7 +4006,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): assert proxy['XXX'] == 'x', proxy['XXX'] assert proxy['YYY'] == 'y', proxy['YYY'] - def test_attributes(self): + def test_attributes(self) -> None: """Test getting and setting NoSubstitutionProxy attributes""" env = Environment() setattr(env, 'env_attr', 'value1') @@ -4024,7 +4024,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): x = getattr(proxy, 'proxy_attr') assert x == 'value2', x - def test_subst(self): + def test_subst(self) -> None: """Test the NoSubstitutionProxy.subst() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4044,7 +4044,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): extra_meaningless_keyword_argument=None) assert x == '$YYY', x - def test_subst_kw(self): + def test_subst_kw(self) -> None: """Test the NoSubstitutionProxy.subst_kw() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4059,7 +4059,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): x = proxy.subst_kw({'$XXX':'$YYY'}) assert x == {'$XXX':'$YYY'}, x - def test_subst_list(self): + def test_subst_list(self) -> None: """Test the NoSubstitutionProxy.subst_list() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4077,7 +4077,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): x = proxy.subst_list('$YYY', raw=0, target=None, source=None, conv=None) assert x == [[]], x - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test the NoSubstitutionProxy.subst_target_source() method""" env = self.TestEnvironment(XXX = 'x', YYY = 'y') assert env['XXX'] == 'x', env['XXX'] @@ -4096,7 +4096,7 @@ class NoSubstitutionProxyTestCase(unittest.TestCase,TestEnvironmentFixture): class EnvironmentVariableTestCase(unittest.TestCase): - def test_is_valid_construction_var(self): + def test_is_valid_construction_var(self) -> None: """Testing is_valid_construction_var()""" r = is_valid_construction_var("_a") assert r is not None, r diff --git a/SCons/EnvironmentValues.py b/SCons/EnvironmentValues.py index c5eb972c2..51368c915 100644 --- a/SCons/EnvironmentValues.py +++ b/SCons/EnvironmentValues.py @@ -72,7 +72,7 @@ class EnvironmentValue: Hold a single value. We're going to cache parsed version of the file We're going to keep track of variables which feed into this values evaluation """ - def __init__(self, value): + def __init__(self, value) -> None: self.value = value self.var_type = ValueTypes.UNKNOWN @@ -82,7 +82,7 @@ class EnvironmentValue: self.parse_value() - def parse_value(self): + def parse_value(self) -> None: """ Scan the string and break into component values """ @@ -99,7 +99,7 @@ class EnvironmentValue: # likely callable? either way we don't parse self._parsed = self.value - def parse_trial(self): + def parse_trial(self) -> None: """ Try alternate parsing methods. :return: @@ -113,7 +113,7 @@ class EnvironmentValues: """ A class to hold all the environment variables """ - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {} for k in kw: self._dict[k] = EnvironmentValue(kw[k]) diff --git a/SCons/EnvironmentValuesTest.py b/SCons/EnvironmentValuesTest.py index 074aa85ca..25d8804d1 100644 --- a/SCons/EnvironmentValuesTest.py +++ b/SCons/EnvironmentValuesTest.py @@ -26,7 +26,7 @@ import unittest from SCons.EnvironmentValues import EnvironmentValues class MyTestCase(unittest.TestCase): - def test_simple_environmentValues(self): + def test_simple_environmentValues(self) -> None: """Test comparing SubstitutionEnvironments """ diff --git a/SCons/Errors.py b/SCons/Errors.py index d37cb6de4..b40ba0e74 100644 --- a/SCons/Errors.py +++ b/SCons/Errors.py @@ -71,9 +71,9 @@ class BuildError(Exception): """ def __init__(self, - node=None, errstr="Unknown error", status=2, exitstatus=2, + node=None, errstr: str="Unknown error", status: int=2, exitstatus: int=2, filename=None, executor=None, action=None, command=None, - exc_info=(None, None, None)): + exc_info=(None, None, None)) -> None: # py3: errstr should be string and not bytes. @@ -91,7 +91,7 @@ class BuildError(Exception): super().__init__(node, errstr, status, exitstatus, filename, executor, action, command, exc_info) - def __str__(self): + def __str__(self) -> str: if self.filename: return self.filename + ': ' + self.errstr else: @@ -113,7 +113,7 @@ class MSVCError(IOError): pass class ExplicitExit(Exception): - def __init__(self, node=None, status=None, *args): + def __init__(self, node=None, status=None, *args) -> None: self.node = node self.status = status self.exitstatus = status diff --git a/SCons/ErrorsTests.py b/SCons/ErrorsTests.py index 9f2f1a280..9743f0db3 100644 --- a/SCons/ErrorsTests.py +++ b/SCons/ErrorsTests.py @@ -95,7 +95,7 @@ class ErrorsTestCase(unittest.TestCase): except SCons.Errors.ExplicitExit as e: assert e.node == "node" - def test_convert_EnvironmentError_to_BuildError(self): + def test_convert_EnvironmentError_to_BuildError(self) -> None: """Test the convert_to_BuildError function on SConsEnvironmentError exceptions. """ @@ -106,7 +106,7 @@ class ErrorsTestCase(unittest.TestCase): assert be.exitstatus == 2 assert be.filename is None - def test_convert_OSError_to_BuildError(self): + def test_convert_OSError_to_BuildError(self) -> None: """Test the convert_to_BuildError function on OSError exceptions. """ diff --git a/SCons/Executor.py b/SCons/Executor.py index 274af6ad9..153b01091 100644 --- a/SCons/Executor.py +++ b/SCons/Executor.py @@ -39,7 +39,7 @@ class Batch: __slots__ = ('targets', 'sources') - def __init__(self, targets=[], sources=[]): + def __init__(self, targets=[], sources=[]) -> None: self.targets = targets self.sources = sources @@ -55,7 +55,7 @@ class TSList(collections.UserList): a list during variable expansion. We're not really using any collections.UserList methods in practice. """ - def __init__(self, func): + def __init__(self, func) -> None: self.func = func def __getattr__(self, attr): nl = self.func() @@ -63,10 +63,10 @@ class TSList(collections.UserList): def __getitem__(self, i): nl = self.func() return nl[i] - def __str__(self): + def __str__(self) -> str: nl = self.func() return str(nl) - def __repr__(self): + def __repr__(self) -> str: nl = self.func() return repr(nl) @@ -74,17 +74,17 @@ class TSObject: """A class that implements $TARGET or $SOURCE expansions by wrapping an Executor method. """ - def __init__(self, func): + def __init__(self, func) -> None: self.func = func def __getattr__(self, attr): n = self.func() return getattr(n, attr) - def __str__(self): + def __str__(self) -> str: n = self.func() if n: return str(n) return '' - def __repr__(self): + def __repr__(self) -> str: n = self.func() if n: return repr(n) @@ -104,7 +104,7 @@ def rfile(node): return rfile() -def execute_nothing(obj, target, kw): +def execute_nothing(obj, target, kw) -> int: return 0 def execute_action_list(obj, target, kw): @@ -138,7 +138,7 @@ def execute_actions_str(obj): env) for action in obj.get_action_list()]) -def execute_null_str(obj): +def execute_null_str(obj) -> str: return '' _execute_str_map = {0 : execute_null_str, @@ -170,7 +170,7 @@ class Executor(object, metaclass=NoSlotsPyPy): '_execute_str') def __init__(self, action, env=None, overridelist=[{}], - targets=[], sources=[], builder_kw={}): + targets=[], sources=[], builder_kw={}) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Executor') self.set_action_list(action) self.pre_actions = [] @@ -202,7 +202,7 @@ class Executor(object, metaclass=NoSlotsPyPy): } return self.lvars - def _get_changes(self): + def _get_changes(self) -> None: cs = [] ct = [] us = [] @@ -383,10 +383,10 @@ class Executor(object, metaclass=NoSlotsPyPy): def __call__(self, target, **kw): return _do_execute_map[self._do_execute](self, target, kw) - def cleanup(self): + def cleanup(self) -> None: self._memo = {} - def add_sources(self, sources): + def add_sources(self, sources) -> None: """Add source files to this Executor's list. This is necessary for "multi" Builders that can be called repeatedly to build up a source file list for a given target.""" @@ -399,7 +399,7 @@ class Executor(object, metaclass=NoSlotsPyPy): def get_sources(self): return self.batches[0].sources - def add_batch(self, targets, sources): + def add_batch(self, targets, sources) -> None: """Add pair of associated target and source to this Executor's list. This is necessary for "batch" Builders that can be called repeatedly to build up a list of matching target and source files that will be @@ -417,18 +417,18 @@ class Executor(object, metaclass=NoSlotsPyPy): msg = "Source `%s' not found, needed by target `%s'." raise SCons.Errors.StopError(msg % (s, self.batches[0].targets[0])) - def add_pre_action(self, action): + def add_pre_action(self, action) -> None: self.pre_actions.append(action) - def add_post_action(self, action): + def add_post_action(self, action) -> None: self.post_actions.append(action) # another extra indirection for new-style objects and nullify... - def __str__(self): + def __str__(self) -> str: return _execute_str_map[self._execute_str](self) - def nullify(self): + def nullify(self) -> None: self.cleanup() self._do_execute = 0 self._execute_str = 0 @@ -459,23 +459,23 @@ class Executor(object, metaclass=NoSlotsPyPy): self._memo['get_contents'] = result return result - def get_timestamp(self): + def get_timestamp(self) -> int: """Fetch a time stamp for this Executor. We don't have one, of course (only files do), but this is the interface used by the timestamp module. """ return 0 - def scan_targets(self, scanner): + def scan_targets(self, scanner) -> None: # TODO(batch): scan by batches self.scan(scanner, self.get_all_targets()) - def scan_sources(self, scanner): + def scan_sources(self, scanner) -> None: # TODO(batch): scan by batches if self.batches[0].sources: self.scan(scanner, self.get_all_sources()) - def scan(self, scanner, node_list): + def scan(self, scanner, node_list) -> None: """Scan a list of this Executor's files (targets or sources) for implicit dependencies and update all of the targets with them. This essentially short-circuits an N*M scan of the sources for @@ -553,7 +553,7 @@ _batch_executors = {} def GetBatchExecutor(key): return _batch_executors[key] -def AddBatchExecutor(key, executor): +def AddBatchExecutor(key, executor) -> None: assert key not in _batch_executors _batch_executors[key] = executor @@ -601,7 +601,7 @@ class Null(object, metaclass=NoSlotsPyPy): '_do_execute', '_execute_str') - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Executor.Null') self.batches = [Batch(kw['targets'][:], [])] @@ -609,9 +609,9 @@ class Null(object, metaclass=NoSlotsPyPy): return get_NullEnvironment() def get_build_scanner_path(self): return None - def cleanup(self): + def cleanup(self) -> None: pass - def prepare(self): + def prepare(self) -> None: pass def get_unignored_sources(self, *args, **kw): return tuple(()) @@ -629,11 +629,11 @@ class Null(object, metaclass=NoSlotsPyPy): return [] def get_action_side_effects(self): return [] - def __call__(self, *args, **kw): + def __call__(self, *args, **kw) -> int: return 0 - def get_contents(self): + def get_contents(self) -> str: return '' - def _morph(self): + def _morph(self) -> None: """Morph this Null executor to a real Executor object.""" batches = self.batches self.__class__ = Executor @@ -643,13 +643,13 @@ class Null(object, metaclass=NoSlotsPyPy): # The following methods require morphing this Null Executor to a # real Executor object. - def add_pre_action(self, action): + def add_pre_action(self, action) -> None: self._morph() self.add_pre_action(action) - def add_post_action(self, action): + def add_post_action(self, action) -> None: self._morph() self.add_post_action(action) - def set_action_list(self, action): + def set_action_list(self, action) -> None: self._morph() self.set_action_list(action) diff --git a/SCons/ExecutorTests.py b/SCons/ExecutorTests.py index c43c45085..24df8e717 100644 --- a/SCons/ExecutorTests.py +++ b/SCons/ExecutorTests.py @@ -27,7 +27,7 @@ import SCons.Executor class MyEnvironment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {} self._dict.update(kw) def __getitem__(self, key): @@ -36,13 +36,13 @@ class MyEnvironment: d = self._dict.copy() d.update(overrides) return MyEnvironment(**d) - def _update(self, dict): + def _update(self, dict) -> None: self._dict.update(dict) class MyAction: - def __init__(self, actions=['action1', 'action2']): + def __init__(self, actions=['action1', 'action2']) -> None: self.actions = actions - def __call__(self, target, source, env, **kw): + def __call__(self, target, source, env, **kw) -> None: for action in self.actions: action(target, source, env, **kw) def genstring(self, target, source, env): @@ -57,13 +57,13 @@ class MyAction: return [] class MyBuilder: - def __init__(self, env, overrides): + def __init__(self, env, overrides) -> None: self.env = env self.overrides = overrides self.action = MyAction() class MyNode: - def __init__(self, name=None, pre=[], post=[]): + def __init__(self, name=None, pre=[], post=[]) -> None: self.name = name self.implicit = [] self.pre_actions = pre @@ -72,10 +72,10 @@ class MyNode: self.always_build = False self.up_to_date = False - def __str__(self): + def __str__(self) -> str: return self.name - def build(self): + def build(self) -> None: executor = SCons.Executor.Executor(MyAction(self.pre_actions + [self.builder.action] + self.post_actions), @@ -90,7 +90,7 @@ class MyNode: if not scanner: scanner = self.get_env_scanner(env, kw) return [scanner.prefix + str(self)] - def add_to_implicit(self, deps): + def add_to_implicit(self, deps) -> None: self.implicit.extend(deps) def missing(self): return self.missing_val @@ -103,7 +103,7 @@ class MyNode: return self.up_to_date class MyScanner: - def __init__(self, prefix): + def __init__(self, prefix) -> None: self.prefix = prefix def path(self, env, cwd, target, source): return () @@ -131,7 +131,7 @@ class ExecutorTestCase(unittest.TestCase): else: raise Exception("Did not catch expected UserError") - def test__action_list(self): + def test__action_list(self) -> None: """Test the {get,set}_action_list() methods""" x = SCons.Executor.Executor('a', 'e', 'o', 't', ['s1', 's2']) @@ -151,7 +151,7 @@ class ExecutorTestCase(unittest.TestCase): l = x.get_action_list() assert l == ['pre', 'c', 'post'], l - def test_get_build_env(self): + def test_get_build_env(self) -> None: """Test fetching and generating a build environment""" x = SCons.Executor.Executor(MyAction(), MyEnvironment(e=1), [], 't', ['s1', 's2']) @@ -181,7 +181,7 @@ class ExecutorTestCase(unittest.TestCase): assert be['O'] == 'ob3', be['O'] assert be['Y'] == 'yyy', be['Y'] - def test_get_build_scanner_path(self): + def test_get_build_scanner_path(self) -> None: """Test fetching the path for the specified scanner.""" t = MyNode('t') t.cwd = 'here' @@ -192,7 +192,7 @@ class ExecutorTestCase(unittest.TestCase): ['s1', 's2']) class LocalScanner: - def path(self, env, dir, target, source): + def path(self, env, dir, target, source) -> str: target = list(map(str, target)) source = list(map(str, source)) return "scanner: %s, %s, %s, %s" % (env['SCANNERVAL'], dir, target, source) @@ -201,7 +201,7 @@ class ExecutorTestCase(unittest.TestCase): p = x.get_build_scanner_path(s) assert p == "scanner: sss, here, ['t'], ['s1', 's2']", p - def test_get_kw(self): + def test_get_kw(self) -> None: """Test the get_kw() method""" t = MyNode('t') x = SCons.Executor.Executor(MyAction(), @@ -220,13 +220,13 @@ class ExecutorTestCase(unittest.TestCase): def test__call__(self): """Test calling an Executor""" result = [] - def pre(target, source, env, result=result, **kw): + def pre(target, source, env, result=result, **kw) -> None: result.append('pre') - def action1(target, source, env, result=result, **kw): + def action1(target, source, env, result=result, **kw) -> None: result.append('action1') - def action2(target, source, env, result=result, **kw): + def action2(target, source, env, result=result, **kw) -> None: result.append('action2') - def post(target, source, env, result=result, **kw): + def post(target, source, env, result=result, **kw) -> None: result.append('post') env = MyEnvironment() @@ -240,7 +240,7 @@ class ExecutorTestCase(unittest.TestCase): assert result == ['pre', 'action1', 'action2', 'post'], result del result[:] - def pre_err(target, source, env, result=result, **kw): + def pre_err(target, source, env, result=result, **kw) -> int: result.append('pre_err') return 1 @@ -256,7 +256,7 @@ class ExecutorTestCase(unittest.TestCase): assert result == ['pre_err'], result del result[:] - def test_cleanup(self): + def test_cleanup(self) -> None: """Test cleaning up an Executor""" orig_env = MyEnvironment(e=1) x = SCons.Executor.Executor('b', orig_env, [{'o':1}], @@ -276,7 +276,7 @@ class ExecutorTestCase(unittest.TestCase): be = x.get_build_env() assert be['eee'] == 1, be['eee'] - def test_add_sources(self): + def test_add_sources(self) -> None: """Test adding sources to an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) sources = x.get_all_sources() @@ -290,7 +290,7 @@ class ExecutorTestCase(unittest.TestCase): sources = x.get_all_sources() assert sources == ['s1', 's2', 's3', 's4'], sources - def test_get_sources(self): + def test_get_sources(self) -> None: """Test getting sources from an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) sources = x.get_sources() @@ -322,7 +322,7 @@ class ExecutorTestCase(unittest.TestCase): else: raise AssertionError("did not catch expected StopError: %s" % r) - def test_add_pre_action(self): + def test_add_pre_action(self) -> None: """Test adding pre-actions to an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) x.add_pre_action('a1') @@ -330,7 +330,7 @@ class ExecutorTestCase(unittest.TestCase): x.add_pre_action('a2') assert x.pre_actions == ['a1', 'a2'] - def test_add_post_action(self): + def test_add_post_action(self) -> None: """Test adding post-actions to an Executor""" x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) x.add_post_action('a1') @@ -338,7 +338,7 @@ class ExecutorTestCase(unittest.TestCase): x.add_post_action('a2') assert x.post_actions == ['a1', 'a2'] - def test___str__(self): + def test___str__(self) -> None: """Test the __str__() method""" env = MyEnvironment(S='string') @@ -355,12 +355,12 @@ class ExecutorTestCase(unittest.TestCase): 'GENSTRING post t s' assert c == expect, c - def test_nullify(self): + def test_nullify(self) -> None: """Test the nullify() method""" env = MyEnvironment(S='string') result = [] - def action1(target, source, env, result=result, **kw): + def action1(target, source, env, result=result, **kw) -> None: result.append('action1') env = MyEnvironment() @@ -381,7 +381,7 @@ class ExecutorTestCase(unittest.TestCase): s = str(x) assert s == '', s - def test_get_contents(self): + def test_get_contents(self) -> None: """Test fetching the signatures contents""" env = MyEnvironment(C='contents') @@ -396,13 +396,13 @@ class ExecutorTestCase(unittest.TestCase): c = x.get_contents() assert c == b'pre t sgrow t spost t s', c - def test_get_timestamp(self): + def test_get_timestamp(self) -> None: """Test fetching the "timestamp" """ x = SCons.Executor.Executor('b', 'e', 'o', 't', ['s1', 's2']) ts = x.get_timestamp() assert ts == 0, ts - def test_scan_targets(self): + def test_scan_targets(self) -> None: """Test scanning the targets for implicit dependencies""" env = MyEnvironment(S='string') t1 = MyNode('t1') @@ -421,7 +421,7 @@ class ExecutorTestCase(unittest.TestCase): assert t1.implicit == ['scanner-t1', 'scanner-t2'], t1.implicit assert t2.implicit == ['scanner-t1', 'scanner-t2'], t2.implicit - def test_scan_sources(self): + def test_scan_sources(self) -> None: """Test scanning the sources for implicit dependencies""" env = MyEnvironment(S='string') t1 = MyNode('t1') @@ -440,7 +440,7 @@ class ExecutorTestCase(unittest.TestCase): assert t1.implicit == ['scanner-s1', 'scanner-s2'], t1.implicit assert t2.implicit == ['scanner-s1', 'scanner-s2'], t2.implicit - def test_get_unignored_sources(self): + def test_get_unignored_sources(self) -> None: """Test fetching the unignored source list""" env = MyEnvironment() s1 = MyNode('s1') @@ -457,7 +457,7 @@ class ExecutorTestCase(unittest.TestCase): r = x.get_unignored_sources(None, [s1, s3]) assert r == [s2], list(map(str, r)) - def test_changed_sources_for_alwaysBuild(self): + def test_changed_sources_for_alwaysBuild(self) -> None: """ Ensure if a target is marked always build that the sources are always marked changed sources :return: diff --git a/SCons/Memoize.py b/SCons/Memoize.py index b02c1445b..c59434823 100644 --- a/SCons/Memoize.py +++ b/SCons/Memoize.py @@ -111,7 +111,7 @@ class Counter: fill in the correct class name and method name that represents the name of the function being counted. """ - def __init__(self, cls_name, method_name): + def __init__(self, cls_name, method_name) -> None: """ """ self.cls_name = cls_name @@ -120,7 +120,7 @@ class Counter: self.miss = 0 def key(self): return self.cls_name+'.'+self.method_name - def display(self): + def display(self) -> None: print(" {:7d} hits {:7d} misses {}()".format(self.hit, self.miss, self.key())) def __eq__(self, other): try: @@ -136,7 +136,7 @@ class CountValue(Counter): the class's methods that memoizes its return value by simply storing the return value in its _memo dictionary. """ - def count(self, *args, **kw): + def count(self, *args, **kw) -> None: """ Counts whether the memoized value has already been set (a hit) or not (a miss). """ @@ -156,12 +156,12 @@ class CountDict(Counter): indexed by some key that can be computed from one or more of its input arguments. """ - def __init__(self, cls_name, method_name, keymaker): + def __init__(self, cls_name, method_name, keymaker) -> None: """ """ super().__init__(cls_name, method_name) self.keymaker = keymaker - def count(self, *args, **kw): + def count(self, *args, **kw) -> None: """ Counts whether the computed key value is already present in the memoization dictionary (a hit) or not (a miss). """ @@ -177,7 +177,7 @@ class CountDict(Counter): else: self.miss = self.miss + 1 -def Dump(title=None): +def Dump(title=None) -> None: """ Dump the hit/miss count for all the counters collected so far. """ @@ -186,7 +186,7 @@ def Dump(title=None): for counter in sorted(CounterList): CounterList[counter].display() -def EnableMemoization(): +def EnableMemoization() -> None: global use_memoizer use_memoizer = 1 diff --git a/SCons/MemoizeTests.py b/SCons/MemoizeTests.py index 7830d993c..825256ccf 100644 --- a/SCons/MemoizeTests.py +++ b/SCons/MemoizeTests.py @@ -29,7 +29,7 @@ import SCons.Memoize SCons.Memoize.EnableMemoization() class FakeObject: - def __init__(self): + def __init__(self) -> None: self._memo = {} def _dict_key(self, argument): @@ -74,7 +74,7 @@ class FakeObject: return SCons.Memoize.CounterList.get(self.__class__.__name__+'.'+name, None) class Returner: - def __init__(self, result): + def __init__(self, result) -> None: self.result = result self.calls = 0 def __call__(self, *args, **kw): @@ -84,7 +84,7 @@ class Returner: class CountDictTestCase(unittest.TestCase): - def test___call__(self): + def test___call__(self) -> None: """Calling a Memoized dict method """ obj = FakeObject() @@ -126,7 +126,7 @@ class CountDictTestCase(unittest.TestCase): class CountValueTestCase(unittest.TestCase): - def test___call__(self): + def test___call__(self) -> None: """Calling a Memoized value method """ obj = FakeObject() diff --git a/SCons/Node/Alias.py b/SCons/Node/Alias.py index 1125c22f6..55c4795e2 100644 --- a/SCons/Node/Alias.py +++ b/SCons/Node/Alias.py @@ -78,7 +78,7 @@ class AliasNodeInfo(SCons.Node.NodeInfoBase): return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -98,7 +98,7 @@ class Alias(SCons.Node.Node): NodeInfo = AliasNodeInfo BuildInfo = AliasBuildInfo - def __init__(self, name): + def __init__(self, name) -> None: super().__init__() self.name = name self.changed_since_last_build = 1 @@ -107,16 +107,16 @@ class Alias(SCons.Node.Node): def str_for_display(self): return '"' + self.__str__() + '"' - def __str__(self): + def __str__(self) -> str: return self.name - def make_ready(self): + def make_ready(self) -> None: self.get_csig() really_build = SCons.Node.Node.build is_up_to_date = SCons.Node.Node.children_are_up_to_date - def is_under(self, dir): + def is_under(self, dir) -> int: # Make Alias nodes get built regardless of # what directory scons was run from. Alias nodes # are outside the filesystem: @@ -128,7 +128,7 @@ class Alias(SCons.Node.Node): childsigs = [n.get_csig() for n in self.children()] return ''.join(childsigs) - def sconsign(self): + def sconsign(self) -> None: """An Alias is not recorded in .sconsign files""" pass @@ -136,11 +136,11 @@ class Alias(SCons.Node.Node): # # - def build(self): + def build(self) -> None: """A "builder" for aliases.""" pass - def convert(self): + def convert(self) -> None: try: del self.builder except AttributeError: pass self.reset_executor() diff --git a/SCons/Node/AliasTests.py b/SCons/Node/AliasTests.py index 14662fd9c..78138f93a 100644 --- a/SCons/Node/AliasTests.py +++ b/SCons/Node/AliasTests.py @@ -28,13 +28,13 @@ import SCons.Node.Alias class AliasTestCase(unittest.TestCase): - def test_AliasNameSpace(self): + def test_AliasNameSpace(self) -> None: """Test creating an Alias name space """ ans = SCons.Node.Alias.AliasNameSpace() assert ans is not None, ans - def test_ANS_Alias(self): + def test_ANS_Alias(self) -> None: """Test the Alias() factory """ ans = SCons.Node.Alias.AliasNameSpace() @@ -45,11 +45,11 @@ class AliasTestCase(unittest.TestCase): a2 = ans.Alias('a1') assert a1 is a2, (a1, a2) - def test_get_contents(self): + def test_get_contents(self) -> None: """Test the get_contents() method """ class DummyNode: - def __init__(self, contents): + def __init__(self, contents) -> None: self.contents = contents def get_csig(self): return self.contents @@ -66,7 +66,7 @@ class AliasTestCase(unittest.TestCase): c = a.get_contents() assert c == 'onetwothree', c - def test_lookup(self): + def test_lookup(self) -> None: """Test the lookup() method """ ans = SCons.Node.Alias.AliasNameSpace() @@ -81,7 +81,7 @@ class AliasTestCase(unittest.TestCase): a = ans.lookup('a2') assert a is None, a - def test_Alias(self): + def test_Alias(self) -> None: """Test creating an Alias() object """ a1 = SCons.Node.Alias.Alias('a') @@ -94,14 +94,14 @@ class AliasTestCase(unittest.TestCase): assert a1.name == a2.name class AliasNodeInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test AliasNodeInfo initialization""" ans = SCons.Node.Alias.AliasNameSpace() aaa = ans.Alias('aaa') ni = SCons.Node.Alias.AliasNodeInfo() class AliasBuildInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test AliasBuildInfo initialization""" ans = SCons.Node.Alias.AliasNameSpace() aaa = ans.Alias('aaa') diff --git a/SCons/Node/FS.py b/SCons/Node/FS.py index 67e1ff608..58b8a5cf4 100644 --- a/SCons/Node/FS.py +++ b/SCons/Node/FS.py @@ -81,11 +81,11 @@ class EntryProxyAttributeError(AttributeError): An AttributeError subclass for recording and displaying the name of the underlying Entry involved in an AttributeError exception. """ - def __init__(self, entry_proxy, attribute): + def __init__(self, entry_proxy, attribute) -> None: super().__init__() self.entry_proxy = entry_proxy self.attribute = attribute - def __str__(self): + def __str__(self) -> str: entry = self.entry_proxy.get() fmt = "%s instance %s has no attribute %s" return fmt % (entry.__class__.__name__, @@ -116,7 +116,7 @@ default_max_drift = 2*24*60*60 # Save_Strings = None -def save_strings(val): +def save_strings(val) -> None: global Save_Strings Save_Strings = val @@ -130,7 +130,7 @@ def save_strings(val): do_splitdrive = None _my_splitdrive =None -def initialize_do_splitdrive(): +def initialize_do_splitdrive() -> None: global do_splitdrive global has_unc drive, path = os.path.splitdrive('X:/foo') @@ -231,7 +231,7 @@ needs_normpath_match = needs_normpath_check.match # TODO: See if theres a reasonable way to enable using links on win32/64 if hasattr(os, 'link') and sys.platform != 'win32': - def _hardlink_func(fs, src, dst): + def _hardlink_func(fs, src, dst) -> None: # If the source is a symlink, we can't just hard-link to it # because a relative symlink may point somewhere completely # different. We must disambiguate the symlink and then @@ -247,12 +247,12 @@ else: _hardlink_func = None if hasattr(os, 'symlink') and sys.platform != 'win32': - def _softlink_func(fs, src, dst): + def _softlink_func(fs, src, dst) -> None: fs.symlink(src, dst) else: _softlink_func = None -def _copy_func(fs, src, dest): +def _copy_func(fs, src, dest) -> None: shutil.copy2(src, dest) st = fs.stat(src) fs.chmod(dest, stat.S_IMODE(st.st_mode) | stat.S_IWRITE) @@ -286,7 +286,7 @@ def set_duplicate(duplicate): if link_dict[func]: Link_Funcs.append(link_dict[func]) -def LinkFunc(target, source, env): +def LinkFunc(target, source, env) -> int: """ Relative paths cause problems with symbolic links, so we use absolute paths, which may be a problem for people @@ -321,19 +321,19 @@ def LinkFunc(target, source, env): return 0 Link = SCons.Action.Action(LinkFunc, None) -def LocalString(target, source, env): +def LocalString(target, source, env) -> str: return 'Local copy of %s from %s' % (target[0], source[0]) LocalCopy = SCons.Action.Action(LinkFunc, LocalString) -def UnlinkFunc(target, source, env): +def UnlinkFunc(target, source, env) -> int: t = target[0] t.fs.unlink(t.get_abspath()) return 0 Unlink = SCons.Action.Action(UnlinkFunc, None) -def MkdirFunc(target, source, env): +def MkdirFunc(target, source, env) -> int: t = target[0] # This os.path.exists test looks redundant, but it's possible # when using Install() to install multiple dirs outside the @@ -385,7 +385,7 @@ class DiskChecker: This Class will hold functions to determine what this particular disk checking implementation should do when enabled or disabled. """ - def __init__(self, disk_check_type, do_check_function, ignore_check_function): + def __init__(self, disk_check_type, do_check_function, ignore_check_function) -> None: self.disk_check_type = disk_check_type self.do_check_function = do_check_function self.ignore_check_function = ignore_check_function @@ -394,7 +394,7 @@ class DiskChecker: def __call__(self, *args, **kw): return self.func(*args, **kw) - def enable(self, disk_check_type_list): + def enable(self, disk_check_type_list) -> None: """ If the current object's disk_check_type matches any in the list passed :param disk_check_type_list: List of disk checks to enable @@ -423,7 +423,7 @@ def do_diskcheck_match(node, predicate, errorfmt): raise TypeError(errorfmt % node.get_abspath()) -def ignore_diskcheck_match(node, predicate, errorfmt): +def ignore_diskcheck_match(node, predicate, errorfmt) -> None: pass @@ -434,7 +434,7 @@ diskcheckers = [ ] -def set_diskcheck(enabled_checkers): +def set_diskcheck(enabled_checkers) -> None: for dc in diskcheckers: dc.enable(enabled_checkers) @@ -584,7 +584,7 @@ class Base(SCons.Node.Node): '_proxy', '_func_sconsign'] - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: """Initialize a generic Node.FS.Base object. Call the superclass initialization, take care of setting up @@ -663,7 +663,7 @@ class Base(SCons.Node.Node): raise AttributeError("%r object has no attribute %r" % (self.__class__, attr)) - def __str__(self): + def __str__(self) -> str: """A Node.FS.Base object's string representation is its path name.""" global Save_Strings @@ -775,7 +775,7 @@ class Base(SCons.Node.Node): st = self.lstat() return st is not None and stat.S_ISLNK(st.st_mode) else: - def islink(self): + def islink(self) -> bool: return False # no symlinks def is_under(self, dir): @@ -784,7 +784,7 @@ class Base(SCons.Node.Node): else: return self.dir.is_under(dir) - def set_local(self): + def set_local(self) -> None: self._local = 1 def srcnode(self): @@ -817,7 +817,7 @@ class Base(SCons.Node.Node): pathname += p.dirname return pathname + path_elems[-1].name - def set_src_builder(self, builder): + def set_src_builder(self, builder) -> None: """Set the source code builder for this node.""" self.sbuilder = builder if not self.has_builder(): @@ -951,7 +951,7 @@ class Base(SCons.Node.Node): self._memo['rentry'] = result return result - def _glob1(self, pattern, ondisk=True, source=False, strings=False): + def _glob1(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False): return [] # Dict that provides a simple backward compatibility @@ -989,12 +989,12 @@ class Entry(Base): 'released_target_info', 'contentsig'] - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: super().__init__(name, directory, fs) self._func_exists = 3 self._func_get_contents = 1 - def diskcheck_match(self): + def diskcheck_match(self) -> None: pass def disambiguate(self, must_exist=None): @@ -1066,7 +1066,7 @@ class Entry(Base): else: return self.get_text_contents() - def must_be_same(self, klass): + def must_be_same(self, klass) -> None: """Called to make sure a Node is a Dir. Since we're an Entry, we can morph into one.""" if self.__class__ is not klass: @@ -1097,7 +1097,7 @@ class Entry(Base): def new_ninfo(self): return self.disambiguate().new_ninfo() - def _glob1(self, pattern, ondisk=True, source=False, strings=False): + def _glob1(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False): return self.disambiguate()._glob1(pattern, ondisk, source, strings) def get_subst_proxy(self): @@ -1162,10 +1162,10 @@ class LocalFS: def scandir(self, path): return os.scandir(path) - def makedirs(self, path, mode=0o777, exist_ok=False): + def makedirs(self, path, mode: int=0o777, exist_ok: bool=False): return os.makedirs(path, mode=mode, exist_ok=exist_ok) - def mkdir(self, path, mode=0o777): + def mkdir(self, path, mode: int=0o777): return os.mkdir(path, mode=mode) def rename(self, old, new): @@ -1190,7 +1190,7 @@ class LocalFS: else: - def islink(self, path): + def islink(self, path) -> bool: return False # no symlinks if hasattr(os, 'readlink'): @@ -1200,13 +1200,13 @@ class LocalFS: else: - def readlink(self, file): + def readlink(self, file) -> str: return '' class FS(LocalFS): - def __init__(self, path = None): + def __init__(self, path = None) -> None: """Initialize the Node.FS subsystem. The supplied path is the top of the source tree, where we @@ -1238,13 +1238,13 @@ class FS(LocalFS): DirNodeInfo.fs = self FileNodeInfo.fs = self - def set_SConstruct_dir(self, dir): + def set_SConstruct_dir(self, dir) -> None: self.SConstruct_dir = dir def get_max_drift(self): return self.max_drift - def set_max_drift(self, max_drift): + def set_max_drift(self, max_drift) -> None: self.max_drift = max_drift def getcwd(self): @@ -1253,7 +1253,7 @@ class FS(LocalFS): else: return "" - def chdir(self, dir, change_os_dir=False): + def chdir(self, dir, change_os_dir: bool=False): """Change the current working directory for lookups. If change_os_dir is true, we will also change the "real" cwd to match. @@ -1285,7 +1285,7 @@ class FS(LocalFS): self.Root[''] = root return root - def _lookup(self, p, directory, fsclass, create=1): + def _lookup(self, p, directory, fsclass, create: int=1): """ The generic entry point for Node lookup with user-supplied data. @@ -1421,7 +1421,7 @@ class FS(LocalFS): return root._lookup_abs(p, fsclass, create) - def Entry(self, name, directory = None, create = 1): + def Entry(self, name, directory = None, create: int = 1): """Look up or create a generic Entry node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory @@ -1430,7 +1430,7 @@ class FS(LocalFS): """ return self._lookup(name, directory, Entry, create) - def File(self, name, directory = None, create = 1): + def File(self, name, directory = None, create: int = 1): """Look up or create a File node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, @@ -1442,7 +1442,7 @@ class FS(LocalFS): """ return self._lookup(name, directory, File, create) - def Dir(self, name, directory = None, create = True): + def Dir(self, name, directory = None, create: bool = True): """Look up or create a Dir node with the specified name. If the name is a relative path (begins with ./, ../, or a file name), then it is looked up relative to the supplied directory node, @@ -1454,7 +1454,7 @@ class FS(LocalFS): """ return self._lookup(name, directory, Dir, create) - def VariantDir(self, variant_dir, src_dir, duplicate=1): + def VariantDir(self, variant_dir, src_dir, duplicate: int=1): """Link the supplied variant directory to the source directory for purposes of building files.""" @@ -1470,7 +1470,7 @@ class FS(LocalFS): raise SCons.Errors.UserError("'%s' already has a source directory: '%s'."%(variant_dir, variant_dir.srcdir)) variant_dir.link(src_dir, duplicate) - def Repository(self, *dirs): + def Repository(self, *dirs) -> None: """Specify Repository directories to search.""" for d in dirs: if not isinstance(d, SCons.Node.Node): @@ -1521,7 +1521,7 @@ class FS(LocalFS): message = fmt % ' '.join(map(str, targets)) return targets, message - def Glob(self, pathname, ondisk=True, source=True, strings=False, exclude=None, cwd=None): + def Glob(self, pathname, ondisk: bool=True, source: bool=True, strings: bool=False, exclude=None, cwd=None): """ Globs @@ -1555,7 +1555,7 @@ class DirBuildInfo(SCons.Node.BuildInfoBase): glob_magic_check = re.compile('[*?[]') -def has_glob_magic(s): +def has_glob_magic(s) -> bool: return glob_magic_check.search(s) is not None class Dir(Base): @@ -1580,12 +1580,12 @@ class Dir(Base): NodeInfo = DirNodeInfo BuildInfo = DirBuildInfo - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.Dir') super().__init__(name, directory, fs) self._morph() - def _morph(self): + def _morph(self) -> None: """Turn a file system Node (either a freshly initialized directory object or a separate Entry object) into a proper directory object. @@ -1649,11 +1649,11 @@ class Dir(Base): l.insert(0, a) self.get_executor().set_action_list(l) - def diskcheck_match(self): + def diskcheck_match(self) -> None: diskcheck_match(self, self.isfile, "File %s found where directory expected.") - def __clearRepositoryCache(self, duplicate=None): + def __clearRepositoryCache(self, duplicate=None) -> None: """Called when we change the repository(ies) for a directory. This clears any cached information that is invalidated by changing the repository.""" @@ -1671,7 +1671,7 @@ class Dir(Base): if duplicate is not None: node.duplicate = duplicate - def __resetDuplicate(self, node): + def __resetDuplicate(self, node) -> None: if node != self: node.duplicate = node.get_dir().duplicate @@ -1682,7 +1682,7 @@ class Dir(Base): """ return self.fs.Entry(name, self) - def Dir(self, name, create=True): + def Dir(self, name, create: bool=True): """ Looks up or creates a directory node named 'name' relative to this directory. @@ -1696,7 +1696,7 @@ class Dir(Base): """ return self.fs.File(name, self) - def link(self, srcdir, duplicate): + def link(self, srcdir, duplicate) -> None: """Set this directory as the variant directory for the supplied source directory.""" self.srcdir = srcdir @@ -1734,7 +1734,7 @@ class Dir(Base): return result - def addRepository(self, dir): + def addRepository(self, dir) -> None: if dir != self and dir not in self.repositories: self.repositories.append(dir) dir._tpath = '.' @@ -1834,10 +1834,10 @@ class Dir(Base): # Taskmaster interface subsystem # - def prepare(self): + def prepare(self) -> None: pass - def build(self, **kw): + def build(self, **kw) -> None: """A null "builder" for directories.""" global MkdirBuilder if self.builder is not MkdirBuilder: @@ -1911,10 +1911,10 @@ class Dir(Base): contents = self.get_contents() return hash_signature(contents) - def do_duplicate(self, src): + def do_duplicate(self, src) -> None: pass - def is_up_to_date(self): + def is_up_to_date(self) -> int: """If any child is not up-to-date, then this directory isn't, either.""" if self.builder is not MkdirBuilder and not self.exists(): @@ -2145,7 +2145,7 @@ class Dir(Base): return None return node - def walk(self, func, arg): + def walk(self, func, arg) -> None: """ Walk this directory tree by calling the specified function for each directory in the tree. @@ -2171,7 +2171,7 @@ class Dir(Base): for dirname in [n for n in names if isinstance(entries[n], Dir)]: entries[dirname].walk(func, arg) - def glob(self, pathname, ondisk=True, source=False, strings=False, exclude=None) -> list: + def glob(self, pathname, ondisk: bool=True, source: bool=False, strings: bool=False, exclude=None) -> list: """Returns a list of Nodes (or strings) matching a pathname pattern. Pathname patterns follow POSIX shell syntax:: @@ -2234,7 +2234,7 @@ class Dir(Base): result = [x for x in result if not any(fnmatch.fnmatch(str(x), str(e)) for e in SCons.Util.flatten(excludes))] return sorted(result, key=lambda a: str(a)) - def _glob1(self, pattern, ondisk=True, source=False, strings=False): + def _glob1(self, pattern, ondisk: bool=True, source: bool=False, strings: bool=False): """ Globs for and returns a list of entry names matching a single pattern in this directory. @@ -2313,7 +2313,7 @@ class RootDir(Dir): __slots__ = ('_lookupDict', 'abspath', 'path') - def __init__(self, drive, fs): + def __init__(self, drive, fs) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.RootDir') SCons.Node.Node.__init__(self) @@ -2371,7 +2371,7 @@ class RootDir(Dir): if not has_unc: self._lookupDict['//'] = self - def _morph(self): + def _morph(self) -> None: """Turn a file system Node (either a freshly initialized directory object or a separate Entry object) into a proper directory object. @@ -2412,12 +2412,12 @@ class RootDir(Dir): self.get_executor().set_action_list(l) - def must_be_same(self, klass): + def must_be_same(self, klass) -> None: if klass is Dir: return Base.must_be_same(self, klass) - def _lookup_abs(self, p, klass, create=True): + def _lookup_abs(self, p, klass, create: bool=True): """ Fast (?) lookup of a *normalized* absolute path. @@ -2459,7 +2459,7 @@ class RootDir(Dir): result.must_be_same(klass) return result - def __str__(self): + def __str__(self) -> str: return self._abspath def entry_abspath(self, name): @@ -2474,7 +2474,7 @@ class RootDir(Dir): def entry_tpath(self, name): return self._tpath + name - def is_under(self, dir): + def is_under(self, dir) -> int: if self is dir: return 1 else: @@ -2531,7 +2531,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase): return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -2544,7 +2544,7 @@ class FileNodeInfo(SCons.Node.NodeInfoBase): def __eq__(self, other): return self.csig == other.csig and self.timestamp == other.timestamp and self.size == other.size - def __ne__(self, other): + def __ne__(self, other) -> bool: return not self.__eq__(other) @@ -2577,7 +2577,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): return super().__setattr__(key, value) - def convert_to_sconsign(self): + def convert_to_sconsign(self) -> None: """ Converts this FileBuildInfo object for writing to a .sconsign file @@ -2604,7 +2604,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): else: setattr(self, attr, list(map(node_to_str, val))) - def convert_from_sconsign(self, dir, name): + def convert_from_sconsign(self, dir, name) -> None: """ Converts a newly-read FileBuildInfo object for in-SCons use @@ -2613,7 +2613,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): """ pass - def prepare_dependencies(self): + def prepare_dependencies(self) -> None: """ Prepares a FileBuildInfo object for explaining what changed @@ -2642,7 +2642,7 @@ class FileBuildInfo(SCons.Node.BuildInfoBase): nodes.append(s) setattr(self, nattr, nodes) - def format(self, names=0): + def format(self, names: int=0): result = [] bkids = self.bsources + self.bdepends + self.bimplicit bkidsigs = self.bsourcesigs + self.bdependsigs + self.bimplicitsigs @@ -2680,11 +2680,11 @@ class File(Base): # Although the command-line argument is in kilobytes, this is in bytes. hash_chunksize = 65536 - def diskcheck_match(self): + def diskcheck_match(self) -> None: diskcheck_match(self, self.isdir, "Directory %s found where file expected.") - def __init__(self, name, directory, fs): + def __init__(self, name, directory, fs) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.FS.File') super().__init__(name, directory, fs) self._morph() @@ -2694,7 +2694,7 @@ class File(Base): the directory of this file.""" return self.dir.Entry(name) - def Dir(self, name, create=True): + def Dir(self, name, create: bool=True): """Create a directory node named 'name' relative to the directory of this file.""" return self.dir.Dir(name, create=create) @@ -2709,7 +2709,7 @@ class File(Base): the directory of this file.""" return self.dir.File(name) - def _morph(self): + def _morph(self) -> None: """Turn a file system node into a File object.""" self.scanner_paths = {} if not hasattr(self, '_local'): @@ -2997,12 +2997,12 @@ class File(Base): return result - def _createDir(self): + def _createDir(self) -> None: # ensure that the directories for this node are # created. self.dir._create() - def push_to_cache(self): + def push_to_cache(self) -> None: """Try to push the node into a cache """ # This should get called before the Nodes' .built() method is @@ -3033,7 +3033,7 @@ class File(Base): return None return self.get_build_env().get_CacheDir().retrieve(self) - def visited(self): + def visited(self) -> None: if self.exists() and self.executor is not None: self.get_build_env().get_CacheDir().push_if_forced(self) @@ -3056,7 +3056,7 @@ class File(Base): SCons.Node.store_info_map[self.store_info](self) - def release_target_info(self): + def release_target_info(self) -> None: """Called just after this node has been marked up-to-date or was built completely. @@ -3123,7 +3123,7 @@ class File(Base): self.builder_set(scb) return scb - def has_src_builder(self): + def has_src_builder(self) -> bool: """Return whether this Node has a source builder or not. If this Node doesn't have an explicit source code builder, this @@ -3159,7 +3159,7 @@ class File(Base): # Taskmaster interface subsystem # - def make_ready(self): + def make_ready(self) -> None: self.has_src_builder() self.get_binfo() @@ -3282,11 +3282,11 @@ class File(Base): # DECISION SUBSYSTEM # - def builder_set(self, builder): + def builder_set(self, builder) -> None: SCons.Node.Node.builder_set(self, builder) self.changed_since_last_build = 5 - def built(self): + def built(self) -> None: """Called just after this File node is successfully built. Just like for 'release_target_info' we try to release @@ -3310,7 +3310,7 @@ class File(Base): self.scanner_paths = None - def changed(self, node=None, allowcache=False): + def changed(self, node=None, allowcache: bool=False): """ Returns if the node is up-to-date with respect to the BuildInfo stored last time it was built. @@ -3728,7 +3728,7 @@ class FileFinder: """ """ - def __init__(self): + def __init__(self) -> None: self._memo = {} def filedir_lookup(self, p, fd=None): @@ -3826,7 +3826,7 @@ class FileFinder: find_file = FileFinder().find_file -def invalidate_node_memos(targets): +def invalidate_node_memos(targets) -> None: """ Invalidate the memoized values of all Nodes (files or directories) that are associated with the given entries. Has been added to diff --git a/SCons/Node/FSTests.py b/SCons/Node/FSTests.py index f3afacea3..e2eb0af70 100644 --- a/SCons/Node/FSTests.py +++ b/SCons/Node/FSTests.py @@ -44,7 +44,7 @@ scanner_count = 0 class Scanner: - def __init__(self, node=None): + def __init__(self, node=None) -> None: global scanner_count scanner_count = scanner_count + 1 self.hash = scanner_count @@ -67,7 +67,7 @@ class Scanner: class Environment: - def __init__(self): + def __init__(self) -> None: self.scanner = Scanner() def Dictionary(self, *args): @@ -82,27 +82,27 @@ class Environment: def Override(self, overrides): return self - def _update(self, dict): + def _update(self, dict) -> None: pass class Action: - def __call__(self, targets, sources, env, **kw): + def __call__(self, targets, sources, env, **kw) -> int: global built_it if kw.get('execute', 1): built_it = 1 return 0 - def show(self, string): + def show(self, string) -> None: pass def get_contents(self, target, source, env): return bytearray("", 'utf-8') - def genstring(self, target, source, env): + def genstring(self, target, source, env) -> str: return "" - def strfunction(self, targets, sources, env): + def strfunction(self, targets, sources, env) -> str: return "" def get_implicit_deps(self, target, source, env): @@ -110,7 +110,7 @@ class Action: class Builder: - def __init__(self, factory, action=Action()): + def __init__(self, factory, action=Action()) -> None: self.factory = factory self.env = Environment() self.overrides = {} @@ -126,19 +126,19 @@ class Builder: class _tempdirTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.save_cwd = os.getcwd() self.test = TestCmd(workdir='') # FS doesn't like the cwd to be something other than its root. os.chdir(self.test.workpath("")) self.fs = SCons.Node.FS.FS() - def tearDown(self): + def tearDown(self) -> None: os.chdir(self.save_cwd) class VariantDirTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test variant dir functionality""" test = TestCmd(workdir='') @@ -316,10 +316,10 @@ class VariantDirTestCase(unittest.TestCase): f9 = fs.File('build/var2/new_dir/test9.out') class MkdirAction(Action): - def __init__(self, dir_made): + def __init__(self, dir_made) -> None: self.dir_made = dir_made - def __call__(self, target, source, env, executor=None): + def __call__(self, target, source, env, executor=None) -> None: if executor: target = executor.get_all_targets() source = executor.get_all_sources() @@ -328,7 +328,7 @@ class VariantDirTestCase(unittest.TestCase): save_Link = SCons.Node.FS.Link link_made = [] - def link_func(target, source, env, link_made=link_made): + def link_func(target, source, env, link_made=link_made) -> None: link_made.append(target) SCons.Node.FS.Link = link_func @@ -458,7 +458,7 @@ class VariantDirTestCase(unittest.TestCase): class LinkSimulator: """A class to intercept os.[sym]link() calls and track them.""" - def __init__(self, duplicate, link, symlink, copy): + def __init__(self, duplicate, link, symlink, copy) -> None: self.duplicate = duplicate self.have = {'hard': link, 'soft': symlink, 'copy': copy} @@ -481,7 +481,7 @@ class VariantDirTestCase(unittest.TestCase): "instead of soft" % next_link raise OSError("Simulating symlink creation error.") - def copy(self, src, dest): + def copy(self, src, dest) -> None: next_link = self.links_to_be_called.pop(0) assert next_link == "copy", \ "Wrong link order: expected %s to be called " \ @@ -631,7 +631,7 @@ class VariantDirTestCase(unittest.TestCase): class BaseTestCase(_tempdirTestCase): - def test_stat(self): + def test_stat(self) -> None: """Test the Base.stat() method""" test = self.test test.write("e1", "e1\n") @@ -645,7 +645,7 @@ class BaseTestCase(_tempdirTestCase): s = e2.stat() assert s is None, s - def test_getmtime(self): + def test_getmtime(self) -> None: """Test the Base.getmtime() method""" test = self.test test.write("file", "file\n") @@ -658,7 +658,7 @@ class BaseTestCase(_tempdirTestCase): mtime = file.getmtime() assert mtime is None, mtime - def test_getsize(self): + def test_getsize(self) -> None: """Test the Base.getsize() method""" test = self.test test.write("file", "file\n") @@ -672,7 +672,7 @@ class BaseTestCase(_tempdirTestCase): size = file.getsize() assert size is None, size - def test_isdir(self): + def test_isdir(self) -> None: """Test the Base.isdir() method""" test = self.test test.subdir('dir') @@ -688,7 +688,7 @@ class BaseTestCase(_tempdirTestCase): nonexistent = fs.Entry('nonexistent') assert not nonexistent.isdir() - def test_isfile(self): + def test_isfile(self) -> None: """Test the Base.isfile() method""" test = self.test test.subdir('dir') @@ -706,7 +706,7 @@ class BaseTestCase(_tempdirTestCase): @unittest.skipUnless(sys.platform != 'win32' and hasattr(os, 'symlink'), "symlink is not used on Windows") - def test_islink(self): + def test_islink(self) -> None: """Test the Base.islink() method""" test = self.test test.subdir('dir') @@ -728,27 +728,27 @@ class BaseTestCase(_tempdirTestCase): class DirNodeInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test DirNodeInfo initialization""" ddd = self.fs.Dir('ddd') ni = SCons.Node.FS.DirNodeInfo() class DirBuildInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test DirBuildInfo initialization""" ddd = self.fs.Dir('ddd') bi = SCons.Node.FS.DirBuildInfo() class FileNodeInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test FileNodeInfo initialization""" fff = self.fs.File('fff') ni = SCons.Node.FS.FileNodeInfo() assert isinstance(ni, SCons.Node.FS.FileNodeInfo) - def test_update(self): + def test_update(self) -> None: """Test updating a File.NodeInfo with on-disk information""" test = self.test fff = self.fs.File('fff') @@ -788,31 +788,31 @@ class FileNodeInfoTestCase(_tempdirTestCase): class FileBuildInfoTestCase(_tempdirTestCase): - def test___init__(self): + def test___init__(self) -> None: """Test File.BuildInfo initialization""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() assert bi, bi - def test_convert_to_sconsign(self): + def test_convert_to_sconsign(self) -> None: """Test converting to .sconsign file format""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() assert hasattr(bi, 'convert_to_sconsign') - def test_convert_from_sconsign(self): + def test_convert_from_sconsign(self) -> None: """Test converting from .sconsign file format""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() assert hasattr(bi, 'convert_from_sconsign') - def test_prepare_dependencies(self): + def test_prepare_dependencies(self) -> None: """Test that we have a prepare_dependencies() method""" fff = self.fs.File('fff') bi = SCons.Node.FS.FileBuildInfo() bi.prepare_dependencies() - def test_format(self): + def test_format(self) -> None: """Test the format() method""" f1 = self.fs.File('f1') bi1 = SCons.Node.FS.FileBuildInfo() @@ -850,7 +850,7 @@ class FileBuildInfoTestCase(_tempdirTestCase): class FSTestCase(_tempdirTestCase): - def test_needs_normpath(self): + def test_needs_normpath(self) -> None: """Test the needs_normpath Regular expression This test case verifies that the regular expression used to @@ -1048,7 +1048,7 @@ class FSTestCase(_tempdirTestCase): drive, path = os.path.splitdrive(os.getcwd()) - def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive): + def _do_Dir_test(lpath, path_, abspath_, up_path_, sep, fileSys=fs, drive=drive) -> None: dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': @@ -1194,7 +1194,7 @@ class FSTestCase(_tempdirTestCase): f1.build() assert built_it - def match(path, expect): + def match(path, expect) -> None: expect = expect.replace('/', os.sep) assert path == expect, "path %s != expected %s" % (path, expect) @@ -1569,7 +1569,7 @@ class FSTestCase(_tempdirTestCase): f.get_string(0) assert f.get_string(1) == 'baz', f.get_string(1) - def test_drive_letters(self): + def test_drive_letters(self) -> None: """Test drive-letter look-ups""" test = self.test @@ -1608,7 +1608,7 @@ class FSTestCase(_tempdirTestCase): if os.sep != '/': seps = seps + ['/'] - def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs): + def _do_Dir_test(lpath, path_, up_path_, sep, fileSys=fs) -> None: dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': @@ -1670,7 +1670,7 @@ class FSTestCase(_tempdirTestCase): os.sep = save_os_sep SCons.Node.FS.initialize_do_splitdrive() - def test_unc_path(self): + def test_unc_path(self) -> None: """Test UNC path look-ups""" test = self.test @@ -1719,7 +1719,7 @@ class FSTestCase(_tempdirTestCase): if os.sep != '/': seps = seps + ['/'] - def _do_Dir_test(lpath, path, up_path, sep, fileSys=fs): + def _do_Dir_test(lpath, path, up_path, sep, fileSys=fs) -> None: dir = fileSys.Dir(lpath.replace('/', sep)) if os.sep != '/': @@ -1784,7 +1784,7 @@ class FSTestCase(_tempdirTestCase): os.sep = save_os_sep SCons.Node.FS.initialize_do_splitdrive() - def test_target_from_source(self): + def test_target_from_source(self) -> None: """Test the method for generating target nodes from sources""" fs = self.fs @@ -1813,7 +1813,7 @@ class FSTestCase(_tempdirTestCase): assert str(t) == 'pre-eee-suf', str(t) assert t.__class__ == SCons.Node.FS.Entry - def test_same_name(self): + def test_same_name(self) -> None: """Test that a local same-named file isn't found for a Dir lookup""" test = self.test fs = self.fs @@ -1825,7 +1825,7 @@ class FSTestCase(_tempdirTestCase): fs.chdir(subdir, change_os_dir=True) self.fs._lookup('#build/file', subdir, SCons.Node.FS.File) - def test_above_root(self): + def test_above_root(self) -> None: """Testing looking up a path above the root directory""" test = self.test fs = self.fs @@ -1836,7 +1836,7 @@ class FSTestCase(_tempdirTestCase): above_path = os.path.join(*['..'] * len(dirs) + ['above']) above = d2.Dir(above_path) - def test_lookup_abs(self): + def test_lookup_abs(self) -> None: """Exercise the _lookup_abs function""" test = self.test fs = self.fs @@ -1846,7 +1846,7 @@ class FSTestCase(_tempdirTestCase): assert d.__class__ == SCons.Node.FS.Dir, str(d.__class__) @unittest.skipUnless(sys.platform == "win32", "requires Windows") - def test_lookup_uncpath(self): + def test_lookup_uncpath(self) -> None: """Testing looking up a UNC path on Windows""" test = self.test fs = self.fs @@ -1858,13 +1858,13 @@ class FSTestCase(_tempdirTestCase): 'UNC path %s got looked up as %s' % (path, f) @unittest.skipUnless(sys.platform.startswith == "win32", "requires Windows") - def test_unc_drive_letter(self): + def test_unc_drive_letter(self) -> None: """Test drive-letter lookup for windows UNC-style directories""" share = self.fs.Dir(r'\\SERVER\SHARE\Directory') assert str(share) == r'\\SERVER\SHARE\Directory', str(share) @unittest.skipUnless(sys.platform == "win32", "requires Windows") - def test_UNC_dirs_2689(self): + def test_UNC_dirs_2689(self) -> None: """Test some UNC dirs that printed incorrectly and/or caused infinite recursion errors prior to r5180 (SCons 2.1).""" fs = self.fs @@ -1873,7 +1873,7 @@ class FSTestCase(_tempdirTestCase): p = fs.Dir(r"\\\computername\sharename").get_abspath() assert p == r"\\computername\sharename", p - def test_rel_path(self): + def test_rel_path(self) -> None: """Test the rel_path() method""" test = self.test fs = self.fs @@ -1956,7 +1956,7 @@ class FSTestCase(_tempdirTestCase): failed = failed + 1 assert failed == 0, "%d rel_path() cases failed" % failed - def test_proxy(self): + def test_proxy(self) -> None: """Test a Node.FS object wrapped in a proxy instance""" f1 = self.fs.File('fff') @@ -1970,7 +1970,7 @@ class FSTestCase(_tempdirTestCase): class DirTestCase(_tempdirTestCase): - def test__morph(self): + def test__morph(self) -> None: """Test handling of actions when morphing an Entry into a Dir""" test = self.test e = self.fs.Entry('eee') @@ -1982,7 +1982,7 @@ class DirTestCase(_tempdirTestCase): assert 'pre' in a, a assert 'post' in a, a - def test_subclass(self): + def test_subclass(self) -> None: """Test looking up subclass of Dir nodes""" class DirSubclass(SCons.Node.FS.Dir): @@ -1991,7 +1991,7 @@ class DirTestCase(_tempdirTestCase): sd = self.fs._lookup('special_dir', None, DirSubclass, create=1) sd.must_be_same(SCons.Node.FS.Dir) - def test_get_env_scanner(self): + def test_get_env_scanner(self) -> None: """Test the Dir.get_env_scanner() method """ import SCons.Defaults @@ -1999,7 +1999,7 @@ class DirTestCase(_tempdirTestCase): s = d.get_env_scanner(Environment()) assert s is SCons.Defaults.DirEntryScanner, s - def test_get_target_scanner(self): + def test_get_target_scanner(self) -> None: """Test the Dir.get_target_scanner() method """ import SCons.Defaults @@ -2007,7 +2007,7 @@ class DirTestCase(_tempdirTestCase): s = d.get_target_scanner() assert s is SCons.Defaults.DirEntryScanner, s - def test_scan(self): + def test_scan(self) -> None: """Test scanning a directory for in-memory entries """ fs = self.fs @@ -2026,7 +2026,7 @@ class DirTestCase(_tempdirTestCase): os.path.join('ddd', 'f2'), os.path.join('ddd', 'f3')], kids - def test_get_contents(self): + def test_get_contents(self) -> None: """Test getting the contents for a directory. """ test = self.test @@ -2113,7 +2113,7 @@ class DirTestCase(_tempdirTestCase): assert self.actual_get_contents_calls == len(expected_get_contents_calls), \ self.actual_get_contents_calls - def test_implicit_re_scans(self): + def test_implicit_re_scans(self) -> None: """Test that adding entries causes a directory to be re-scanned """ @@ -2132,7 +2132,7 @@ class DirTestCase(_tempdirTestCase): assert kids == [os.path.join('ddd', 'f1'), os.path.join('ddd', 'f2')], kids - def test_entry_exists_on_disk(self): + def test_entry_exists_on_disk(self) -> None: """Test the Dir.entry_exists_on_disk() method """ test = self.test @@ -2151,7 +2151,7 @@ class DirTestCase(_tempdirTestCase): if os.path.normcase("TeSt") != os.path.normpath("TeSt") or sys.platform == "cygwin": assert d.entry_exists_on_disk('case-insensitive') - def test_rentry_exists_on_disk(self): + def test_rentry_exists_on_disk(self) -> None: """Test the Dir.rentry_exists_on_disk() method """ test = self.test @@ -2177,7 +2177,7 @@ class DirTestCase(_tempdirTestCase): if os.path.normcase("TeSt") != os.path.normpath("TeSt") or sys.platform == "cygwin": assert d.rentry_exists_on_disk('case-insensitive') - def test_srcdir_list(self): + def test_srcdir_list(self) -> None: """Test the Dir.srcdir_list() method """ src = self.fs.Dir('src') @@ -2188,7 +2188,7 @@ class DirTestCase(_tempdirTestCase): self.fs.VariantDir(bld, src, duplicate=0) self.fs.VariantDir(sub2, src, duplicate=0) - def check(result, expect): + def check(result, expect) -> None: result = list(map(str, result)) expect = list(map(os.path.normpath, expect)) assert result == expect, result @@ -2230,7 +2230,7 @@ class DirTestCase(_tempdirTestCase): s = b1_b2_b1_b2_sub.srcdir_list() check(s, ['src/b1/b2/sub']) - def test_srcdir_duplicate(self): + def test_srcdir_duplicate(self) -> None: """Test the Dir.srcdir_duplicate() method """ test = self.test @@ -2265,12 +2265,12 @@ class DirTestCase(_tempdirTestCase): assert str(n) == os.path.normpath('bld1/exists'), str(n) assert os.path.exists(test.workpath('bld1', 'exists')) - def test_srcdir_find_file(self): + def test_srcdir_find_file(self) -> None: """Test the Dir.srcdir_find_file() method """ test = self.test - def return_true(node): + def return_true(node) -> int: return 1 SCons.Node._is_derived_map[2] = return_true @@ -2296,7 +2296,7 @@ class DirTestCase(_tempdirTestCase): exists_e = src0.Entry('exists-e') exists_e._func_exists = 5 - def check(result, expect): + def check(result, expect) -> None: result = list(map(str, result)) expect = list(map(os.path.normpath, expect)) assert result == expect, result @@ -2393,7 +2393,7 @@ class DirTestCase(_tempdirTestCase): n = bld1.srcdir_find_file('on-disk-e2') check(n, ['bld1/on-disk-e2', 'bld1']) - def test_dir_on_disk(self): + def test_dir_on_disk(self) -> None: """Test the Dir.dir_on_disk() method""" self.test.subdir('sub', ['sub', 'exists']) self.test.write(['sub', 'file'], "self/file\n") @@ -2408,7 +2408,7 @@ class DirTestCase(_tempdirTestCase): r = sub.dir_on_disk('file') assert not r, r - def test_file_on_disk(self): + def test_file_on_disk(self) -> None: """Test the Dir.file_on_disk() method""" self.test.subdir('sub', ['sub', 'dir']) self.test.write(['sub', 'exists'], "self/exists\n") @@ -2425,7 +2425,7 @@ class DirTestCase(_tempdirTestCase): class EntryTestCase(_tempdirTestCase): - def test_runTest(self): + def test_runTest(self) -> None: """Test methods specific to the Entry sub-class. """ test = TestCmd(workdir='') @@ -2472,11 +2472,11 @@ class EntryTestCase(_tempdirTestCase): assert not exists, "e4n exists?" class MyCalc: - def __init__(self, val): + def __init__(self, val) -> None: self.max_drift = 0 class M: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def collect(self, args): @@ -2493,7 +2493,7 @@ class EntryTestCase(_tempdirTestCase): test.subdir('e5d') test.write('e5f', "e5f\n") - def test_Entry_Entry_lookup(self): + def test_Entry_Entry_lookup(self) -> None: """Test looking up an Entry within another Entry""" self.fs.Entry('#topdir') self.fs.Entry('#topdir/a/b/c') @@ -2501,7 +2501,7 @@ class EntryTestCase(_tempdirTestCase): class FileTestCase(_tempdirTestCase): - def test_subclass(self): + def test_subclass(self) -> None: """Test looking up subclass of File nodes""" class FileSubclass(SCons.Node.FS.File): @@ -2510,7 +2510,7 @@ class FileTestCase(_tempdirTestCase): sd = self.fs._lookup('special_file', None, FileSubclass, create=1) sd.must_be_same(SCons.Node.FS.File) - def test_Dirs(self): + def test_Dirs(self) -> None: """Test the File.Dirs() method""" fff = self.fs.File('subdir/fff') # This simulates that the SConscript file that defined @@ -2521,7 +2521,7 @@ class FileTestCase(_tempdirTestCase): dirs = fff.Dirs(['d1', 'd2']) assert dirs == [d1, d2], list(map(str, dirs)) - def test_exists(self): + def test_exists(self) -> None: """Test the File.exists() method""" fs = self.fs test = self.test @@ -2553,7 +2553,7 @@ class FileTestCase(_tempdirTestCase): assert not os.path.exists(build_f1.get_abspath()), "%s did not get removed after %s was removed" % ( build_f1, src_f1) - def test_changed(self): + def test_changed(self) -> None: """ Verify that changes between BuildInfo's list of souces, depends, and implicit dependencies do not corrupt content signature values written to .SConsign @@ -2567,7 +2567,7 @@ class FileTestCase(_tempdirTestCase): # N implicits (for example ['alpha.h', 'beta.h', 'gamma.h', '/usr/bin/g++']) class ChangedNode(SCons.Node.FS.File): - def __init__(self, name, directory=None, fs=None): + def __init__(self, name, directory=None, fs=None) -> None: super().__init__(name, directory, fs) self.name = name self.Tag('found_includes', []) @@ -2607,12 +2607,12 @@ class FileTestCase(_tempdirTestCase): class ChangedEnvironment(SCons.Environment.Base): - def __init__(self): + def __init__(self) -> None: super().__init__() self.decide_source = self._changed_timestamp_then_content class FakeNodeInfo: - def __init__(self, csig, timestamp): + def __init__(self, csig, timestamp) -> None: self.csig = csig self.timestamp = timestamp @@ -2693,7 +2693,7 @@ class FileTestCase(_tempdirTestCase): class GlobTestCase(_tempdirTestCase): - def setUp(self): + def setUp(self) -> None: _tempdirTestCase.setUp(self) fs = SCons.Node.FS.FS() @@ -2758,7 +2758,7 @@ class GlobTestCase(_tempdirTestCase): self.sub_dir3_jjj = self.sub_dir3.File('jjj') self.sub_dir3_lll = self.sub_dir3.File('lll') - def do_cases(self, cases, **kwargs): + def do_cases(self, cases, **kwargs) -> None: # First, execute all of the cases with string=True and verify # that we get the expected strings returned. We do this first @@ -2800,7 +2800,7 @@ class GlobTestCase(_tempdirTestCase): pprint.pprint(list(map(fmt, r))) self.fail() - def test_exact_match(self): + def test_exact_match(self) -> None: """Test globbing for exact Node matches""" join = os.path.join @@ -2820,7 +2820,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_subdir_matches(self): + def test_subdir_matches(self) -> None: """Test globbing for exact Node matches in subdirectories""" join = os.path.join @@ -2836,7 +2836,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_asterisk1(self): + def test_asterisk1(self) -> None: """Test globbing for simple asterisk Node matches (1)""" cases = ( ('h*', @@ -2858,7 +2858,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases, ondisk=False) - def test_asterisk2(self): + def test_asterisk2(self) -> None: """Test globbing for simple asterisk Node matches (2)""" cases = ( ('disk-b*', @@ -2882,7 +2882,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_question_mark(self): + def test_question_mark(self) -> None: """Test globbing for simple question-mark Node matches""" join = os.path.join @@ -2906,7 +2906,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_does_not_exist(self): + def test_does_not_exist(self) -> None: """Test globbing for things that don't exist""" cases = ( @@ -2917,7 +2917,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_subdir_asterisk(self): + def test_subdir_asterisk(self) -> None: """Test globbing for asterisk Node matches in subdirectories""" join = os.path.join @@ -2979,7 +2979,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_subdir_question(self): + def test_subdir_question(self) -> None: """Test globbing for question-mark Node matches in subdirectories""" join = os.path.join @@ -3003,7 +3003,7 @@ class GlobTestCase(_tempdirTestCase): self.do_cases(cases) - def test_sort(self): + def test_sort(self) -> None: """Test whether globbing sorts""" join = os.path.join # At least sometimes this should return out-of-order items @@ -3025,7 +3025,7 @@ class GlobTestCase(_tempdirTestCase): class RepositoryTestCase(_tempdirTestCase): - def setUp(self): + def setUp(self) -> None: _tempdirTestCase.setUp(self) self.test.subdir('rep1', 'rep2', 'rep3', 'work') @@ -3039,7 +3039,7 @@ class RepositoryTestCase(_tempdirTestCase): self.fs = SCons.Node.FS.FS() self.fs.Repository(self.rep1, self.rep2, self.rep3) - def test_getRepositories(self): + def test_getRepositories(self) -> None: """Test the Dir.getRepositories() method""" self.fs.Repository('foo') self.fs.Repository(os.path.join('foo', 'bar')) @@ -3060,7 +3060,7 @@ class RepositoryTestCase(_tempdirTestCase): r = [os.path.normpath(str(x)) for x in rep] assert r == expect, r - def test_get_all_rdirs(self): + def test_get_all_rdirs(self) -> None: """Test the Dir.get_all_rdirs() method""" self.fs.Repository('foo') self.fs.Repository(os.path.join('foo', 'bar')) @@ -3082,7 +3082,7 @@ class RepositoryTestCase(_tempdirTestCase): r = [os.path.normpath(str(x)) for x in rep] assert r == expect, r - def test_rentry(self): + def test_rentry(self) -> None: """Test the Base.entry() method""" return_true = lambda: 1 return_false = lambda: 0 @@ -3150,13 +3150,13 @@ class RepositoryTestCase(_tempdirTestCase): r = str(r) assert r == os.path.join(self.rep2, 'f3'), r - def test_rdir(self): + def test_rdir(self) -> None: """Test the Dir.rdir() method""" - def return_true(obj): + def return_true(obj) -> int: return 1 - def return_false(obj): + def return_false(obj) -> int: return 0 SCons.Node._exists_map[5] = return_true @@ -3206,13 +3206,13 @@ class RepositoryTestCase(_tempdirTestCase): r = e2.rdir() assert r is re2, r - def test_rfile(self): + def test_rfile(self) -> None: """Test the File.rfile() method""" - def return_true(obj): + def return_true(obj) -> int: return 1 - def return_false(obj): + def return_false(obj) -> int: return 0 SCons.Node._exists_map[5] = return_true @@ -3262,7 +3262,7 @@ class RepositoryTestCase(_tempdirTestCase): r = e2.rfile() assert r is re2, r - def test_Rfindalldirs(self): + def test_Rfindalldirs(self) -> None: """Test the Rfindalldirs() methods""" fs = self.fs test = self.test @@ -3299,7 +3299,7 @@ class RepositoryTestCase(_tempdirTestCase): r = fs.Top.Rfindalldirs(('d1', d2)) assert r == [d1, rep1_d1, rep2_d1, rep3_d1, d2], list(map(str, r)) - def test_rexists(self): + def test_rexists(self) -> None: """Test the Entry.rexists() method""" fs = self.fs test = self.test @@ -3325,7 +3325,7 @@ class RepositoryTestCase(_tempdirTestCase): f2 = fs.File(os.path.join('build', 'f2')) assert f2.rexists() - def test_FAT_timestamps(self): + def test_FAT_timestamps(self) -> None: """Test repository timestamps on FAT file systems""" fs = self.fs test = self.test @@ -3345,7 +3345,7 @@ class RepositoryTestCase(_tempdirTestCase): finally: test.unlink(["rep2", "tstamp"]) - def test_get_contents(self): + def test_get_contents(self) -> None: """Ensure get_contents() returns binary contents from Repositories""" fs = self.fs test = self.test @@ -3357,7 +3357,7 @@ class RepositoryTestCase(_tempdirTestCase): finally: test.unlink(["rep3", "contents"]) - def test_get_text_contents(self): + def test_get_text_contents(self) -> None: """Ensure get_text_contents() returns text contents from Repositories""" fs = self.fs @@ -3395,7 +3395,7 @@ class RepositoryTestCase(_tempdirTestCase): class find_fileTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Testing find_file function""" test = TestCmd(workdir='') test.write('./foo', 'Some file\n') @@ -3468,7 +3468,7 @@ class find_fileTestCase(unittest.TestCase): class StringDirTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test using a string as the second argument of File() and Dir()""" @@ -3485,7 +3485,7 @@ class StringDirTestCase(unittest.TestCase): class stored_infoTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test how we store build information""" test = TestCmd(workdir='') test.subdir('sub') @@ -3498,7 +3498,7 @@ class stored_infoTestCase(unittest.TestCase): class MySConsign: class Null: - def __init__(self): + def __init__(self) -> None: self.xyzzy = 7 def get_entry(self, name): @@ -3515,7 +3515,7 @@ class stored_infoTestCase(unittest.TestCase): class has_src_builderTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test the has_src_builder() method""" test = TestCmd(workdir='') fs = SCons.Node.FS.FS(test.workpath('')) @@ -3552,7 +3552,7 @@ class has_src_builderTestCase(unittest.TestCase): class prepareTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test the prepare() method""" class MyFile(SCons.Node.FS.File): @@ -3573,10 +3573,10 @@ class prepareTestCase(unittest.TestCase): assert exc_caught, "Should have caught a StopError." class MkdirAction(Action): - def __init__(self, dir_made): + def __init__(self, dir_made) -> None: self.dir_made = dir_made - def __call__(self, target, source, env, executor=None): + def __call__(self, target, source, env, executor=None) -> None: if executor: target = executor.get_all_targets() source = executor.get_all_sources() @@ -3603,7 +3603,7 @@ class prepareTestCase(unittest.TestCase): @unittest.skipUnless(hasattr(os, 'symlink'), "Platform doesn't support symlink") class CleanSymlinksTestCase(_tempdirTestCase): - def test_cleans_symlinks(self): + def test_cleans_symlinks(self) -> None: """Test the prepare() method will cleanup symlinks.""" test = self.test @@ -3629,7 +3629,7 @@ class CleanSymlinksTestCase(_tempdirTestCase): except FileNotFoundError: test.fail('Real file %s should not be removed'%test.workpath('foo')) - def test_cleans_dangling_symlinks(self): + def test_cleans_dangling_symlinks(self) -> None: """Test the prepare() method will cleanup dangling symlinks.""" test = self.test @@ -3660,7 +3660,7 @@ class CleanSymlinksTestCase(_tempdirTestCase): class SConstruct_dirTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test setting the SConstruct directory""" fs = SCons.Node.FS.FS() @@ -3670,7 +3670,7 @@ class SConstruct_dirTestCase(unittest.TestCase): class CacheDirTestCase(unittest.TestCase): - def test_get_cachedir_csig(self): + def test_get_cachedir_csig(self) -> None: fs = SCons.Node.FS.FS() f9 = fs.File('f9') @@ -3680,7 +3680,7 @@ class CacheDirTestCase(unittest.TestCase): class clearTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test clearing FS nodes of cached data.""" fs = SCons.Node.FS.FS() test = TestCmd(workdir='') @@ -3735,7 +3735,7 @@ class clearTestCase(unittest.TestCase): class disambiguateTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test calling the disambiguate() method.""" test = TestCmd(workdir='') @@ -3797,7 +3797,7 @@ class disambiguateTestCase(unittest.TestCase): class postprocessTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test calling the postprocess() method.""" fs = SCons.Node.FS.FS() @@ -3812,7 +3812,7 @@ class postprocessTestCase(unittest.TestCase): class SpecialAttrTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test special attributes of file nodes.""" test = TestCmd(workdir='') fs = SCons.Node.FS.FS(test.workpath('work')) @@ -3970,7 +3970,7 @@ class SpecialAttrTestCase(unittest.TestCase): class SaveStringsTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test caching string values of nodes.""" test = TestCmd(workdir='') @@ -3990,7 +3990,7 @@ class SaveStringsTestCase(unittest.TestCase): return [d0_f, d1_f, d0_b, d1_b] - def modify(nodes): + def modify(nodes) -> None: d0_f, d1_f, d0_b, d1_b = nodes d1_f.duplicate = 0 d1_b.duplicate = 0 @@ -4030,7 +4030,7 @@ class SaveStringsTestCase(unittest.TestCase): class AbsolutePathTestCase(unittest.TestCase): - def test_root_lookup_equivalence(self): + def test_root_lookup_equivalence(self) -> None: """Test looking up /fff vs. fff in the / directory""" test = TestCmd(workdir='') diff --git a/SCons/Node/NodeTests.py b/SCons/Node/NodeTests.py index ee4d08007..e7c9e9adc 100644 --- a/SCons/Node/NodeTests.py +++ b/SCons/Node/NodeTests.py @@ -60,10 +60,10 @@ class MyActionBase: return _actionAppend(other, self) class MyAction(MyActionBase): - def __init__(self): + def __init__(self) -> None: self.order = 0 - def __call__(self, target, source, env, executor=None): + def __call__(self, target, source, env, executor=None) -> int: global built_it, built_target, built_source, built_args, built_order if executor: target = executor.get_all_targets() @@ -80,23 +80,23 @@ class MyAction(MyActionBase): return [] class MyExecutor: - def __init__(self, env=None, targets=[], sources=[]): + def __init__(self, env=None, targets=[], sources=[]) -> None: self.env = env self.targets = targets self.sources = sources def get_build_env(self): return self.env - def get_build_scanner_path(self, scanner): + def get_build_scanner_path(self, scanner) -> str: return 'executor would call %s' % scanner - def cleanup(self): + def cleanup(self) -> None: self.cleaned_up = 1 - def scan_targets(self, scanner): + def scan_targets(self, scanner) -> None: if not scanner: return d = scanner(self.targets) for t in self.targets: t.implicit.extend(d) - def scan_sources(self, scanner): + def scan_sources(self, scanner) -> None: if not scanner: return d = scanner(self.sources) @@ -104,14 +104,14 @@ class MyExecutor: t.implicit.extend(d) class MyListAction(MyActionBase): - def __init__(self, list): + def __init__(self, list) -> None: self.list = list - def __call__(self, target, source, env): + def __call__(self, target, source, env) -> None: for A in self.list: A(target, source, env) class Environment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {} self._dict.update(kw) def __getitem__(self, key): @@ -124,7 +124,7 @@ class Environment: d = self._dict.copy() d.update(overrides) return Environment(**d) - def _update(self, dict): + def _update(self, dict) -> None: self._dict.update(dict) def get_factory(self, factory): return factory or MyNode @@ -137,7 +137,7 @@ class Environment: return [] class Builder: - def __init__(self, env=None, is_explicit=1): + def __init__(self, env=None, is_explicit: int=1) -> None: if env is None: env = Environment() self.env = env self.overrides = {} @@ -150,7 +150,7 @@ class Builder: return [t] def get_actions(self): return [self.action] - def get_contents(self, target, source, env): + def get_contents(self, target, source, env) -> int: return 7 class NoneBuilder(Builder): @@ -159,7 +159,7 @@ class NoneBuilder(Builder): return None class ListBuilder(Builder): - def __init__(self, *nodes): + def __init__(self, *nodes) -> None: super().__init__() self.nodes = nodes def execute(self, target, source, env): @@ -171,7 +171,7 @@ class ListBuilder(Builder): self.status = Builder.execute(self, target, source, env) class FailBuilder: - def execute(self, target, source, env): + def execute(self, target, source, env) -> int: return 1 class ExceptBuilder: @@ -199,20 +199,20 @@ class MyNode(SCons.Node.Node): we expect to be overridden by real, functional Node subclasses. So simulate a real, functional Node subclass. """ - def __init__(self, name): + def __init__(self, name) -> None: super().__init__() self.name = name self.Tag('found_includes', []) - def __str__(self): + def __str__(self) -> str: return self.name def get_found_includes(self, env, scanner, target): return scanner(self) class Calculator: - def __init__(self, val): + def __init__(self, val) -> None: self.max_drift = 0 class M: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val def signature(self, args): return self.val @@ -230,7 +230,7 @@ class NodeInfoBaseTestCase(unittest.TestCase): # the merge and format test (arbitrary attributes do not work). Do it with a # derived class that does provide the slots. - def test_merge(self): + def test_merge(self) -> None: """Test merging NodeInfoBase attributes""" class TestNodeInfo(SCons.Node.NodeInfoBase): @@ -250,12 +250,12 @@ class NodeInfoBaseTestCase(unittest.TestCase): assert ni1.a2 == 222, ni1.a2 assert ni1.a3 == 333, ni1.a3 - def test_update(self): + def test_update(self) -> None: """Test the update() method""" ni = SCons.Node.NodeInfoBase() ni.update(SCons.Node.Node()) - def test_format(self): + def test_format(self) -> None: """Test the NodeInfoBase.format() method""" class TestNodeInfo(SCons.Node.NodeInfoBase): @@ -278,13 +278,13 @@ class NodeInfoBaseTestCase(unittest.TestCase): class BuildInfoBaseTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test BuildInfoBase initialization""" n = SCons.Node.Node() bi = SCons.Node.BuildInfoBase() assert bi - def test_merge(self): + def test_merge(self) -> None: """Test merging BuildInfoBase attributes""" n1 = SCons.Node.Node() bi1 = SCons.Node.BuildInfoBase() @@ -305,7 +305,7 @@ class BuildInfoBaseTestCase(unittest.TestCase): class NodeTestCase(unittest.TestCase): - def test_build(self): + def test_build(self) -> None: """Test building a node """ global built_it, built_order @@ -379,7 +379,7 @@ class NodeTestCase(unittest.TestCase): assert built_args["on"] == 3, built_args assert built_args["off"] == 4, built_args - def test_get_build_scanner_path(self): + def test_get_build_scanner_path(self) -> None: """Test the get_build_scanner_path() method""" n = SCons.Node.Node() x = MyExecutor() @@ -387,7 +387,7 @@ class NodeTestCase(unittest.TestCase): p = n.get_build_scanner_path('fake_scanner') assert p == "executor would call fake_scanner", p - def test_get_executor(self): + def test_get_executor(self) -> None: """Test the get_executor() method""" n = SCons.Node.Node() @@ -414,13 +414,13 @@ class NodeTestCase(unittest.TestCase): x = n.get_executor() assert x.env == 'env2', x.env - def test_set_executor(self): + def test_set_executor(self) -> None: """Test the set_executor() method""" n = SCons.Node.Node() n.set_executor(1) assert n.executor == 1, n.executor - def test_executor_cleanup(self): + def test_executor_cleanup(self) -> None: """Test letting the executor cleanup its cache""" n = SCons.Node.Node() x = MyExecutor() @@ -428,7 +428,7 @@ class NodeTestCase(unittest.TestCase): n.executor_cleanup() assert x.cleaned_up - def test_reset_executor(self): + def test_reset_executor(self) -> None: """Test the reset_executor() method""" n = SCons.Node.Node() n.set_executor(1) @@ -436,14 +436,14 @@ class NodeTestCase(unittest.TestCase): n.reset_executor() assert not hasattr(n, 'executor'), "unexpected executor attribute" - def test_built(self): + def test_built(self) -> None: """Test the built() method""" class SubNodeInfo(SCons.Node.NodeInfoBase): __slots__ = ('updated',) - def update(self, node): + def update(self, node) -> None: self.updated = 1 class SubNode(SCons.Node.Node): - def clear(self): + def clear(self) -> None: self.cleared = 1 n = SubNode() @@ -452,19 +452,19 @@ class NodeTestCase(unittest.TestCase): assert n.cleared, n.cleared assert n.ninfo.updated, n.ninfo.cleared - def test_push_to_cache(self): + def test_push_to_cache(self) -> None: """Test the base push_to_cache() method""" n = SCons.Node.Node() r = n.push_to_cache() assert r is None, r - def test_retrieve_from_cache(self): + def test_retrieve_from_cache(self) -> None: """Test the base retrieve_from_cache() method""" n = SCons.Node.Node() r = n.retrieve_from_cache() assert r == 0, r - def test_visited(self): + def test_visited(self) -> None: """Test the base visited() method Just make sure it's there and we can call it. @@ -472,7 +472,7 @@ class NodeTestCase(unittest.TestCase): n = SCons.Node.Node() n.visited() - def test_builder_set(self): + def test_builder_set(self) -> None: """Test setting a Node's Builder """ node = SCons.Node.Node() @@ -480,7 +480,7 @@ class NodeTestCase(unittest.TestCase): node.builder_set(b) assert node.builder == b - def test_has_builder(self): + def test_has_builder(self) -> None: """Test the has_builder() method """ n1 = SCons.Node.Node() @@ -488,7 +488,7 @@ class NodeTestCase(unittest.TestCase): n1.builder_set(Builder()) assert n1.has_builder() == 1 - def test_has_explicit_builder(self): + def test_has_explicit_builder(self) -> None: """Test the has_explicit_builder() method """ n1 = SCons.Node.Node() @@ -498,7 +498,7 @@ class NodeTestCase(unittest.TestCase): n1.set_explicit(None) assert not n1.has_explicit_builder() - def test_get_builder(self): + def test_get_builder(self) -> None: """Test the get_builder() method""" n1 = SCons.Node.Node() b = n1.get_builder() @@ -511,7 +511,7 @@ class NodeTestCase(unittest.TestCase): b = n1.get_builder(999) assert b == 888, b - def test_multiple_side_effect_has_builder(self): + def test_multiple_side_effect_has_builder(self) -> None: """Test the multiple_side_effect_has_builder() method """ n1 = SCons.Node.Node() @@ -519,7 +519,7 @@ class NodeTestCase(unittest.TestCase): n1.builder_set(Builder()) assert n1.multiple_side_effect_has_builder() == 1 - def test_is_derived(self): + def test_is_derived(self) -> None: """Test the is_derived() method """ n1 = SCons.Node.Node() @@ -533,7 +533,7 @@ class NodeTestCase(unittest.TestCase): assert n2.is_derived() == 1 assert n3.is_derived() == 1 - def test_alter_targets(self): + def test_alter_targets(self) -> None: """Test the alter_targets() method """ n = SCons.Node.Node() @@ -541,13 +541,13 @@ class NodeTestCase(unittest.TestCase): assert t == [], t assert m is None, m - def test_is_up_to_date(self): + def test_is_up_to_date(self) -> None: """Test the default is_up_to_date() method """ node = SCons.Node.Node() assert node.is_up_to_date() is None - def test_children_are_up_to_date(self): + def test_children_are_up_to_date(self) -> None: """Test the children_are_up_to_date() method used by subclasses """ n1 = SCons.Node.Node() @@ -562,7 +562,7 @@ class NodeTestCase(unittest.TestCase): n1.always_build = 1 assert not n1.children_are_up_to_date(), "expected not up to date" - def test_env_set(self): + def test_env_set(self) -> None: """Test setting a Node's Environment """ node = SCons.Node.Node() @@ -570,7 +570,7 @@ class NodeTestCase(unittest.TestCase): node.env_set(e) assert node.env == e - def test_get_actions(self): + def test_get_actions(self) -> None: """Test fetching a Node's action list """ node = SCons.Node.Node() @@ -578,7 +578,7 @@ class NodeTestCase(unittest.TestCase): a = node.builder.get_actions() assert isinstance(a[0], MyAction), a[0] - def test_get_csig(self): + def test_get_csig(self) -> None: """Test generic content signature calculation """ @@ -586,7 +586,7 @@ class NodeTestCase(unittest.TestCase): __slots__ = ('csig',) try: SCons.Node.Node.NodeInfo = TestNodeInfo - def my_contents(obj): + def my_contents(obj) -> int: return 444 SCons.Node._get_contents_map[4] = my_contents node = SCons.Node.Node() @@ -596,14 +596,14 @@ class NodeTestCase(unittest.TestCase): finally: SCons.Node.Node.NodeInfo = SCons.Node.NodeInfoBase - def test_get_cachedir_csig(self): + def test_get_cachedir_csig(self) -> None: """Test content signature calculation for CacheDir """ class TestNodeInfo(SCons.Node.NodeInfoBase): __slots__ = ('csig',) try: SCons.Node.Node.NodeInfo = TestNodeInfo - def my_contents(obj): + def my_contents(obj) -> int: return 555 SCons.Node._get_contents_map[4] = my_contents node = SCons.Node.Node() @@ -613,7 +613,7 @@ class NodeTestCase(unittest.TestCase): finally: SCons.Node.Node.NodeInfo = SCons.Node.NodeInfoBase - def test_get_binfo(self): + def test_get_binfo(self) -> None: """Test fetching/creating a build information structure """ class TestNodeInfo(SCons.Node.NodeInfoBase): @@ -643,11 +643,11 @@ class NodeTestCase(unittest.TestCase): assert binfo.bimplicit == [i] assert hasattr(binfo, 'bimplicitsigs') - def test_explain(self): + def test_explain(self) -> None: """Test explaining why a Node must be rebuilt """ class testNode(SCons.Node.Node): - def __str__(self): return 'xyzzy' + def __str__(self) -> str: return 'xyzzy' node = testNode() node.exists = lambda: None # Can't do this with new-style classes (python bug #1066490) @@ -656,7 +656,7 @@ class NodeTestCase(unittest.TestCase): assert result == "building `xyzzy' because it doesn't exist\n", result class testNode2(SCons.Node.Node): - def __str__(self): return 'null_binfo' + def __str__(self) -> str: return 'null_binfo' class FS: pass node = testNode2() @@ -668,7 +668,7 @@ class NodeTestCase(unittest.TestCase): def get_null_info(): class Null_SConsignEntry: class Null_BuildInfo: - def prepare_dependencies(self): + def prepare_dependencies(self) -> None: pass binfo = Null_BuildInfo() return Null_SConsignEntry() @@ -688,20 +688,20 @@ class NodeTestCase(unittest.TestCase): # node.del_binfo() # assert not hasattr(node, 'binfo'), node - def test_store_info(self): + def test_store_info(self) -> None: """Test calling the method to store build information """ node = SCons.Node.Node() SCons.Node.store_info_map[node.store_info](node) - def test_get_stored_info(self): + def test_get_stored_info(self) -> None: """Test calling the method to fetch stored build information """ node = SCons.Node.Node() result = node.get_stored_info() assert result is None, result - def test_set_always_build(self): + def test_set_always_build(self) -> None: """Test setting a Node's always_build value """ node = SCons.Node.Node() @@ -710,7 +710,7 @@ class NodeTestCase(unittest.TestCase): node.set_always_build(3) assert node.always_build == 3 - def test_set_noclean(self): + def test_set_noclean(self) -> None: """Test setting a Node's noclean value """ node = SCons.Node.Node() @@ -723,7 +723,7 @@ class NodeTestCase(unittest.TestCase): node.set_noclean(None) assert node.noclean == 0, node.noclean - def test_set_precious(self): + def test_set_precious(self) -> None: """Test setting a Node's precious value """ node = SCons.Node.Node() @@ -732,7 +732,7 @@ class NodeTestCase(unittest.TestCase): node.set_precious(7) assert node.precious == 7 - def test_set_pseudo(self): + def test_set_pseudo(self) -> None: """Test setting a Node's pseudo value """ node = SCons.Node.Node() @@ -741,14 +741,14 @@ class NodeTestCase(unittest.TestCase): node.set_pseudo(False) assert not node.pseudo - def test_exists(self): + def test_exists(self) -> None: """Test evaluating whether a Node exists. """ node = SCons.Node.Node() e = node.exists() assert e == 1, e - def test_exists_repo(self): + def test_exists_repo(self) -> None: """Test evaluating whether a Node exists locally or in a repository. """ node = SCons.Node.Node() @@ -756,14 +756,14 @@ class NodeTestCase(unittest.TestCase): assert e == 1, e class MyNode(SCons.Node.Node): - def exists(self): + def exists(self) -> str: return 'xyz' node = MyNode() e = node.rexists() assert e == 'xyz', e - def test_prepare(self): + def test_prepare(self) -> None: """Test preparing a node to be built By extension, this also tests the missing() method. @@ -902,7 +902,7 @@ class NodeTestCase(unittest.TestCase): raise Exception("did not catch expected exception") assert node.ignore == [zero, one, two, three, four] - def test_get_found_includes(self): + def test_get_found_includes(self) -> None: """Test the default get_found_includes() method """ node = SCons.Node.Node() @@ -911,7 +911,7 @@ class NodeTestCase(unittest.TestCase): deps = node.get_found_includes(e, None, target) assert deps == [], deps - def test_get_implicit_deps(self): + def test_get_implicit_deps(self) -> None: """Test get_implicit_deps() """ node = MyNode("nnn") @@ -958,7 +958,7 @@ class NodeTestCase(unittest.TestCase): deps = node.get_implicit_deps(env, s, s.path) assert deps == [d1, d2], list(map(str, deps)) - def test_get_env_scanner(self): + def test_get_env_scanner(self) -> None: """Test fetching the environment scanner for a Node """ node = SCons.Node.Node() @@ -969,7 +969,7 @@ class NodeTestCase(unittest.TestCase): s = node.get_env_scanner(env, {'X':1}) assert s == scanner, s - def test_get_target_scanner(self): + def test_get_target_scanner(self) -> None: """Test fetching the target scanner for a Node """ s = Scanner() @@ -980,7 +980,7 @@ class NodeTestCase(unittest.TestCase): x = n.get_target_scanner() assert x is s, x - def test_get_source_scanner(self): + def test_get_source_scanner(self) -> None: """Test fetching the source scanner for a Node """ target = SCons.Node.Node() @@ -998,7 +998,7 @@ class NodeTestCase(unittest.TestCase): r.builder = self return [r] class Builder2(Builder1): - def __init__(self, scanner): + def __init__(self, scanner) -> None: self.source_scanner = scanner builder = Builder2(ts1) @@ -1020,7 +1020,7 @@ class NodeTestCase(unittest.TestCase): assert s is ts3, s - def test_scan(self): + def test_scan(self) -> None: """Test Scanner functionality """ env = Environment() @@ -1068,11 +1068,11 @@ class NodeTestCase(unittest.TestCase): SCons.Node.implicit_deps_changed = save_implicit_deps_changed SCons.Node.implicit_deps_unchanged = save_implicit_deps_unchanged - def test_scanner_key(self): + def test_scanner_key(self) -> None: """Test that a scanner_key() method exists""" assert SCons.Node.Node().scanner_key() is None - def test_children(self): + def test_children(self) -> None: """Test fetching the non-ignored "children" of a Node. """ node = SCons.Node.Node() @@ -1103,7 +1103,7 @@ class NodeTestCase(unittest.TestCase): for kid in [n2, n5, n8, n11]: assert kid not in kids, kid - def test_all_children(self): + def test_all_children(self) -> None: """Test fetching all the "children" of a Node. """ node = SCons.Node.Node() @@ -1132,7 +1132,7 @@ class NodeTestCase(unittest.TestCase): for kid in [n1, n2, n3, n4, n5, n6, n7, n8, n9, n10, n11, n12]: assert kid in kids, kid - def test_state(self): + def test_state(self) -> None: """Test setting and getting the state of a node """ node = SCons.Node.Node() @@ -1144,7 +1144,7 @@ class NodeTestCase(unittest.TestCase): assert SCons.Node.up_to_date < SCons.Node.executed assert SCons.Node.executed < SCons.Node.failed - def test_walker(self): + def test_walker(self) -> None: """Test walking a Node tree. """ @@ -1194,7 +1194,7 @@ class NodeTestCase(unittest.TestCase): n8.add_dependency([n3]) n7.add_dependency([n8]) - def cycle(node, stack): + def cycle(node, stack) -> None: global cycle_detected cycle_detected = 1 @@ -1212,20 +1212,20 @@ class NodeTestCase(unittest.TestCase): n = nw.get_next() assert nw.get_next() is None - def test_abspath(self): + def test_abspath(self) -> None: """Test the get_abspath() method.""" n = MyNode("foo") assert n.get_abspath() == str(n), n.get_abspath() - def test_for_signature(self): + def test_for_signature(self) -> None: """Test the for_signature() method.""" n = MyNode("foo") assert n.for_signature() == str(n), n.get_abspath() - def test_get_string(self): + def test_get_string(self) -> None: """Test the get_string() method.""" class TestNode(MyNode): - def __init__(self, name, sig): + def __init__(self, name, sig) -> None: super().__init__(name) self.sig = sig @@ -1236,12 +1236,12 @@ class NodeTestCase(unittest.TestCase): assert n.get_string(0) == "foo", n.get_string(0) assert n.get_string(1) == "bar", n.get_string(1) - def test_literal(self): + def test_literal(self) -> None: """Test the is_literal() function.""" n=SCons.Node.Node() assert n.is_literal() - def test_sconscripts(self): + def test_sconscripts(self) -> None: """Test the is_sconscript() function.""" # check nodes are not sconscript unless added to the list n=SCons.Node.Node() @@ -1254,7 +1254,7 @@ class NodeTestCase(unittest.TestCase): assert not n.is_sconscript() assert n2.is_sconscript() - def test_conftests(self): + def test_conftests(self) -> None: """Test the is_conftest() function.""" # check nodes are not sconscript unless added to the list n=SCons.Node.Node() @@ -1267,9 +1267,9 @@ class NodeTestCase(unittest.TestCase): assert not n.is_conftest() assert n2.is_conftest() - def test_Annotate(self): + def test_Annotate(self) -> None: """Test using an interface-specific Annotate function.""" - def my_annotate(node, self=self): + def my_annotate(node, self=self) -> None: node.Tag('annotation', self.node_string) save_Annotate = SCons.Node.Annotate @@ -1288,7 +1288,7 @@ class NodeTestCase(unittest.TestCase): finally: SCons.Node.Annotate = save_Annotate - def test_clear(self): + def test_clear(self) -> None: """Test clearing all cached state information.""" n = SCons.Node.Node() @@ -1308,25 +1308,25 @@ class NodeTestCase(unittest.TestCase): assert n.cached == 0, n.cached assert x.cleaned_up - def test_get_subst_proxy(self): + def test_get_subst_proxy(self) -> None: """Test the get_subst_proxy method.""" n = MyNode("test") assert n.get_subst_proxy() == n, n.get_subst_proxy() - def test_new_binfo(self): + def test_new_binfo(self) -> None: """Test the new_binfo() method""" n = SCons.Node.Node() result = n.new_binfo() assert isinstance(result, SCons.Node.BuildInfoBase), result - def test_get_suffix(self): + def test_get_suffix(self) -> None: """Test the base Node get_suffix() method""" n = SCons.Node.Node() s = n.get_suffix() assert s == '', s - def test_postprocess(self): + def test_postprocess(self) -> None: """Test calling the base Node postprocess() method""" n = SCons.Node.Node() n.waiting_parents = {'foo', 'bar'} @@ -1334,7 +1334,7 @@ class NodeTestCase(unittest.TestCase): n.postprocess() assert n.waiting_parents == set(), n.waiting_parents - def test_add_to_waiting_parents(self): + def test_add_to_waiting_parents(self) -> None: """Test the add_to_waiting_parents() method""" n1 = SCons.Node.Node() n2 = SCons.Node.Node() @@ -1347,7 +1347,7 @@ class NodeTestCase(unittest.TestCase): class NodeListTestCase(unittest.TestCase): - def test___str__(self): + def test___str__(self) -> None: """Test""" n1 = MyNode("n1") n2 = MyNode("n2") diff --git a/SCons/Node/Python.py b/SCons/Node/Python.py index 57416ef0b..008787a85 100644 --- a/SCons/Node/Python.py +++ b/SCons/Node/Python.py @@ -58,7 +58,7 @@ class ValueNodeInfo(SCons.Node.NodeInfoBase): return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -87,7 +87,7 @@ class Value(SCons.Node.Node): NodeInfo = ValueNodeInfo BuildInfo = ValueBuildInfo - def __init__(self, value, built_value=None, name=None): + def __init__(self, value, built_value=None, name=None) -> None: super().__init__() self.value = value self.changed_since_last_build = 6 @@ -105,25 +105,25 @@ class Value(SCons.Node.Node): def str_for_display(self): return repr(self.value) - def __str__(self): + def __str__(self) -> str: return str(self.value) - def make_ready(self): + def make_ready(self) -> None: self.get_csig() - def build(self, **kw): + def build(self, **kw) -> None: if not hasattr(self, 'built_value'): SCons.Node.Node.build(self, **kw) is_up_to_date = SCons.Node.Node.children_are_up_to_date - def is_under(self, dir): + def is_under(self, dir) -> int: # Make Value nodes get built regardless of # what directory scons was run from. Value nodes # are outside the filesystem: return 1 - def write(self, built_value): + def write(self, built_value) -> None: """Set the value of the node.""" self.built_value = built_value diff --git a/SCons/Node/PythonTests.py b/SCons/Node/PythonTests.py index b6a3f7930..2be2b292f 100644 --- a/SCons/Node/PythonTests.py +++ b/SCons/Node/PythonTests.py @@ -28,7 +28,7 @@ import SCons.Node.Python class ValueTestCase(unittest.TestCase): - def test_Value(self): + def test_Value(self) -> None: """Test creating a Value() object """ v1 = SCons.Node.Python.Value('a') @@ -45,11 +45,11 @@ class ValueTestCase(unittest.TestCase): v3 = SCons.Node.Python.Value('c', 'cb') assert v3.built_value == 'cb' - def test_build(self): + def test_build(self) -> None: """Test "building" a Value Node """ class fake_executor: - def __call__(self, node): + def __call__(self, node) -> None: node.write('faked') v1 = SCons.Node.Python.Value('b', 'built') @@ -68,14 +68,14 @@ class ValueTestCase(unittest.TestCase): assert v3.name == 'name', v3.name assert v3.built_value == 'faked', v3.built_value - def test_read(self): + def test_read(self) -> None: """Test the Value.read() method """ v1 = SCons.Node.Python.Value('a') x = v1.read() assert x == 'a', x - def test_write(self): + def test_write(self) -> None: """Test the Value.write() method """ v1 = SCons.Node.Python.Value('a') @@ -86,7 +86,7 @@ class ValueTestCase(unittest.TestCase): assert v1.value == 'a', v1.value assert v1.built_value == 'new', v1.built_value - def test_get_csig(self): + def test_get_csig(self) -> None: """Test calculating the content signature of a Value() object """ v1 = SCons.Node.Python.Value('aaa') @@ -106,21 +106,21 @@ class ValueTestCase(unittest.TestCase): class ValueNodeInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test ValueNodeInfo initialization""" vvv = SCons.Node.Python.Value('vvv') ni = SCons.Node.Python.ValueNodeInfo() class ValueBuildInfoTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test ValueBuildInfo initialization""" vvv = SCons.Node.Python.Value('vvv') bi = SCons.Node.Python.ValueBuildInfo() class ValueChildTestCase(unittest.TestCase): - def test___init__(self): + def test___init__(self) -> None: """Test support for a Value() being an implicit dependency of a Node""" value = SCons.Node.Python.Value('v') node = SCons.Node.Node() @@ -132,7 +132,7 @@ class ValueChildTestCase(unittest.TestCase): class ValueMemoTestCase(unittest.TestCase): - def test_memo(self): + def test_memo(self) -> None: """Test memoization""" # First confirm that ValueWithMemo does memoization. value1 = SCons.Node.Python.ValueWithMemo('vvv') @@ -145,13 +145,13 @@ class ValueMemoTestCase(unittest.TestCase): value3 = ni.str_to_node('vvv') assert value1 is value3 - def test_built_value(self): + def test_built_value(self) -> None: """Confirm that built values are not memoized.""" v1 = SCons.Node.Python.ValueWithMemo('c', 'ca') v2 = SCons.Node.Python.ValueWithMemo('c', 'ca') assert v1 is not v2 - def test_non_primitive_values(self): + def test_non_primitive_values(self) -> None: """Confirm that non-primitive values are not memoized.""" d = {'a': 1} v1 = SCons.Node.Python.ValueWithMemo(d) @@ -163,7 +163,7 @@ class ValueMemoTestCase(unittest.TestCase): v4 = SCons.Node.Python.ValueWithMemo(a) assert v3 is not v4 - def test_value_set_name(self): + def test_value_set_name(self) -> None: """ Confirm setting name and caching takes the name into account """ v1 = SCons.Node.Python.ValueWithMemo(b'\x00\x0F', name='name') diff --git a/SCons/Node/__init__.py b/SCons/Node/__init__.py index bb0986859..81ff2ffc5 100644 --- a/SCons/Node/__init__.py +++ b/SCons/Node/__init__.py @@ -94,7 +94,7 @@ implicit_deps_changed = 0 # A variable that can be set to an interface-specific function be called # to annotate a Node with information about its creation. -def do_nothing_node(node): pass +def do_nothing_node(node) -> None: pass Annotate = do_nothing_node @@ -121,10 +121,10 @@ _is_derived_map = {0 : is_derived_none, def exists_none(node): raise NotImplementedError -def exists_always(node): +def exists_always(node) -> int: return 1 -def exists_base(node): +def exists_base(node) -> bool: return node.stat() is not None def exists_entry(node): @@ -326,10 +326,10 @@ do_store_info = True # First, the single info functions # -def store_info_pass(node): +def store_info_pass(node) -> None: pass -def store_info_file(node): +def store_info_file(node) -> None: # Merge our build information into the already-stored entry. # This accommodates "chained builds" where a file that's a target # in one build (SConstruct file) is a source in a different build. @@ -353,7 +353,7 @@ class NodeInfoBase: __slots__ = ('__weakref__',) current_version_id = 2 - def update(self, node): + def update(self, node) -> None: try: field_list = self.field_list except AttributeError: @@ -370,10 +370,10 @@ class NodeInfoBase: else: setattr(self, f, func()) - def convert(self, node, val): + def convert(self, node, val) -> None: pass - def merge(self, other): + def merge(self, other) -> None: """ Merge the fields of another object into this object. Already existing information is overwritten by the other instance's data. @@ -383,7 +383,7 @@ class NodeInfoBase: state = other.__getstate__() self.__setstate__(state) - def format(self, field_list=None, names=0): + def format(self, field_list=None, names: int=0): if field_list is None: try: field_list = self.field_list @@ -426,7 +426,7 @@ class NodeInfoBase: pass return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. The version is discarded. """ @@ -452,7 +452,7 @@ class BuildInfoBase: "bsources", "bdepends", "bact", "bimplicit", "__weakref__") current_version_id = 2 - def __init__(self): + def __init__(self) -> None: # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. self.bsourcesigs = [] @@ -460,7 +460,7 @@ class BuildInfoBase: self.bimplicitsigs = [] self.bactsig = None - def merge(self, other): + def merge(self, other) -> None: """ Merge the fields of another object into this object. Already existing information is overwritten by the other instance's data. @@ -490,7 +490,7 @@ class BuildInfoBase: pass return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: """ Restore the attributes from a pickled state. """ @@ -553,7 +553,7 @@ class Node(object, metaclass=NoSlotsPyPy): __slots__ = ('shared', '__dict__') - def __init__(self): + def __init__(self) -> None: if SCons.Debug.track_instances: logInstanceCreation(self, 'Node.Node') # Note that we no longer explicitly initialize a self.builder # attribute to None here. That's because the self.builder @@ -615,7 +615,7 @@ class Node(object, metaclass=NoSlotsPyPy): def disambiguate(self, must_exist=None): return self - def get_suffix(self): + def get_suffix(self) -> str: return '' @SCons.Memoize.CountMethodCall @@ -634,11 +634,11 @@ class Node(object, metaclass=NoSlotsPyPy): """Fetch the appropriate scanner path for this node.""" return self.get_executor().get_build_scanner_path(scanner) - def set_executor(self, executor): + def set_executor(self, executor) -> None: """Set the action executor for this node.""" self.executor = executor - def get_executor(self, create=1): + def get_executor(self, create: int=1): """Fetch the action executor for this node. Create one if there isn't already one, and requested to do so.""" try: @@ -659,7 +659,7 @@ class Node(object, metaclass=NoSlotsPyPy): self.executor = executor return executor - def executor_cleanup(self): + def executor_cleanup(self) -> None: """Let the executor clean up any cached information.""" try: executor = self.get_executor(create=None) @@ -669,19 +669,19 @@ class Node(object, metaclass=NoSlotsPyPy): if executor is not None: executor.cleanup() - def reset_executor(self): + def reset_executor(self) -> None: """Remove cached executor; forces recompute when needed.""" try: delattr(self, 'executor') except AttributeError: pass - def push_to_cache(self): + def push_to_cache(self) -> None: """Try to push a node into a cache """ pass - def retrieve_from_cache(self): + def retrieve_from_cache(self) -> int: """Try to retrieve the node's content from a cache This method is called from multiple threads in a parallel build, @@ -696,7 +696,7 @@ class Node(object, metaclass=NoSlotsPyPy): # Taskmaster interface subsystem # - def make_ready(self): + def make_ready(self) -> None: """Get a Node ready for evaluation. This is called before the Taskmaster decides if the Node is @@ -795,7 +795,7 @@ class Node(object, metaclass=NoSlotsPyPy): "Cannot find target " + str(self) + " after building") self.ninfo.update(self) - def visited(self): + def visited(self) -> None: """Called just after this node has been visited (with or without a build).""" try: @@ -808,7 +808,7 @@ class Node(object, metaclass=NoSlotsPyPy): self.ninfo.update(self) SCons.Node.store_info_map[self.store_info](self) - def release_target_info(self): + def release_target_info(self) -> None: """Called just after this node has been marked up-to-date or was built completely. @@ -825,10 +825,10 @@ class Node(object, metaclass=NoSlotsPyPy): """ pass - def add_to_waiting_s_e(self, node): + def add_to_waiting_s_e(self, node) -> None: self.waiting_s_e.add(node) - def add_to_waiting_parents(self, node): + def add_to_waiting_parents(self, node) -> int: """ Returns the number of nodes added to our waiting parents list: 1 if we add a unique waiting parent, 0 if not. (Note that the @@ -842,13 +842,13 @@ class Node(object, metaclass=NoSlotsPyPy): wp.add(node) return 1 - def postprocess(self): + def postprocess(self) -> None: """Clean up anything we don't need to hang onto after we've been built.""" self.executor_cleanup() self.waiting_parents = set() - def clear(self): + def clear(self) -> None: """Completely clear a Node of all its cached state (so that it can be re-evaluated by interfaces that do continuous integration builds). @@ -868,17 +868,17 @@ class Node(object, metaclass=NoSlotsPyPy): self.cached = 0 self.includes = None - def clear_memoized_values(self): + def clear_memoized_values(self) -> None: self._memo = {} - def builder_set(self, builder): + def builder_set(self, builder) -> None: self.builder = builder try: del self.executor except AttributeError: pass - def has_builder(self): + def has_builder(self) -> bool: """Return whether this Node has a builder or not. In Boolean tests, this turns out to be a *lot* more efficient @@ -897,7 +897,7 @@ class Node(object, metaclass=NoSlotsPyPy): b = self.builder = None return b is not None - def set_explicit(self, is_explicit): + def set_explicit(self, is_explicit) -> None: self.is_explicit = is_explicit def has_explicit_builder(self): @@ -934,11 +934,11 @@ class Node(object, metaclass=NoSlotsPyPy): """ return _is_derived_map[self._func_is_derived](self) - def is_sconscript(self): + def is_sconscript(self) -> bool: """ Returns true if this node is an sconscript """ return self in SConscriptNodes - def is_conftest(self): + def is_conftest(self) -> bool: """ Returns true if this node is an conftest node""" try: self.attributes.conftest_node @@ -1050,14 +1050,14 @@ class Node(object, metaclass=NoSlotsPyPy): scanner = scanner.select(node) return scanner - def add_to_implicit(self, deps): + def add_to_implicit(self, deps) -> None: if not hasattr(self, 'implicit') or self.implicit is None: self.implicit = [] self.implicit_set = set() self._children_reset() self._add_child(self.implicit, self.implicit_set, deps) - def scan(self): + def scan(self) -> None: """Scan this node's dependents for implicit dependencies.""" # Don't bother scanning non-derived files, because we don't # care what their dependencies are. @@ -1119,7 +1119,7 @@ class Node(object, metaclass=NoSlotsPyPy): """ return scanner.select(self) - def env_set(self, env, safe=0): + def env_set(self, env, safe: int=0) -> None: if safe and self.env: return self.env = env @@ -1197,7 +1197,7 @@ class Node(object, metaclass=NoSlotsPyPy): return binfo - def del_binfo(self): + def del_binfo(self) -> None: """Delete the build info from this node.""" try: delattr(self, 'binfo') @@ -1226,27 +1226,27 @@ class Node(object, metaclass=NoSlotsPyPy): # # - def set_precious(self, precious = 1): + def set_precious(self, precious: int = 1) -> None: """Set the Node's precious value.""" self.precious = precious - def set_pseudo(self, pseudo = True): + def set_pseudo(self, pseudo: bool = True) -> None: """Set the Node's precious value.""" self.pseudo = pseudo - def set_noclean(self, noclean = 1): + def set_noclean(self, noclean: int = 1) -> None: """Set the Node's noclean value.""" # Make sure noclean is an integer so the --debug=stree # output in Util.py can use it as an index. self.noclean = noclean and 1 or 0 - def set_nocache(self, nocache = 1): + def set_nocache(self, nocache: int = 1) -> None: """Set the Node's nocache value.""" # Make sure nocache is an integer so the --debug=stree # output in Util.py can use it as an index. self.nocache = nocache and 1 or 0 - def set_always_build(self, always_build = 1): + def set_always_build(self, always_build: int = 1) -> None: """Set the Node's always_build value.""" self.always_build = always_build @@ -1263,7 +1263,7 @@ class Node(object, metaclass=NoSlotsPyPy): """Fetch the contents of the entry.""" return _get_contents_map[self._func_get_contents](self) - def missing(self): + def missing(self) -> bool: return not self.is_derived() and \ not self.linked and \ not self.rexists() @@ -1284,7 +1284,7 @@ class Node(object, metaclass=NoSlotsPyPy): s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node dependency to %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - def add_prerequisite(self, prerequisite): + def add_prerequisite(self, prerequisite) -> None: """Adds prerequisites""" if self.prerequisites is None: self.prerequisites = UniqueList() @@ -1317,7 +1317,7 @@ class Node(object, metaclass=NoSlotsPyPy): s = str(e) raise SCons.Errors.UserError("attempted to add a non-Node as source of %s:\n\t%s is a %s, not a Node" % (str(self), s, type(e))) - def _add_child(self, collection, set, child): + def _add_child(self, collection, set, child) -> None: """Adds 'child' to 'collection', first checking 'set' to see if it's already present.""" added = None @@ -1329,16 +1329,16 @@ class Node(object, metaclass=NoSlotsPyPy): if added: self._children_reset() - def set_specific_source(self, source): + def set_specific_source(self, source) -> None: self.add_source(source) self._specific_sources = True - def add_wkid(self, wkid): + def add_wkid(self, wkid) -> None: """Add a node to the list of kids waiting to be evaluated""" if self.wkids is not None: self.wkids.append(wkid) - def _children_reset(self): + def _children_reset(self) -> None: self.clear_memoized_values() # We need to let the Executor clear out any calculated # build info that it's cached so we can re-calculate it. @@ -1381,7 +1381,7 @@ class Node(object, metaclass=NoSlotsPyPy): self._memo['_children_get'] = children return children - def all_children(self, scan=1): + def all_children(self, scan: int=1): """Return a list of all the node's direct children.""" if scan: self.scan() @@ -1405,14 +1405,14 @@ class Node(object, metaclass=NoSlotsPyPy): # internally anyway...) return list(chain.from_iterable([_f for _f in [self.sources, self.depends, self.implicit] if _f])) - def children(self, scan=1): + def children(self, scan: int=1): """Return a list of the node's direct children, minus those that are ignored by this node.""" if scan: self.scan() return self._children_get() - def set_state(self, state): + def set_state(self, state) -> None: self.state = state def get_state(self): @@ -1425,7 +1425,7 @@ class Node(object, metaclass=NoSlotsPyPy): env = SCons.Defaults.DefaultEnvironment() return env - def Decider(self, function): + def Decider(self, function) -> None: foundkey = None for k, v in _decider_map.items(): if v == function: @@ -1436,7 +1436,7 @@ class Node(object, metaclass=NoSlotsPyPy): _decider_map[foundkey] = function self.changed_since_last_build = foundkey - def Tag(self, key, value): + def Tag(self, key, value) -> None: """ Add a user-defined tag. """ if not self._tags: self._tags = {} @@ -1448,7 +1448,7 @@ class Node(object, metaclass=NoSlotsPyPy): return None return self._tags.get(key, None) - def changed(self, node=None, allowcache=False): + def changed(self, node=None, allowcache: bool=False): """ Returns if the node is up-to-date with respect to the BuildInfo stored last time it was built. The default behavior is to compare @@ -1534,7 +1534,7 @@ class Node(object, metaclass=NoSlotsPyPy): state = s return (state == 0 or state == SCons.Node.up_to_date) - def is_literal(self): + def is_literal(self) -> int: """Always pass the string representation of a Node to the command interpreter literally.""" return 1 @@ -1710,12 +1710,12 @@ class Node(object, metaclass=NoSlotsPyPy): return ( ' '*11).join(lines) class NodeList(collections.UserList): - def __str__(self): + def __str__(self) -> str: return str(list(map(str, self.data))) def get_children(node, parent): return node.children() -def ignore_cycle(node, stack): pass -def do_nothing(node, parent): pass +def ignore_cycle(node, stack) -> None: pass +def do_nothing(node, parent) -> None: pass class Walker: """An iterator for walking a Node tree. @@ -1732,7 +1732,7 @@ class Walker: """ def __init__(self, node, kids_func=get_children, cycle_func=ignore_cycle, - eval_func=do_nothing): + eval_func=do_nothing) -> None: self.kids_func = kids_func self.cycle_func = cycle_func self.eval_func = eval_func @@ -1771,7 +1771,7 @@ class Walker: return node return None - def is_done(self): + def is_done(self) -> bool: return not self.stack diff --git a/SCons/PathList.py b/SCons/PathList.py index a7e666dfa..dab8b2ce4 100644 --- a/SCons/PathList.py +++ b/SCons/PathList.py @@ -67,7 +67,7 @@ class _PathList: """ An actual PathList object. """ - def __init__(self, pathlist): + def __init__(self, pathlist) -> None: """ Initializes a PathList object, canonicalizing the input and pre-processing it for quicker substitution later. @@ -113,7 +113,7 @@ class _PathList: self.pathlist = tuple(pl) - def __len__(self): return len(self.pathlist) + def __len__(self) -> int: return len(self.pathlist) def __getitem__(self, i): return self.pathlist[i] @@ -168,7 +168,7 @@ class PathListCache: cheaply avoid re-parsing both values of CPPPATH by using the common value from this cache. """ - def __init__(self): + def __init__(self) -> None: self._memo = {} def _PathList_key(self, pathlist): diff --git a/SCons/PathListTests.py b/SCons/PathListTests.py index e62baad0d..78fd1a495 100644 --- a/SCons/PathListTests.py +++ b/SCons/PathListTests.py @@ -28,10 +28,10 @@ import SCons.PathList class subst_pathTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: class FakeEnvironment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self.kw = kw def subst(self, s, target=None, source=None, conv=lambda x: x): if s[0] == '$': @@ -48,7 +48,7 @@ class subst_pathTestCase(unittest.TestCase): from SCons.Environment import Environment self.env = Environment(AAA = 'aaa', NULL = '') - def test_node(self): + def test_node(self) -> None: """Test the subst_path() method on a Node """ @@ -65,12 +65,12 @@ class subst_pathTestCase(unittest.TestCase): assert result == (n,), result - def test_object(self): + def test_object(self) -> None: """Test the subst_path() method on a non-Node object """ class A: - def __str__(self): + def __str__(self) -> str: return '' a = A() @@ -81,12 +81,12 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('',), result - def test_object_get(self): + def test_object_get(self) -> None: """Test the subst_path() method on an object with a get() method """ class B: - def get(self): + def get(self) -> str: return 'b' b = B() @@ -97,7 +97,7 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('b',), result - def test_string(self): + def test_string(self) -> None: """Test the subst_path() method on a non-substitution string """ @@ -109,7 +109,7 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('x',), result - def test_subst(self): + def test_subst(self) -> None: """Test the subst_path() method on substitution strings """ @@ -119,14 +119,14 @@ class subst_pathTestCase(unittest.TestCase): assert result == ('aaa',), result - def test_list_of_lists(self): + def test_list_of_lists(self) -> None: """Test the subst_path() method on substitution of nested lists. """ pl = SCons.PathList.PathList((['$AAA', '$AAA'], '$NULL')) result = pl.subst_path(self.env, 'y', 'z') assert result == ('aaa', 'aaa'), result - def test_subst_nested(self): + def test_subst_nested(self) -> None: """Test the subst_path() method on nested substitution of strings. """ self.env.Append(L1 = ['a', 'b'], @@ -144,7 +144,7 @@ class subst_pathTestCase(unittest.TestCase): result = pl.subst_path(self.env, 'y', 'z') assert result == ('a', 'b', 'c', 'd', 'c', 'd'), result - def test_another_env(self): + def test_another_env(self) -> None: """Test the subst_path does lazy evaluation. """ pl = SCons.PathList.PathList(('$AAA', '$NULL')) @@ -156,7 +156,7 @@ class subst_pathTestCase(unittest.TestCase): class PathListCacheTestCase(unittest.TestCase): - def test_no_PathListCache(self): + def test_no_PathListCache(self) -> None: """Make sure the PathListCache class is not visible """ try: @@ -169,7 +169,7 @@ class PathListCacheTestCase(unittest.TestCase): class PathListTestCase(unittest.TestCase): - def test_PathList(self): + def test_PathList(self) -> None: """Test the PathList() entry point """ diff --git a/SCons/Platform/PlatformTests.py b/SCons/Platform/PlatformTests.py index ee0ab75a6..852c76371 100644 --- a/SCons/Platform/PlatformTests.py +++ b/SCons/Platform/PlatformTests.py @@ -36,12 +36,12 @@ class Environment(collections.UserDict): def Detect(self, cmd): return cmd - def AppendENVPath(self, key, value): + def AppendENVPath(self, key, value) -> None: pass class PlatformTestCase(unittest.TestCase): - def test_Platform(self): + def test_Platform(self) -> None: """Test the Platform() function""" p = SCons.Platform.Platform('cygwin') assert str(p) == 'cygwin', p @@ -132,7 +132,7 @@ class PlatformTestCase(unittest.TestCase): SCons.Platform.Platform()(env) assert env != {}, env - def test_win32_no_arch_shell_variables(self): + def test_win32_no_arch_shell_variables(self) -> None: """ Test that a usable HOST_ARCH is available when neither: PROCESSOR_ARCHITEW6432 nor PROCESSOR_ARCHITECTURE @@ -160,7 +160,7 @@ class PlatformTestCase(unittest.TestCase): class TempFileMungeTestCase(unittest.TestCase): - def test_MAXLINELENGTH(self): + def test_MAXLINELENGTH(self) -> None: """ Test different values for MAXLINELENGTH with the same size command string to ensure that the temp file mechanism kicks in only at MAXLINELENGTH+1, or higher @@ -196,7 +196,7 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert cmd != defined_cmd, cmd - def test_TEMPFILEARGJOINBYTE(self): + def test_TEMPFILEARGJOINBYTE(self) -> None: """ Test argument join byte TEMPFILEARGJOINBYTE """ @@ -231,7 +231,7 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert file_content != env['TEMPFILEARGJOINBYTE'].join(['test','command','line']) - def test_TEMPFILEARGESCFUNC(self): + def test_TEMPFILEARGESCFUNC(self) -> None: """ Test a custom TEMPFILEARGESCFUNC """ @@ -261,7 +261,7 @@ class TempFileMungeTestCase(unittest.TestCase): SCons.Action.print_actions = old_actions assert b"newarg" in file_content - def test_tempfilecreation_once(self): + def test_tempfilecreation_once(self) -> None: """ Init class with cmd, such that the fully expanded string reads "a test command line". @@ -287,7 +287,7 @@ class TempFileMungeTestCase(unittest.TestCase): class Attrs: pass - def __init__(self): + def __init__(self) -> None: self.attributes = self.Attrs() target = [Node()] @@ -300,7 +300,7 @@ class TempFileMungeTestCase(unittest.TestCase): class PlatformEscapeTestCase(unittest.TestCase): - def test_posix_escape(self): + def test_posix_escape(self) -> None: """ Check that paths with parens are escaped properly """ import SCons.Platform.posix diff --git a/SCons/Platform/__init__.py b/SCons/Platform/__init__.py index 3fa5a75e2..77eea5c09 100644 --- a/SCons/Platform/__init__.py +++ b/SCons/Platform/__init__.py @@ -130,14 +130,14 @@ def DefaultToolList(platform, env): class PlatformSpec: - def __init__(self, name, generate): + def __init__(self, name, generate) -> None: self.name = name self.generate = generate def __call__(self, *args, **kw): return self.generate(*args, **kw) - def __str__(self): + def __str__(self) -> str: return self.name @@ -192,7 +192,7 @@ class TempFileMunge: env["TEMPFILEARGESCFUNC"] = tempfile_arg_esc_func """ - def __init__(self, cmd, cmdstr = None): + def __init__(self, cmd, cmdstr = None) -> None: self.cmd = cmd self.cmdstr = cmdstr @@ -323,7 +323,7 @@ class TempFileMunge: return cmdlist - def _print_cmd_str(self, target, source, env, cmdstr): + def _print_cmd_str(self, target, source, env, cmdstr) -> None: # check if the user has specified a cmd line print function print_func = None try: diff --git a/SCons/Platform/aix.py b/SCons/Platform/aix.py index e5f34b45f..3afe50638 100644 --- a/SCons/Platform/aix.py +++ b/SCons/Platform/aix.py @@ -67,7 +67,7 @@ def get_xlc(env, xlc=None, packages=[]): xlcPath, sep, xlc = filename.rpartition('/') return (xlcPath, xlc, xlcVersion) -def generate(env): +def generate(env) -> None: posix.generate(env) #Based on AIX 5.2: ARG_MAX=24576 - 3000 for environment expansion env['MAXLINELENGTH'] = 21576 diff --git a/SCons/Platform/cygwin.py b/SCons/Platform/cygwin.py index 82e1d616b..c62a668b3 100644 --- a/SCons/Platform/cygwin.py +++ b/SCons/Platform/cygwin.py @@ -40,7 +40,7 @@ if sys.platform == 'win32': r'C:\cygwin\bin' ] -def generate(env): +def generate(env) -> None: posix.generate(env) env['PROGPREFIX'] = '' diff --git a/SCons/Platform/darwin.py b/SCons/Platform/darwin.py index dcaf5c80f..f17968b62 100644 --- a/SCons/Platform/darwin.py +++ b/SCons/Platform/darwin.py @@ -32,7 +32,7 @@ from . import posix import os -def generate(env): +def generate(env) -> None: posix.generate(env) env['SHLIBSUFFIX'] = '.dylib' env['HOST_OS'] = 'darwin' diff --git a/SCons/Platform/hpux.py b/SCons/Platform/hpux.py index 642f1feff..9d796db39 100644 --- a/SCons/Platform/hpux.py +++ b/SCons/Platform/hpux.py @@ -30,7 +30,7 @@ selection method. from . import posix -def generate(env): +def generate(env) -> None: posix.generate(env) #Based on HP-UX11i: ARG_MAX=2048000 - 3000 for environment expansion env['MAXLINELENGTH'] = 2045000 diff --git a/SCons/Platform/irix.py b/SCons/Platform/irix.py index 4d6be540d..19f619b13 100644 --- a/SCons/Platform/irix.py +++ b/SCons/Platform/irix.py @@ -30,7 +30,7 @@ selection method. from . import posix -def generate(env): +def generate(env) -> None: posix.generate(env) env['HOST_OS'] = 'irix' diff --git a/SCons/Platform/os2.py b/SCons/Platform/os2.py index 6b412eed2..7394aa899 100644 --- a/SCons/Platform/os2.py +++ b/SCons/Platform/os2.py @@ -30,7 +30,7 @@ selection method. from . import win32 -def generate(env): +def generate(env) -> None: if 'ENV' not in env: env['ENV'] = {} env['OBJPREFIX'] = '' diff --git a/SCons/Platform/posix.py b/SCons/Platform/posix.py index 75b6c0bf2..55b00b4db 100644 --- a/SCons/Platform/posix.py +++ b/SCons/Platform/posix.py @@ -74,7 +74,7 @@ def piped_env_spawn(sh, escape, cmd, args, env, stdout, stderr): env, stdout, stderr) -def generate(env): +def generate(env) -> None: # Bearing in mind we have python 2.4 as a baseline, we can just do this: spawn = subprocess_spawn pspawn = piped_env_spawn diff --git a/SCons/Platform/sunos.py b/SCons/Platform/sunos.py index 86924335f..4aa1fffcb 100644 --- a/SCons/Platform/sunos.py +++ b/SCons/Platform/sunos.py @@ -30,7 +30,7 @@ selection method. from . import posix -def generate(env): +def generate(env) -> None: posix.generate(env) # Based on sunSparc 8:32bit # ARG_MAX=1048320 - 3000 for environment expansion diff --git a/SCons/Platform/virtualenv.py b/SCons/Platform/virtualenv.py index 2204a595b..df7ad574d 100644 --- a/SCons/Platform/virtualenv.py +++ b/SCons/Platform/virtualenv.py @@ -51,7 +51,7 @@ def _running_in_virtualenv(): (hasattr(sys, 'base_prefix') and sys.base_prefix != sys.prefix)) -def _is_path_in(path, base): +def _is_path_in(path, base) -> bool: """Returns true if **path** is located under the **base** directory.""" if not path or not base: # empty path may happen, base too return False @@ -59,7 +59,7 @@ def _is_path_in(path, base): return (not rp.startswith(os.path.pardir)) and (not rp == os.path.curdir) -def _inject_venv_variables(env): +def _inject_venv_variables(env) -> None: if 'ENV' not in env: env['ENV'] = {} ENV = env['ENV'] @@ -69,7 +69,7 @@ def _inject_venv_variables(env): except KeyError: pass -def _inject_venv_path(env, path_list=None): +def _inject_venv_path(env, path_list=None) -> None: """Modify environment such that SCons will take into account its virtualenv when running external tools.""" if path_list is None: @@ -86,7 +86,7 @@ def select_paths_in_venv(path_list): return [path for path in path_list if IsInVirtualenv(path)] -def ImportVirtualenv(env): +def ImportVirtualenv(env) -> None: """Copies virtualenv-related environment variables from OS environment to ``env['ENV']`` and prepends virtualenv's PATH to ``env['ENV']['PATH']``. """ diff --git a/SCons/Platform/virtualenvTests.py b/SCons/Platform/virtualenvTests.py index c840749df..9591063ae 100644 --- a/SCons/Platform/virtualenvTests.py +++ b/SCons/Platform/virtualenvTests.py @@ -34,7 +34,7 @@ class Environment(collections.UserDict): def Detect(self, cmd): return cmd - def AppendENVPath(self, key, value): + def AppendENVPath(self, key, value) -> None: if SCons.Util.is_List(value): value = os.path.pathsep.join(value) if 'ENV' not in self: @@ -45,7 +45,7 @@ class Environment(collections.UserDict): else: self['ENV'][key] = os.path.pathsep.join([current, value]) - def PrependENVPath(self, key, value): + def PrependENVPath(self, key, value) -> None: if SCons.Util.is_List(value): value = os.path.pathsep.join(value) if 'ENV' not in self: @@ -58,12 +58,12 @@ class Environment(collections.UserDict): class SysPrefixes: """Used to temporarily mock sys.prefix, sys.real_prefix and sys.base_prefix""" - def __init__(self, prefix, real_prefix=None, base_prefix=None): + def __init__(self, prefix, real_prefix=None, base_prefix=None) -> None: self._prefix = prefix self._real_prefix = real_prefix self._base_prefix = base_prefix - def start(self): + def start(self) -> None: self._store() sys.prefix = self._prefix if self._real_prefix is None: @@ -77,7 +77,7 @@ class SysPrefixes: else: sys.base_prefix = self._base_prefix - def stop(self): + def stop(self) -> None: self._restore() def __enter__(self): @@ -85,10 +85,10 @@ class SysPrefixes: attrs = ('prefix', 'real_prefix', 'base_prefix') return {k: getattr(sys, k) for k in attrs if hasattr(sys, k)} - def __exit__(self, *args): + def __exit__(self, *args) -> None: self.stop() - def _store(self): + def _store(self) -> None: s = dict() if hasattr(sys, 'real_prefix'): s['real_prefix'] = sys.real_prefix @@ -97,7 +97,7 @@ class SysPrefixes: s['prefix'] = sys.prefix self._stored = s - def _restore(self): + def _restore(self) -> None: s = self._stored if 'real_prefix' in s: sys.real_prefix = s['real_prefix'] @@ -117,7 +117,7 @@ def _p(p): class _is_path_in_TestCase(unittest.TestCase): - def test_false(self): + def test_false(self) -> None: for args in [ ('',''), ('', _p('/foo/bar')), (_p('/foo/bar'), ''), @@ -127,7 +127,7 @@ class _is_path_in_TestCase(unittest.TestCase): (_p('foo'), _p('foo/bar')) ]: assert SCons.Platform.virtualenv._is_path_in(*args) is False, "_is_path_in(%r, %r) should be False" % args - def test__true(self): + def test__true(self) -> None: for args in [ (_p('/foo'), _p('/')), (_p('/foo/bar'), _p('/foo')), (_p('/foo/bar/geez'), _p('/foo/bar')), @@ -137,7 +137,7 @@ class _is_path_in_TestCase(unittest.TestCase): assert SCons.Platform.virtualenv._is_path_in(*args) is True, "_is_path_in(%r, %r) should be True" % args class IsInVirtualenvTestCase(unittest.TestCase): - def test_false(self): + def test_false(self) -> None: # "without wirtualenv" - always false with SysPrefixes(_p('/prefix')): for p in [ _p(''), @@ -166,7 +166,7 @@ class IsInVirtualenvTestCase(unittest.TestCase): _p('/virtualenv/bleah') ]: assert SCons.Platform.virtualenv.IsInVirtualenv(p) is False, "IsInVirtualenv(%r) should be False" % p - def test_true(self): + def test_true(self) -> None: # "with virtualenv" with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): for p in [ _p('/virtualenv/prefix/foo'), @@ -189,22 +189,22 @@ class _inject_venv_pathTestCase(unittest.TestCase): _p('/usr/bin'), _p('/opt/bin') ] - def test_with_path_string(self): + def test_with_path_string(self) -> None: env = Environment() path_string = os.path.pathsep.join(self.path_list()) with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): SCons.Platform.virtualenv._inject_venv_path(env, path_string) assert env['ENV']['PATH'] == _p('/virtualenv/prefix/bin'), env['ENV']['PATH'] - def test_with_path_list(self): + def test_with_path_list(self) -> None: env = Environment() with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): SCons.Platform.virtualenv._inject_venv_path(env, self.path_list()) assert env['ENV']['PATH'] == _p('/virtualenv/prefix/bin'), env['ENV']['PATH'] class VirtualenvTestCase(unittest.TestCase): - def test_none(self): - def _msg(given): + def test_none(self) -> None: + def _msg(given) -> str: return "Virtualenv() should be None, not %s" % repr(given) with SysPrefixes(_p('/prefix')): @@ -214,8 +214,8 @@ class VirtualenvTestCase(unittest.TestCase): ve = SCons.Platform.virtualenv.Virtualenv() assert ve is None, _msg(ve) - def test_not_none(self): - def _msg(expected, given): + def test_not_none(self) -> None: + def _msg(expected, given) -> str: return "Virtualenv() should == %r, not %s" % (_p(expected), repr(given)) with SysPrefixes(_p('/virtualenv/prefix'), real_prefix=_p('/real/prefix')): diff --git a/SCons/Platform/win32.py b/SCons/Platform/win32.py index 990794f96..c9fcd9502 100644 --- a/SCons/Platform/win32.py +++ b/SCons/Platform/win32.py @@ -58,7 +58,7 @@ if False: shutil.copy2 = CopyFile - def win_api_copyfile(src,dst): + def win_api_copyfile(src,dst) -> None: CopyFile(src,dst) os.utime(dst) @@ -283,7 +283,7 @@ class ArchDefinition: Determine which windows CPU were running on. A class for defining architecture-specific settings and logic. """ - def __init__(self, arch, synonyms=[]): + def __init__(self, arch, synonyms=[]) -> None: self.arch = arch self.synonyms = synonyms diff --git a/SCons/SConf.py b/SCons/SConf.py index 136be279b..daece1ade 100644 --- a/SCons/SConf.py +++ b/SCons/SConf.py @@ -61,7 +61,7 @@ SCons.Conftest.LogErrorMessages = 0 build_type = None build_types = ['clean', 'help'] -def SetBuildType(buildtype): +def SetBuildType(buildtype) -> None: global build_type build_type = buildtype @@ -73,7 +73,7 @@ FORCE=1 # force all tests to be rebuilt CACHE=2 # force all tests to be taken from cache (raise an error, if necessary) cache_mode = AUTO -def _set_conftest_node(node): +def _set_conftest_node(node) -> None: node.attributes.conftest_node = 1 def SetCacheMode(mode): @@ -90,7 +90,7 @@ def SetCacheMode(mode): raise ValueError("SCons.SConf.SetCacheMode: Unknown mode " + mode) progress_display = SCons.Util.display # will be overwritten by SCons.Script -def SetProgressDisplay(display): +def SetProgressDisplay(display) -> None: """Set the progress display to use (called from SCons.Script)""" global progress_display progress_display = display @@ -102,7 +102,7 @@ _ac_config_logs = {} # all config.log files created in this build _ac_config_hs = {} # all config.h files created in this build sconf_global = None # current sconf object -def _createConfigH(target, source, env): +def _createConfigH(target, source, env) -> None: t = open(str(target[0]), "w") defname = re.sub('[^A-Za-z0-9_]', '_', str(target[0]).upper()) t.write("""#ifndef %(DEFNAME)s_SEEN @@ -119,13 +119,13 @@ def _stringConfigH(target, source, env): return "scons: Configure: creating " + str(target[0]) -def NeedConfigHBuilder(): +def NeedConfigHBuilder() -> bool: if len(_ac_config_hs) == 0: return False else: return True -def CreateConfigHBuilder(env): +def CreateConfigHBuilder(env) -> None: """Called if necessary just before the building targets phase begins.""" action = SCons.Action.Action(_createConfigH, _stringConfigH) @@ -141,13 +141,13 @@ SCons.Warnings.enableWarningClass(SConfWarning) # some error definitions class SConfError(SCons.Errors.UserError): - def __init__(self,msg): + def __init__(self,msg) -> None: super().__init__(msg) class ConfigureDryRunError(SConfError): """Raised when a file or directory needs to be updated during a Configure process, but the user requested a dry-run""" - def __init__(self,target): + def __init__(self,target) -> None: if not isinstance(target, SCons.Node.FS.File): msg = 'Cannot create configure directory "%s" within a dry-run.' % str(target) else: @@ -157,12 +157,12 @@ class ConfigureDryRunError(SConfError): class ConfigureCacheError(SConfError): """Raised when a use explicitely requested the cache feature, but the test is run the first time.""" - def __init__(self,target): + def __init__(self,target) -> None: super().__init__('"%s" is not yet built and cache is forced.' % str(target)) # define actions for building text files -def _createSource(target, source, env): +def _createSource(target, source, env) -> None: fd = open(str(target[0]), "w") fd.write(source[0].get_contents().decode()) fd.close() @@ -180,11 +180,11 @@ class SConfBuildInfo(SCons.Node.FS.FileBuildInfo): """ __slots__ = ('result', 'string') - def __init__(self): + def __init__(self) -> None: self.result = None # -> 0/None -> no error, != 0 error self.string = None # the stdout / stderr output when building the target - def set_build_result(self, result, string): + def set_build_result(self, result, string) -> None: self.result = result self.string = string @@ -193,11 +193,11 @@ class Streamer: """ 'Sniffer' for a file-like writable object. Similar to the unix tool tee. """ - def __init__(self, orig): + def __init__(self, orig) -> None: self.orig = orig self.s = io.StringIO() - def write(self, str): + def write(self, str) -> None: if self.orig: self.orig.write(str) try: @@ -206,7 +206,7 @@ class Streamer: # "unicode argument expected" bug in IOStream (python 2.x) self.s.write(str.decode()) - def writelines(self, lines): + def writelines(self, lines) -> None: for l in lines: self.write(l + '\n') @@ -216,7 +216,7 @@ class Streamer: """ return self.s.getvalue() - def flush(self): + def flush(self) -> None: if self.orig: self.orig.flush() self.s.flush() @@ -229,11 +229,11 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): """ non_sconf_nodes = set() - def display(self, message): + def display(self, message) -> None: if sconf_global.logstream: sconf_global.logstream.write("scons: Configure: " + message + "\n") - def display_cached_string(self, bi): + def display_cached_string(self, bi) -> None: """ Logs the original builder messages, given the SConfBuildInfo instance bi. @@ -378,7 +378,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): sconsign.set_entry(t.name, sconsign_entry) sconsign.merge() - def make_ready_current(self): + def make_ready_current(self) -> None: # We're overriding make_ready_current() call to add to the list # of nodes used by this task, filtering out any nodes created # by the checker for it's own purpose. @@ -386,7 +386,7 @@ class SConfBuildTask(SCons.Taskmaster.AlwaysTask): super().make_ready_current() make_ready = make_ready_current - def postprocess(self): + def postprocess(self) -> None: # We're done executing this task, so now we'll go through all the # nodes used by this task which aren't nodes created for # Configure checkers, but rather are existing or built files @@ -410,8 +410,8 @@ class SConfBase: SConf run, we need to explicitly cache this error. """ - def __init__(self, env, custom_tests = {}, conf_dir='$CONFIGUREDIR', - log_file='$CONFIGURELOG', config_h = None, _depth = 0): + def __init__(self, env, custom_tests = {}, conf_dir: str='$CONFIGUREDIR', + log_file: str='$CONFIGURELOG', config_h = None, _depth: int = 0) -> None: """Constructor. Pass additional tests in the custom_tests-dictionary, e.g. custom_tests={'CheckPrivate':MyPrivateTest}, where MyPrivateTest defines a custom test. @@ -432,7 +432,7 @@ class SConfBase: # and keep the build state consistent. def force_build(dependency, target, prev_ni, repo_node=None, - env_decider=env.decide_source): + env_decider=env.decide_source) -> bool: try: env_decider(dependency, target, prev_ni, repo_node) except Exception as e: @@ -496,7 +496,7 @@ class SConfBase: return self.env - def Define(self, name, value = None, comment = None): + def Define(self, name, value = None, comment = None) -> None: """ Define a pre processor symbol name, with the optional given value in the current config header. @@ -602,7 +602,7 @@ class SConfBase: """ return self.pspawn(sh, escape, cmd, args, env, self.logstream, self.logstream) - def TryBuild(self, builder, text=None, extension=""): + def TryBuild(self, builder, text=None, extension: str=""): """Low level TryBuild implementation. Normally you don't need to call that - you can use TryCompile / TryLink / TryRun instead """ @@ -673,7 +673,7 @@ class SConfBase: return result - def TryAction(self, action, text = None, extension = ""): + def TryAction(self, action, text = None, extension: str = ""): """Tries to execute the given action with optional source file contents and optional source file extension , Returns the status (0 : failed, 1 : ok) and the contents of the @@ -724,7 +724,7 @@ class SConfBase: class TestWrapper: """A wrapper around Tests (to ensure sanity)""" - def __init__(self, test, sconf): + def __init__(self, test, sconf) -> None: self.test = test self.sconf = sconf def __call__(self, *args, **kw): @@ -737,12 +737,12 @@ class SConfBase: context.Result("error: no result") return ret - def AddTest(self, test_name, test_instance): + def AddTest(self, test_name, test_instance) -> None: """Adds test_class to this SConf instance. It can be called with self.test_name(...)""" setattr(self, test_name, SConfBase.TestWrapper(test_instance, self)) - def AddTests(self, tests): + def AddTests(self, tests) -> None: """Adds all the tests given in the tests dictionary to this SConf instance """ @@ -758,7 +758,7 @@ class SConfBase: if not os.path.isdir( dirName ): os.makedirs( dirName ) - def _startup(self): + def _startup(self) -> None: """Private method. Set up logstream, and set the environment variables necessary for a piped build """ @@ -781,7 +781,7 @@ class SConfBase: log_mode = "w" fp = open(str(self.logfile), log_mode) - def conflog_cleanup(logf): + def conflog_cleanup(logf) -> None: logf.close() atexit.register(conflog_cleanup, fp) @@ -855,7 +855,7 @@ class CheckContext: changed. """ - def __init__(self, sconf): + def __init__(self, sconf) -> None: """Constructor. Pass the corresponding SConf instance.""" self.sconf = sconf self.did_show_result = 0 @@ -873,7 +873,7 @@ class CheckContext: # correctly. Note that we can't use Conftest.py's support for config.h, # cause we will need to specify a builder for the config.h file ... - def Message(self, text): + def Message(self, text) -> None: """Inform about what we are doing right now, e.g. 'Checking for SOMETHING ... ' """ @@ -881,7 +881,7 @@ class CheckContext: self.sconf.cached = 1 self.did_show_result = 0 - def Result(self, res): + def Result(self, res) -> None: """Inform about the result of the test. If res is not a string, displays 'yes' or 'no' depending on whether res is evaluated as true or false. The result is only displayed when self.did_show_result is not set. @@ -923,17 +923,17 @@ class CheckContext: #### Stuff used by Conftest.py (look there for explanations). - def BuildProg(self, text, ext): + def BuildProg(self, text, ext) -> bool: self.sconf.cached = 1 # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. return not self.TryBuild(self.env.Program, text, ext) - def CompileProg(self, text, ext): + def CompileProg(self, text, ext) -> bool: self.sconf.cached = 1 # TODO: should use self.vardict for $CC, $CPPFLAGS, etc. return not self.TryBuild(self.env.Object, text, ext) - def CompileSharedObject(self, text, ext): + def CompileSharedObject(self, text, ext) -> bool: self.sconf.cached = 1 # TODO: should use self.vardict for $SHCC, $CPPFLAGS, etc. return not self.TryBuild(self.env.SharedObject, text, ext) @@ -944,7 +944,7 @@ class CheckContext: st, out = self.TryRun(text, ext) return not st, out - def AppendLIBS(self, lib_name_list, unique=False): + def AppendLIBS(self, lib_name_list, unique: bool=False): oldLIBS = self.env.get( 'LIBS', [] ) if unique: self.env.AppendUnique(LIBS = lib_name_list) @@ -952,7 +952,7 @@ class CheckContext: self.env.Append(LIBS = lib_name_list) return oldLIBS - def PrependLIBS(self, lib_name_list, unique=False): + def PrependLIBS(self, lib_name_list, unique: bool=False): oldLIBS = self.env.get( 'LIBS', [] ) if unique: self.env.PrependUnique(LIBS = lib_name_list) @@ -965,7 +965,7 @@ class CheckContext: self.env.Replace(LIBS = val) return oldLIBS - def Display(self, msg): + def Display(self, msg) -> None: if self.sconf.cached: # We assume that Display is called twice for each test here # once for the Checking for ... message and once for the result. @@ -975,7 +975,7 @@ class CheckContext: progress_display(msg, append_newline=0) self.Log("scons: Configure: " + msg + "\n") - def Log(self, msg): + def Log(self, msg) -> None: if self.sconf.logstream is not None: self.sconf.logstream.write(msg) @@ -995,39 +995,39 @@ def SConf(*args, **kw): return SCons.Util.Null() -def CheckFunc(context, function_name, header = None, language = None): +def CheckFunc(context, function_name, header = None, language = None) -> bool: res = SCons.Conftest.CheckFunc(context, function_name, header = header, language = language) context.did_show_result = 1 return not res -def CheckType(context, type_name, includes = "", language = None): +def CheckType(context, type_name, includes: str = "", language = None) -> bool: res = SCons.Conftest.CheckType(context, type_name, header = includes, language = language) context.did_show_result = 1 return not res -def CheckTypeSize(context, type_name, includes = "", language = None, expect = None): +def CheckTypeSize(context, type_name, includes: str = "", language = None, expect = None): res = SCons.Conftest.CheckTypeSize(context, type_name, header = includes, language = language, expect = expect) context.did_show_result = 1 return res -def CheckDeclaration(context, declaration, includes = "", language = None): +def CheckDeclaration(context, declaration, includes: str = "", language = None) -> bool: res = SCons.Conftest.CheckDeclaration(context, declaration, includes = includes, language = language) context.did_show_result = 1 return not res -def CheckMember(context, aggregate_member, header = None, language = None): +def CheckMember(context, aggregate_member, header = None, language = None) -> bool: '''Returns the status (False : failed, True : ok).''' res = SCons.Conftest.CheckMember(context, aggregate_member, header=header, language=language) context.did_show_result = 1 return not res -def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'): +def createIncludesFromHeaders(headers, leaveLast, include_quotes: str = '""'): # used by CheckHeader and CheckLibWithHeader to produce C - #include # statements from the specified header (list) if not SCons.Util.is_List(headers): @@ -1043,7 +1043,7 @@ def createIncludesFromHeaders(headers, leaveLast, include_quotes = '""'): % (include_quotes[0], s, include_quotes[1])) return ''.join(l), lastHeader -def CheckHeader(context, header, include_quotes = '<>', language = None): +def CheckHeader(context, header, include_quotes: str = '<>', language = None) -> bool: """ A test for a C or C++ header file. """ @@ -1055,29 +1055,29 @@ def CheckHeader(context, header, include_quotes = '<>', language = None): context.did_show_result = 1 return not res -def CheckCC(context): +def CheckCC(context) -> bool: res = SCons.Conftest.CheckCC(context) context.did_show_result = 1 return not res -def CheckCXX(context): +def CheckCXX(context) -> bool: res = SCons.Conftest.CheckCXX(context) context.did_show_result = 1 return not res -def CheckSHCC(context): +def CheckSHCC(context) -> bool: res = SCons.Conftest.CheckSHCC(context) context.did_show_result = 1 return not res -def CheckSHCXX(context): +def CheckSHCXX(context) -> bool: res = SCons.Conftest.CheckSHCXX(context) context.did_show_result = 1 return not res # Bram: Make this function obsolete? CheckHeader() is more generic. -def CheckCHeader(context, header, include_quotes = '""'): +def CheckCHeader(context, header, include_quotes: str = '""'): """ A test for a C header file. """ @@ -1086,16 +1086,16 @@ def CheckCHeader(context, header, include_quotes = '""'): # Bram: Make this function obsolete? CheckHeader() is more generic. -def CheckCXXHeader(context, header, include_quotes = '""'): +def CheckCXXHeader(context, header, include_quotes: str = '""'): """ A test for a C++ header file. """ return CheckHeader(context, header, include_quotes, language = "C++") -def CheckLib(context, library = None, symbol = "main", - header = None, language = None, autoadd=True, - append=True, unique=False) -> bool: +def CheckLib(context, library = None, symbol: str = "main", + header = None, language = None, autoadd: bool=True, + append: bool=True, unique: bool=False) -> bool: """ A test for a library. See also CheckLibWithHeader. Note that library may also be None to test whether the given symbol @@ -1119,7 +1119,7 @@ def CheckLib(context, library = None, symbol = "main", # Bram: Can only include one header and can't use #ifdef HAVE_HEADER_H. def CheckLibWithHeader(context, libs, header, language, - call = None, autoadd=True, append=True, unique=False) -> bool: + call = None, autoadd: bool=True, append: bool=True, unique: bool=False) -> bool: # ToDo: accept path for library. Support system header files. """ Another (more sophisticated) test for a library. diff --git a/SCons/SConfTests.py b/SCons/SConfTests.py index 5d0984833..e8e0fc72b 100644 --- a/SCons/SConfTests.py +++ b/SCons/SConfTests.py @@ -40,13 +40,13 @@ else: class SConfTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: # we always want to start with a clean directory self.save_cwd = os.getcwd() self.test = TestCmd.TestCmd(workdir = '') os.chdir(self.test.workpath('')) - def tearDown(self): + def tearDown(self) -> None: self.test.cleanup() import SCons.SConsign SCons.SConsign.Reset() @@ -91,7 +91,7 @@ class SConfTestCase(unittest.TestCase): global existing_lib existing_lib = 'm' - def _baseTryXXX(self, TryFunc): + def _baseTryXXX(self, TryFunc) -> None: # TryCompile and TryLink are much the same, so we can test them # in one method, we pass the function as a string ('TryCompile', # 'TryLink'), so we are aware of reloading modules. @@ -148,7 +148,7 @@ class SConfTestCase(unittest.TestCase): finally: sconf.Finish() - def test_TryBuild(self): + def test_TryBuild(self) -> None: """Test SConf.TryBuild """ # 1 test that we can try a builder that returns a list of nodes @@ -160,14 +160,14 @@ class SConfTestCase(unittest.TestCase): import SCons.Node class MyAction: - def get_contents(self, target, source, env): + def get_contents(self, target, source, env) -> str: return 'MyBuilder-MyAction $SOURCE $TARGET' class Attrs: __slots__ = ('shared', '__dict__') class MyBuilder(SCons.Builder.BuilderBase): - def __init__(self): + def __init__(self) -> None: self.prefix = '' self.suffix = '' # need action because temporary file name uses hash of actions get_contents() @@ -175,7 +175,7 @@ class SConfTestCase(unittest.TestCase): def __call__(self, env, target, source, *args, **kw): class MyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self.state = SCons.Node.no_state self.waiting_parents = set() @@ -185,45 +185,45 @@ class SConfTestCase(unittest.TestCase): self.attributes = Attrs() def disambiguate(self): return self - def has_builder(self): + def has_builder(self) -> int: return 1 - def add_pre_action(self, *actions): + def add_pre_action(self, *actions) -> None: pass - def add_post_action(self, *actions): + def add_post_action(self, *actions) -> None: pass - def children(self, scan = 1): + def children(self, scan: int = 1): return [] def get_state(self): return self.state - def set_state(self, state): + def set_state(self, state) -> None: self.state = state def alter_targets(self): return [], None def depends_on(self, nodes): return None - def postprocess(self): + def postprocess(self) -> None: pass - def clear(self): + def clear(self) -> None: pass def is_up_to_date(self): return None - def prepare(self): + def prepare(self) -> None: pass - def push_to_cache(self): + def push_to_cache(self) -> None: pass - def retrieve_from_cache(self): + def retrieve_from_cache(self) -> int: return 0 - def build(self, **kw): + def build(self, **kw) -> None: return - def built(self): + def built(self) -> None: pass - def get_stored_info(self): + def get_stored_info(self) -> None: pass - def is_conftest(self): + def is_conftest(self) -> bool: return True def get_executor(self): class Executor: - def __init__(self, targets): + def __init__(self, targets) -> None: self.targets = targets def get_all_targets(self): return self.targets @@ -235,17 +235,17 @@ class SConfTestCase(unittest.TestCase): finally: sconf.Finish() - def test_TryCompile(self): + def test_TryCompile(self) -> None: """Test SConf.TryCompile """ self._baseTryXXX( "TryCompile" ) #self.SConf.SConf.TryCompile ) - def test_TryLink(self): + def test_TryLink(self) -> None: """Test SConf.TryLink """ self._baseTryXXX( "TryLink" ) #self.SConf.SConf.TryLink ) - def test_TryRun(self): + def test_TryRun(self) -> None: """Test SConf.TryRun """ def checks(sconf): @@ -293,14 +293,14 @@ int main(void) { assert secondOcc is None, log - def test_TryAction(self): + def test_TryAction(self) -> None: """Test SConf.TryAction """ def actionOK(target, source, env): with open(str(target[0]), "w") as f: f.write("RUN OK\n") return None - def actionFAIL(target, source, env): + def actionFAIL(target, source, env) -> int: return 1 @@ -318,7 +318,7 @@ int main(void) { finally: sconf.Finish() - def _test_check_compilers(self, comp, func, name): + def _test_check_compilers(self, comp, func, name) -> None: """This is the implementation for CheckCC and CheckCXX tests.""" from copy import deepcopy @@ -413,7 +413,7 @@ int main(void) { sconf.Finish() - def test_CheckHeader(self): + def test_CheckHeader(self) -> None: """Test SConf.CheckHeader() """ self._resetSConfState() @@ -434,7 +434,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckCHeader(self): + def test_CheckCHeader(self) -> None: """Test SConf.CheckCHeader() """ self._resetSConfState() @@ -454,7 +454,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckCXXHeader(self): + def test_CheckCXXHeader(self) -> None: """Test SConf.CheckCXXHeader() """ self._resetSConfState() @@ -474,7 +474,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckLib(self): + def test_CheckLib(self) -> None: """Test SConf.CheckLib() """ self._resetSConfState() @@ -565,7 +565,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckLibWithHeader(self): + def test_CheckLibWithHeader(self) -> None: """Test SConf.CheckLibWithHeader() """ self._resetSConfState() @@ -664,7 +664,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckFunc(self): + def test_CheckFunc(self) -> None: """Test SConf.CheckFunc() """ self._resetSConfState() @@ -684,7 +684,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckProg(self): + def test_CheckProg(self) -> None: """Test SConf.CheckProg() """ self._resetSConfState() @@ -708,7 +708,7 @@ int main(void) { sconf.Finish() - def test_Define(self): + def test_Define(self) -> None: """Test SConf.Define() """ self._resetSConfState() @@ -744,7 +744,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckTypeSize(self): + def test_CheckTypeSize(self) -> None: """Test SConf.CheckTypeSize() """ self._resetSConfState() @@ -778,7 +778,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckDeclaration(self): + def test_CheckDeclaration(self) -> None: """Test SConf.CheckDeclaration() """ self._resetSConfState() @@ -799,7 +799,7 @@ int main(void) { finally: sconf.Finish() - def test_CheckMember(self): + def test_CheckMember(self) -> None: """Test SConf.CheckMember() """ self._resetSConfState() @@ -820,7 +820,7 @@ int main(void) { sconf.Finish() - def test_(self): + def test_(self) -> None: """Test SConf.CheckType() """ self._resetSConfState() @@ -837,7 +837,7 @@ int main(void) { finally: sconf.Finish() - def test_CustomChecks(self): + def test_CustomChecks(self) -> None: """Test Custom Checks """ def CheckCustom(test): diff --git a/SCons/SConsign.py b/SCons/SConsign.py index ecca39127..860d40b83 100644 --- a/SCons/SConsign.py +++ b/SCons/SConsign.py @@ -35,7 +35,7 @@ from SCons.compat import PICKLE_PROTOCOL from SCons.Util import print_time -def corrupt_dblite_warning(filename): +def corrupt_dblite_warning(filename) -> None: SCons.Warnings.warn( SCons.Warnings.CorruptSConsignWarning, "Ignoring corrupt .sconsign file: %s" % filename, @@ -106,7 +106,7 @@ def Get_DataBase(dir): raise -def Reset(): +def Reset() -> None: """Reset global state. Used by unit tests that end up using SConsign multiple times to get a clean slate for each test.""" global sig_files, DB_sync_list @@ -116,7 +116,7 @@ def Reset(): normcase = os.path.normcase -def write(): +def write() -> None: global sig_files if print_time(): @@ -154,16 +154,16 @@ class SConsignEntry: __slots__ = ("binfo", "ninfo", "__weakref__") current_version_id = 2 - def __init__(self): + def __init__(self) -> None: # Create an object attribute from the class attribute so it ends up # in the pickled data in the .sconsign file. #_version_id = self.current_version_id pass - def convert_to_sconsign(self): + def convert_to_sconsign(self) -> None: self.binfo.convert_to_sconsign() - def convert_from_sconsign(self, dir, name): + def convert_from_sconsign(self, dir, name) -> None: self.binfo.convert_from_sconsign(dir, name) def __getstate__(self): @@ -180,7 +180,7 @@ class SConsignEntry: pass return state - def __setstate__(self, state): + def __setstate__(self, state) -> None: for key, value in state.items(): if key not in ('_version_id', '__weakref__'): setattr(self, key, value) @@ -195,7 +195,7 @@ class Base: methods for fetching and storing the individual bits of information that make up signature entry. """ - def __init__(self): + def __init__(self) -> None: self.entries = {} self.dirty = False self.to_be_merged = {} @@ -206,26 +206,26 @@ class Base: """ return self.entries[filename] - def set_entry(self, filename, obj): + def set_entry(self, filename, obj) -> None: """ Set the entry. """ self.entries[filename] = obj self.dirty = True - def do_not_set_entry(self, filename, obj): + def do_not_set_entry(self, filename, obj) -> None: pass - def store_info(self, filename, node): + def store_info(self, filename, node) -> None: entry = node.get_stored_info() entry.binfo.merge(node.get_binfo()) self.to_be_merged[filename] = node self.dirty = True - def do_not_store_info(self, filename, node): + def do_not_store_info(self, filename, node) -> None: pass - def merge(self): + def merge(self) -> None: for key, node in self.to_be_merged.items(): entry = node.get_stored_info() try: @@ -247,7 +247,7 @@ class DB(Base): from a global .sconsign.db* file--the actual file suffix is determined by the database module. """ - def __init__(self, dir): + def __init__(self, dir) -> None: super().__init__() self.dir = dir @@ -287,7 +287,7 @@ class DB(Base): global sig_files sig_files.append(self) - def write(self, sync=1): + def write(self, sync: int=1) -> None: if not self.dirty: return @@ -315,7 +315,7 @@ class DB(Base): class Dir(Base): - def __init__(self, fp=None, dir=None): + def __init__(self, fp=None, dir=None) -> None: """ fp - file pointer to read entries from """ @@ -338,7 +338,7 @@ class DirFile(Dir): """ Encapsulates reading and writing a per-directory .sconsign file. """ - def __init__(self, dir): + def __init__(self, dir) -> None: """ dir - the directory for the file """ @@ -367,7 +367,7 @@ class DirFile(Dir): global sig_files sig_files.append(self) - def write(self, sync=1): + def write(self, sync: int=1) -> None: """ Write the .sconsign file to disk. @@ -431,7 +431,7 @@ class DirFile(Dir): ForDirectory = DB -def File(name, dbm_module=None): +def File(name, dbm_module=None) -> None: """ Arrange for all signatures to be stored in a global .sconsign.db* file. diff --git a/SCons/SConsignTests.py b/SCons/SConsignTests.py index e9f20718d..84bc2000b 100644 --- a/SCons/SConsignTests.py +++ b/SCons/SConsignTests.py @@ -31,25 +31,25 @@ import SCons.SConsign from SCons.Util import get_hash_format, get_current_hash_algorithm_used class BuildInfo: - def merge(self, object): + def merge(self, object) -> None: pass class DummySConsignEntry: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self.binfo = BuildInfo() - def convert_to_sconsign(self): + def convert_to_sconsign(self) -> None: self.c_to_s = 1 - def convert_from_sconsign(self, dir, name): + def convert_from_sconsign(self, dir, name) -> None: self.c_from_s = 1 class FS: - def __init__(self, top): + def __init__(self, top) -> None: self.Top = top self.Top.repositories = [] class DummyNode: - def __init__(self, path='not_a_valid_path', binfo=None): + def __init__(self, path: str='not_a_valid_path', binfo=None) -> None: self.path = path self.tpath = path self.fs = FS(self) @@ -64,18 +64,18 @@ class DummyNode: return self.tpath class SConsignTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.save_cwd = os.getcwd() self.test = TestCmd.TestCmd(workdir = '') os.chdir(self.test.workpath('')) - def tearDown(self): + def tearDown(self) -> None: self.test.cleanup() SCons.SConsign.Reset() os.chdir(self.save_cwd) class BaseTestCase(SConsignTestCase): - def test_Base(self): + def test_Base(self) -> None: aaa = DummySConsignEntry('aaa') bbb = DummySConsignEntry('bbb') bbb.arg1 = 'bbb arg1' @@ -216,7 +216,7 @@ class BaseTestCase(SConsignTestCase): class SConsignDBTestCase(SConsignTestCase): - def test_SConsignDB(self): + def test_SConsignDB(self) -> None: save_DataBase = SCons.SConsign.DataBase SCons.SConsign.DataBase = {} try: @@ -262,7 +262,7 @@ class SConsignDBTestCase(SConsignTestCase): class SConsignDirFileTestCase(SConsignTestCase): - def test_SConsignDirFile(self): + def test_SConsignDirFile(self) -> None: bi_foo = DummySConsignEntry('foo') bi_bar = DummySConsignEntry('bar') @@ -291,7 +291,7 @@ class SConsignDirFileTestCase(SConsignTestCase): class SConsignFileTestCase(SConsignTestCase): - def test_SConsignFile(self): + def test_SConsignFile(self) -> None: test = self.test file = test.workpath('sconsign_file') @@ -319,9 +319,9 @@ class SConsignFileTestCase(SConsignTestCase): self.name = name self.mode = mode return self - def __getitem__(self, key): + def __getitem__(self, key) -> None: pass - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: pass fake_dbm = Fake_DBM() @@ -343,7 +343,7 @@ class SConsignFileTestCase(SConsignTestCase): class writeTestCase(SConsignTestCase): - def test_write(self): + def test_write(self) -> None: test = self.test file = test.workpath('sconsign_file') @@ -351,12 +351,12 @@ class writeTestCase(SConsignTestCase): class Fake_DBM: def __getitem__(self, key): return None - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: pass def open(self, name, mode): self.sync_count = 0 return self - def sync(self): + def sync(self) -> None: self.sync_count = self.sync_count + 1 fake_dbm = Fake_DBM() diff --git a/SCons/Scanner/C.py b/SCons/Scanner/C.py index 31ab7e62e..5fa1bbb9f 100644 --- a/SCons/Scanner/C.py +++ b/SCons/Scanner/C.py @@ -41,11 +41,11 @@ class SConsCPPScanner(SCons.cpp.PreProcessor): by Nodes, not strings; 2) we can keep track of the files that are missing. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.missing = [] - def initialize_result(self, fname): + def initialize_result(self, fname) -> None: self.result = SCons.Util.UniqueList([fname]) def finalize_result(self, fname): @@ -131,7 +131,7 @@ class SConsCPPScannerWrapper: evaluation of #if/#ifdef/#else/#elif lines. """ - def __init__(self, name, variable): + def __init__(self, name, variable) -> None: self.name = name self.path = FindPathDirs(variable) @@ -185,12 +185,12 @@ class SConsCPPConditionalScanner(SCons.cpp.PreProcessor): missing. """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) self.missing = [] self._known_paths = [] - def initialize_result(self, fname): + def initialize_result(self, fname) -> None: self.result = SCons.Util.UniqueList([fname]) def find_include_file(self, t): @@ -228,7 +228,7 @@ class SConsCPPConditionalScannerWrapper: evaluation of #if/#ifdef/#else/#elif lines. """ - def __init__(self, name, variable): + def __init__(self, name, variable) -> None: self.name = name self.path = FindPathDirs(variable) diff --git a/SCons/Scanner/CTests.py b/SCons/Scanner/CTests.py index 0f62198d6..6860a10ce 100644 --- a/SCons/Scanner/CTests.py +++ b/SCons/Scanner/CTests.py @@ -201,7 +201,7 @@ test.write("f5b.h", "\n") # define some helpers: class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -241,7 +241,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'): else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -250,7 +250,7 @@ def deps_match(self, deps, headers): # define some tests: class CScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find local files with no CPPPATH""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() @@ -260,7 +260,7 @@ class CScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find a file in a CPPPATH directory""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() @@ -270,7 +270,7 @@ class CScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in explicit subdirectories, ignore missing file""" env = DummyEnvironment(CPPPATH=[test.workpath("d1")]) s = SCons.Scanner.C.CScanner() @@ -280,7 +280,7 @@ class CScannerTestCase3(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in explicit subdirectories""" env = DummyEnvironment(CPPPATH=[test.workpath("d1"), test.workpath("d1/d2")]) s = SCons.Scanner.C.CScanner() @@ -290,7 +290,7 @@ class CScannerTestCase4(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Make sure files in repositories will get scanned""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() @@ -315,7 +315,7 @@ class CScannerTestCase5(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find a same-named file in different directories when CPPPATH changes""" env1 = DummyEnvironment(CPPPATH=[test.workpath("d1")]) env2 = DummyEnvironment(CPPPATH=[test.workpath("d1/d2")]) @@ -330,7 +330,7 @@ class CScannerTestCase6(unittest.TestCase): deps_match(self, deps2, headers2) class CScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in a subdirectory relative to the current directory""" env = DummyEnvironment(CPPPATH=["include"]) s = SCons.Scanner.C.CScanner() @@ -347,11 +347,11 @@ class CScannerTestCase8(unittest.TestCase): deps_match(self, deps2, headers2) class CScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Generate a warning when we can't find a #included file""" SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: - def __call__(self, x): + def __call__(self, x) -> None: self.out = x to = TestOut() @@ -372,7 +372,7 @@ class CScannerTestCase9(unittest.TestCase): test.unlink('fa.h') class CScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in the local directory when the scanned file is elsewhere""" fs = SCons.Node.FS.FS(test.workpath('')) fs.chdir(fs.Dir('include')) @@ -387,7 +387,7 @@ class CScannerTestCase10(unittest.TestCase): test.unlink('include/fa.cpp') class CScannerTestCase11(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Handle dependencies on a derived .h file in a non-existent directory""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) @@ -407,7 +407,7 @@ class CScannerTestCase11(unittest.TestCase): os.chdir(test.workpath('')) class CScannerTestCase12(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in VariantDir() directories""" os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) @@ -429,7 +429,7 @@ class CScannerTestCase12(unittest.TestCase): os.chdir(test.workpath('')) class CScannerTestCase13(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in directories named in a substituted environment variable""" class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, test=test): @@ -445,7 +445,7 @@ class CScannerTestCase13(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase14(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files when there's no space between "#include" and the name""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CScanner() @@ -455,7 +455,7 @@ class CScannerTestCase14(unittest.TestCase): deps_match(self, deps, headers) class CScannerTestCase15(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Verify scanner initialization with the suffixes in $CPPSUFFIXES""" suffixes = [".c", ".C", ".cxx", ".cpp", ".c++", ".cc", ".h", ".H", ".hxx", ".hpp", ".hh", @@ -468,7 +468,7 @@ class CScannerTestCase15(unittest.TestCase): class CConditionalScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find local files with no CPPPATH""" env = DummyEnvironment(CPPPATH=[]) s = SCons.Scanner.C.CConditionalScanner() @@ -479,7 +479,7 @@ class CConditionalScannerTestCase1(unittest.TestCase): class CConditionalScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find local files with no CPPPATH based on #ifdef""" env = DummyEnvironment(CPPPATH=[], CPPDEFINES=["INCLUDE_F2"]) s = SCons.Scanner.C.CConditionalScanner() @@ -490,7 +490,7 @@ class CConditionalScannerTestCase2(unittest.TestCase): class CConditionalScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Find files in explicit subdirectories, ignore missing file""" env = DummyEnvironment( CPPPATH=[test.workpath("d1")], @@ -513,7 +513,7 @@ class CConditionalScannerTestCase3(unittest.TestCase): class CConditionalScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Test that dependency is detected if #include uses a macro.""" with self.subTest("macro defined in the source file"): @@ -533,7 +533,7 @@ class CConditionalScannerTestCase4(unittest.TestCase): class dictify_CPPDEFINESTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """Make sure CPPDEFINES converts correctly. Various types and combinations of types could fail if not handled diff --git a/SCons/Scanner/D.py b/SCons/Scanner/D.py index c9b1e36d9..f4366dfc5 100644 --- a/SCons/Scanner/D.py +++ b/SCons/Scanner/D.py @@ -35,7 +35,7 @@ def DScanner(): return ds class D(Classic): - def __init__(self): + def __init__(self) -> None: super().__init__( name="DScanner", suffixes='$DSUFFIXES', diff --git a/SCons/Scanner/DTests.py b/SCons/Scanner/DTests.py index 25ccca330..358014d3e 100644 --- a/SCons/Scanner/DTests.py +++ b/SCons/Scanner/DTests.py @@ -33,7 +33,7 @@ test = TestCmd.TestCmd(workdir = '') class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -73,7 +73,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'): else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -222,44 +222,44 @@ void main() {} """) class DScannerTestCase(unittest.TestCase): - def helper(self, filename, headers): + def helper(self, filename, headers) -> None: env = DummyEnvironment() s = SCons.Scanner.D.DScanner() path = s.path(env) deps = s(env.File(filename), env, path) deps_match(self, deps, headers) - def test_BasicImport(self): + def test_BasicImport(self) -> None: self.helper('basic.d', ['A.d']) - def test_StaticImport(self): + def test_StaticImport(self) -> None: self.helper('static.d', ['A.d']) - def test_publicImport(self): + def test_publicImport(self) -> None: self.helper('public.d', ['A.d']) - def test_RenameImport(self): + def test_RenameImport(self) -> None: self.helper('rename.d', ['A.d']) - def test_SelectiveImport(self): + def test_SelectiveImport(self) -> None: self.helper('selective.d', ['A.d']) - def test_RenameAndSelectiveImport(self): + def test_RenameAndSelectiveImport(self) -> None: self.helper('renameAndSelective.d', ['A.d']) - def test_ScopedImport(self): + def test_ScopedImport(self) -> None: self.helper('scoped.d', ['A.d']) - def test_CombinatorialImport(self): + def test_CombinatorialImport(self) -> None: self.helper('combinatorial.d', ['A.d', 'B.d', 'C.d', 'D.d']) - def test_SubdirsImport(self): + def test_SubdirsImport(self) -> None: self.helper('subdirs.d', [os.path.join('X','X','X.d'), os.path.join('X','Y.d'), os.path.join('X','Z.d')]) - def test_MultipleImport(self): + def test_MultipleImport(self) -> None: self.helper('multiple.d', ['A.d', 'B.d', 'C.d', os.path.join('X','Y.d')]) - def test_MultilineImport(self): + def test_MultilineImport(self) -> None: self.helper('multiline.d', ['A.d']) if __name__ == "__main__": diff --git a/SCons/Scanner/DirTests.py b/SCons/Scanner/DirTests.py index 1c46c6c3f..32355f352 100644 --- a/SCons/Scanner/DirTests.py +++ b/SCons/Scanner/DirTests.py @@ -41,7 +41,7 @@ from SCons.SConsign import current_sconsign_filename # return self.fs.Entry(name) class DummyEnvironment: - def __init__(self, root): + def __init__(self, root) -> None: self.fs = SCons.Node.FS.FS(root) def Dir(self, name): return self.fs.Dir(name) @@ -53,7 +53,7 @@ class DummyEnvironment: return factory or self.fs.Entry class DirScannerTestBase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.test = TestCmd.TestCmd(workdir = '') self.test.subdir('dir', ['dir', 'sub']) @@ -79,7 +79,7 @@ class DirScannerTestBase(unittest.TestCase): self.test.write(['dir', 'sub', '{}.pag'.format(sconsign)], "dir/{}.pag\n".format(sconsign)) class DirScannerTestCase(DirScannerTestBase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(self.test.workpath()) s = SCons.Scanner.Dir.DirScanner() @@ -102,7 +102,7 @@ class DirScannerTestCase(DirScannerTestBase): assert sss == expect, "Found {}, expected {}".format(sss, expect) class DirEntryScannerTestCase(DirScannerTestBase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(self.test.workpath()) s = SCons.Scanner.Dir.DirEntryScanner() diff --git a/SCons/Scanner/Fortran.py b/SCons/Scanner/Fortran.py index 9cf5b220d..14df5fc96 100644 --- a/SCons/Scanner/Fortran.py +++ b/SCons/Scanner/Fortran.py @@ -48,7 +48,7 @@ class F90Scanner(Classic): """ def __init__(self, name, suffixes, path_variable, - use_regex, incl_regex, def_regex, *args, **kwargs): + use_regex, incl_regex, def_regex, *args, **kwargs) -> None: self.cre_use = re.compile(use_regex, re.M) self.cre_incl = re.compile(incl_regex, re.M) @@ -119,7 +119,7 @@ class F90Scanner(Classic): return [pair[1] for pair in sorted(nodes)] -def FortranScan(path_variable="FORTRANPATH"): +def FortranScan(path_variable: str="FORTRANPATH"): """Return a prototype Scanner instance for scanning source files for Fortran USE & INCLUDE statements""" diff --git a/SCons/Scanner/FortranTests.py b/SCons/Scanner/FortranTests.py index 729e91a18..d2f608906 100644 --- a/SCons/Scanner/FortranTests.py +++ b/SCons/Scanner/FortranTests.py @@ -202,7 +202,7 @@ test.write(['modules', 'use.mod'], "\n") # define some helpers: class DummyEnvironment: - def __init__(self, listCppPath): + def __init__(self, listCppPath) -> None: self.path = listCppPath self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -214,16 +214,16 @@ class DummyEnvironment: else: raise KeyError("Dummy environment only has FORTRANPATH attribute.") - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.Dictionary() def __getitem__(self, key): return self.Dictionary()[key] - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.Dictionary()[key] = value - def __delitem__(self, key): + def __delitem__(self, key) -> None: del self.Dictionary()[key] def subst(self, arg, target=None, source=None, conv=None): @@ -249,7 +249,7 @@ class DummyEnvironment: return self.fs.File(filename) -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = list(map(os.path.normpath, list(map(str, deps)))) expect = list(map(os.path.normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) @@ -258,7 +258,7 @@ def deps_match(self, deps, headers): # define some tests: class FortranScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f1.f', "\n") test.write('f2.f', " INCLUDE 'fi.f'\n") env = DummyEnvironment([]) @@ -272,7 +272,7 @@ class FortranScannerTestCase1(unittest.TestCase): class FortranScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f1.f', "\n") test.write('f2.f', " INCLUDE 'fi.f'\n") env = DummyEnvironment([test.workpath("d1")]) @@ -286,7 +286,7 @@ class FortranScannerTestCase2(unittest.TestCase): class FortranScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -296,7 +296,7 @@ class FortranScannerTestCase3(unittest.TestCase): class FortranScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write(['d1', 'f2.f'], " INCLUDE 'fi.f'\n") env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() @@ -308,7 +308,7 @@ class FortranScannerTestCase4(unittest.TestCase): class FortranScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -318,7 +318,7 @@ class FortranScannerTestCase5(unittest.TestCase): class FortranScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f2.f', "\n") env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() @@ -330,7 +330,7 @@ class FortranScannerTestCase6(unittest.TestCase): class FortranScannerTestCase7(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -340,7 +340,7 @@ class FortranScannerTestCase7(unittest.TestCase): class FortranScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f2.f', "\n") env = DummyEnvironment([test.workpath("d1/d2"), test.workpath("d1")]) s = SCons.Scanner.Fortran.FortranScan() @@ -352,7 +352,7 @@ class FortranScannerTestCase8(unittest.TestCase): class FortranScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f3.f', "\n") env = DummyEnvironment([]) s = SCons.Scanner.Fortran.FortranScan() @@ -380,7 +380,7 @@ class FortranScannerTestCase9(unittest.TestCase): class FortranScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(["include"]) s = SCons.Scanner.Fortran.FortranScan() path = s.path(env) @@ -397,11 +397,11 @@ class FortranScannerTestCase10(unittest.TestCase): class FortranScannerTestCase11(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: - def __call__(self, x): + def __call__(self, x) -> None: self.out = x to = TestOut() @@ -419,7 +419,7 @@ class FortranScannerTestCase11(unittest.TestCase): class FortranScannerTestCase12(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) env.fs.chdir(env.Dir('include')) s = SCons.Scanner.Fortran.FortranScan() @@ -432,7 +432,7 @@ class FortranScannerTestCase12(unittest.TestCase): class FortranScannerTestCase13(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.Repository(test.workpath('repository')) @@ -451,7 +451,7 @@ class FortranScannerTestCase13(unittest.TestCase): class FortranScannerTestCase14(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.VariantDir('build1', 'src', 1) @@ -473,7 +473,7 @@ class FortranScannerTestCase14(unittest.TestCase): class FortranScannerTestCase15(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, test=test): if arg == "$junk": @@ -492,7 +492,7 @@ class FortranScannerTestCase15(unittest.TestCase): class FortranScannerTestCase16(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: test.write('f1.f', "\n") test.write('f2.f', "\n") test.write('f3.f', "\n") diff --git a/SCons/Scanner/IDLTests.py b/SCons/Scanner/IDLTests.py index 28433d1c8..b70115bdc 100644 --- a/SCons/Scanner/IDLTests.py +++ b/SCons/Scanner/IDLTests.py @@ -187,7 +187,7 @@ test.write([ 'repository', 'src', 'ddd.idl'], "\n") # define some helpers: class DummyEnvironment: - def __init__(self, listCppPath): + def __init__(self, listCppPath) -> None: self.path = listCppPath self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -207,16 +207,16 @@ class DummyEnvironment: path = [path] return list(map(self.subst, path)) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.Dictionary() def __getitem__(self,key): return self.Dictionary()[key] - def __setitem__(self,key,value): + def __setitem__(self,key,value) -> None: self.Dictionary()[key] = value - def __delitem__(self,key): + def __delitem__(self,key) -> None: del self.Dictionary()[key] def get_calculator(self): @@ -237,7 +237,7 @@ my_normpath = os.path.normpath if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) @@ -245,7 +245,7 @@ def deps_match(self, deps, headers): # define some tests: class IDLScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -254,7 +254,7 @@ class IDLScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -263,7 +263,7 @@ class IDLScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1")]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -272,7 +272,7 @@ class IDLScannerTestCase3(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([test.workpath("d1"), test.workpath("d1/d2")]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -281,7 +281,7 @@ class IDLScannerTestCase4(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -306,7 +306,7 @@ class IDLScannerTestCase5(unittest.TestCase): deps_match(self, deps, headers) class IDLScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env1 = DummyEnvironment([test.workpath("d1")]) env2 = DummyEnvironment([test.workpath("d1/d2")]) s = SCons.Scanner.IDL.IDLScan() @@ -320,7 +320,7 @@ class IDLScannerTestCase6(unittest.TestCase): deps_match(self, deps2, headers2) class IDLScannerTestCase7(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(["include"]) s = SCons.Scanner.IDL.IDLScan() path = s.path(env) @@ -336,10 +336,10 @@ class IDLScannerTestCase7(unittest.TestCase): deps_match(self, deps2, headers2) class IDLScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: SCons.Warnings.enableWarningClass(SCons.Warnings.DependencyWarning) class TestOut: - def __call__(self, x): + def __call__(self, x) -> None: self.out = x to = TestOut() @@ -358,7 +358,7 @@ class IDLScannerTestCase8(unittest.TestCase): test.unlink('fa.idl') class IDLScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment([]) env.fs.chdir(env.Dir('include')) s = SCons.Scanner.IDL.IDLScan() @@ -370,7 +370,7 @@ class IDLScannerTestCase9(unittest.TestCase): test.unlink('include/t4.idl') class IDLScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.Repository(test.workpath('repository')) @@ -389,7 +389,7 @@ class IDLScannerTestCase10(unittest.TestCase): os.chdir(test.workpath('')) class IDLScannerTestCase11(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: os.chdir(test.workpath('work')) fs = SCons.Node.FS.FS(test.workpath('work')) fs.VariantDir('build1', 'src', 1) @@ -410,7 +410,7 @@ class IDLScannerTestCase11(unittest.TestCase): os.chdir(test.workpath('')) class IDLScannerTestCase12(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, test=test): if arg == "$blah": diff --git a/SCons/Scanner/Java.py b/SCons/Scanner/Java.py index e6c2db978..4a66c9de9 100644 --- a/SCons/Scanner/Java.py +++ b/SCons/Scanner/Java.py @@ -52,7 +52,7 @@ def _subst_paths(env, paths) -> list: return paths -def _collect_classes(classlist, dirname, files): +def _collect_classes(classlist, dirname, files) -> None: for fname in files: if fname.endswith(".class"): classlist.append(os.path.join(str(dirname), fname)) diff --git a/SCons/Scanner/JavaTests.py b/SCons/Scanner/JavaTests.py index faa0c49ea..cf4ca8384 100644 --- a/SCons/Scanner/JavaTests.py +++ b/SCons/Scanner/JavaTests.py @@ -54,7 +54,7 @@ for fname in subfiles: test.write(fname.split('/'), "\n") class DummyEnvironment(collections.UserDict): - def __init__(self,**kw): + def __init__(self,**kw) -> None: collections.UserDict.__init__(self) self.data.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -73,7 +73,7 @@ class DummyEnvironment(collections.UserDict): path = [path] return list(map(self.subst, path)) - def has_key(self, key): + def has_key(self, key) -> bool: return key in self.Dictionary() def get_calculator(self): @@ -93,13 +93,13 @@ class DummyEnvironment(collections.UserDict): class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def rexists(self): + def rexists(self) -> int: return 1 - def __str__(self): + def __str__(self) -> str: return self.name @@ -109,14 +109,14 @@ my_normpath = os.path.normpath if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = sorted(map(my_normpath, list(map(str, deps)))) expect = sorted(map(my_normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) class JavaScannerEmptyClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=path) s = SCons.Scanner.Java.JavaScanner() @@ -126,7 +126,7 @@ class JavaScannerEmptyClasspath(unittest.TestCase): class JavaScannerClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath('classpath.jar')]) s = SCons.Scanner.Java.JavaScanner() @@ -136,7 +136,7 @@ class JavaScannerClasspath(unittest.TestCase): class JavaScannerWildcardClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath('*')]) s = SCons.Scanner.Java.JavaScanner() @@ -146,7 +146,7 @@ class JavaScannerWildcardClasspath(unittest.TestCase): class JavaScannerDirClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath()]) s = SCons.Scanner.Java.JavaScanner() @@ -156,7 +156,7 @@ class JavaScannerDirClasspath(unittest.TestCase): class JavaScannerNamedDirClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVACLASSPATH=[test.workpath('com'), test.workpath('java space')], @@ -168,7 +168,7 @@ class JavaScannerNamedDirClasspath(unittest.TestCase): class JavaScannerSearchPathClasspath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVACLASSPATH=os.pathsep.join([test.workpath('com'), test.workpath('java space')]), @@ -180,7 +180,7 @@ class JavaScannerSearchPathClasspath(unittest.TestCase): class JavaScannerEmptyProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=path) s = SCons.Scanner.Java.JavaScanner() @@ -190,7 +190,7 @@ class JavaScannerEmptyProcessorpath(unittest.TestCase): class JavaScannerProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath('classpath.jar')]) s = SCons.Scanner.Java.JavaScanner() @@ -200,7 +200,7 @@ class JavaScannerProcessorpath(unittest.TestCase): class JavaScannerWildcardProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath('*')]) s = SCons.Scanner.Java.JavaScanner() @@ -210,7 +210,7 @@ class JavaScannerWildcardProcessorpath(unittest.TestCase): class JavaScannerDirProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath()]) s = SCons.Scanner.Java.JavaScanner() @@ -220,7 +220,7 @@ class JavaScannerDirProcessorpath(unittest.TestCase): class JavaScannerNamedDirProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=[test.workpath('com'), test.workpath('java space')], @@ -232,7 +232,7 @@ class JavaScannerNamedDirProcessorpath(unittest.TestCase): class JavaScannerSearchPathProcessorpath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment( JAVASUFFIXES=['.java'], JAVAPROCESSORPATH=os.pathsep.join([test.workpath('com'), test.workpath('java space')]), diff --git a/SCons/Scanner/LaTeX.py b/SCons/Scanner/LaTeX.py index 700b7cbe7..6abe7362d 100644 --- a/SCons/Scanner/LaTeX.py +++ b/SCons/Scanner/LaTeX.py @@ -78,7 +78,7 @@ class FindENVPathDirs: A class to bind a specific E{*}PATH variable name to a function that will return all of the E{*}path directories. """ - def __init__(self, variable): + def __init__(self, variable) -> None: self.variable = variable def __call__(self, env, dir=None, target=None, source=None, argument=None): @@ -175,7 +175,7 @@ class LaTeX(ScannerBase): 'includefrom', 'subincludefrom', 'inputfrom', 'subinputfrom'] - def __init__(self, name, suffixes, graphics_extensions, *args, **kwargs): + def __init__(self, name, suffixes, graphics_extensions, *args, **kwargs) -> None: regex = r''' \\( include @@ -219,7 +219,7 @@ class LaTeX(ScannerBase): back and uses a dictionary of tuples rather than a single tuple of paths. """ - def __init__(self, dictionary): + def __init__(self, dictionary) -> None: self.dictionary = {} for k,n in dictionary.items(): self.dictionary[k] = (FindPathDirs(n), FindENVPathDirs(n)) @@ -241,7 +241,7 @@ class LaTeX(ScannerBase): Do not scan *.eps, *.pdf, *.jpg, etc. """ - def __init__(self, suffixes): + def __init__(self, suffixes) -> None: self.suffixes = suffixes def __call__(self, node, env): @@ -331,7 +331,7 @@ class LaTeX(ScannerBase): line_continues_a_comment = len(comment) > 0 return '\n'.join(out).rstrip()+'\n' - def scan(self, node, subdir='.'): + def scan(self, node, subdir: str='.'): # Modify the default scan function to allow for the regular # expression to return a comma separated list of file names # as can be the case with the bibliography keyword. diff --git a/SCons/Scanner/LaTeXTests.py b/SCons/Scanner/LaTeXTests.py index 252d8d451..ae3ae6659 100644 --- a/SCons/Scanner/LaTeXTests.py +++ b/SCons/Scanner/LaTeXTests.py @@ -81,7 +81,7 @@ test.write('incNO.tex', "\n") # define some helpers: # copied from CTest.py class DummyEnvironment(collections.UserDict): - def __init__(self, **kw): + def __init__(self, **kw) -> None: super().__init__() self.data.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -121,7 +121,7 @@ if os.path.normcase('foo') == os.path.normcase('FOO'): else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -129,7 +129,7 @@ def deps_match(self, deps, headers): class LaTeXScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) @@ -141,7 +141,7 @@ class LaTeXScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class LaTeXScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(TEXINPUTS=[test.workpath("subdir")],LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) @@ -150,7 +150,7 @@ class LaTeXScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class LaTeXScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(TEXINPUTS=[test.workpath("subdir")],LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) @@ -159,7 +159,7 @@ class LaTeXScannerTestCase3(unittest.TestCase): deps_match(self, deps, files) class LaTeXScannerTestCase4(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(TEXINPUTS=[test.workpath("subdir")],LATEXSUFFIXES = [".tex", ".ltx", ".latex"]) s = SCons.Scanner.LaTeX.LaTeXScanner() path = s.path(env) diff --git a/SCons/Scanner/ProgTests.py b/SCons/Scanner/ProgTests.py index 5aa057128..2798ab6cd 100644 --- a/SCons/Scanner/ProgTests.py +++ b/SCons/Scanner/ProgTests.py @@ -44,7 +44,7 @@ for h in libs: # define some helpers: class DummyEnvironment: - def __init__(self, **kw): + def __init__(self, **kw) -> None: self._dict = {'LIBSUFFIXES' : '.lib'} self._dict.update(kw) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -57,16 +57,16 @@ class DummyEnvironment: else: return [self._dict[x] for x in args] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.Dictionary() def __getitem__(self,key): return self.Dictionary()[key] - def __setitem__(self,key,value): + def __setitem__(self,key,value) -> None: self.Dictionary()[key] = value - def __delitem__(self,key): + def __delitem__(self,key) -> None: del self.Dictionary()[key] def subst(self, s, target=None, source=None, conv=None): @@ -87,11 +87,11 @@ class DummyEnvironment: return self.fs.File(test.workpath(filename)) class DummyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def rexists(self): + def rexists(self) -> int: return 1 - def __str__(self): + def __str__(self) -> str: return self.name def deps_match(deps, libs): @@ -102,7 +102,7 @@ def deps_match(deps, libs): # define some tests: class ProgramScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("") ], LIBS=[ 'l1', 'l2', 'l3' ]) s = SCons.Scanner.Prog.ProgramScanner() @@ -135,7 +135,7 @@ class ProgramScannerTestCase1(unittest.TestCase): class ProgramScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=list(map(test.workpath, ["", "d1", "d1/d2" ])), LIBS=[ 'l1', 'l2', 'l3' ]) @@ -145,7 +145,7 @@ class ProgramScannerTestCase2(unittest.TestCase): assert deps_match(deps, ['l1.lib', 'd1/l2.lib', 'd1/d2/l3.lib' ]), list(map(str, deps)) class ProgramScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[test.workpath("d1/d2"), test.workpath("d1")], LIBS='l2 l3'.split()) @@ -155,7 +155,7 @@ class ProgramScannerTestCase3(unittest.TestCase): assert deps_match(deps, ['d1/l2.lib', 'd1/d2/l3.lib']), list(map(str, deps)) class ProgramScannerTestCase5(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: class SubstEnvironment(DummyEnvironment): def subst(self, arg, target=None, source=None, conv=None, path=test.workpath("d1")): if arg == "$blah": @@ -170,7 +170,7 @@ class ProgramScannerTestCase5(unittest.TestCase): assert deps_match(deps, [ 'd1/l2.lib' ]), list(map(str, deps)) class ProgramScannerTestCase6(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', 'sub/libbar', 'xyz.other'], LIBPREFIXES=['lib'], @@ -181,7 +181,7 @@ class ProgramScannerTestCase6(unittest.TestCase): assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) class ProgramScannerTestCase7(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', '$LIBBAR', '$XYZ'], LIBPREFIXES=['lib'], @@ -194,7 +194,7 @@ class ProgramScannerTestCase7(unittest.TestCase): assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) class ProgramScannerTestCase8(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: n1 = DummyNode('n1') env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], @@ -217,7 +217,7 @@ class ProgramScannerTestCase8(unittest.TestCase): assert deps == [n1, n2], deps class ProgramScannerTestCase9(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', '$LIBBAR'], LIBPREFIXES=['lib'], @@ -229,7 +229,7 @@ class ProgramScannerTestCase9(unittest.TestCase): assert deps_match(deps, ['dir/libfoo.a', 'dir/sub/libbar.a', 'dir/libxyz.other']), list(map(str, deps)) class ProgramScannerTestCase10(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment(LIBPATH=[ test.workpath("dir") ], LIBS=['foo', '$LIBBAR'], LIBPREFIXES=['lib'], diff --git a/SCons/Scanner/PythonTests.py b/SCons/Scanner/PythonTests.py index 1a4f5b430..03e4e1031 100644 --- a/SCons/Scanner/PythonTests.py +++ b/SCons/Scanner/PythonTests.py @@ -56,7 +56,7 @@ else: my_normpath = os.path.normpath -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: global my_normpath scanned = list(map(my_normpath, list(map(str, deps)))) expect = list(map(my_normpath, headers)) @@ -66,7 +66,7 @@ def deps_match(self, deps, headers): # Copied from LaTeXTests.py. class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -104,7 +104,7 @@ class DummyEnvironment(collections.UserDict): class PythonScannerTestPythonPath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner env['ENV']['PYTHONPATH'] = test.workpath('') @@ -115,7 +115,7 @@ class PythonScannerTestPythonPath(unittest.TestCase): class PythonScannerTestPythonCallablePath(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner env['ENV']['PYTHONPATH'] = test.workpath('') @@ -126,7 +126,7 @@ class PythonScannerTestPythonCallablePath(unittest.TestCase): class PythonScannerTestImportSimplePackage(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('imports_simple_package.py') @@ -141,7 +141,7 @@ class PythonScannerTestImportSimplePackage(unittest.TestCase): class PythonScannerTestImportSimplePackageModule1As(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('import_simple_package_module1_as.py') @@ -152,7 +152,7 @@ class PythonScannerTestImportSimplePackageModule1As(unittest.TestCase): class PythonScannerTestImportSimplePackageModuleAs(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('import_simple_package_module1.py') @@ -163,7 +163,7 @@ class PythonScannerTestImportSimplePackageModuleAs(unittest.TestCase): class PythonScannerTestFromImportSimplePackageModule1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_module1.py') @@ -174,7 +174,7 @@ class PythonScannerTestFromImportSimplePackageModule1(unittest.TestCase): class PythonScannerTestFromImportSimplePackageModule1As(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_module1_as.py') @@ -186,7 +186,7 @@ class PythonScannerTestFromImportSimplePackageModule1As(unittest.TestCase): class PythonScannerTestFromImportSimplePackageModulesNoSpace( unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_modules_no_space.py') @@ -199,7 +199,7 @@ class PythonScannerTestFromImportSimplePackageModulesNoSpace( class PythonScannerTestFromImportSimplePackageModulesWithSpace( unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('from_import_simple_package_modules_with_space.py') @@ -211,7 +211,7 @@ class PythonScannerTestFromImportSimplePackageModulesWithSpace( class PythonScannerTestCurdirReferenceScript(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.Dir('curdir_reference').File('script.py') @@ -222,7 +222,7 @@ class PythonScannerTestCurdirReferenceScript(unittest.TestCase): class PythonScannerTestImportsNested3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File('imports_nested3.py') @@ -234,7 +234,7 @@ class PythonScannerTestImportsNested3(unittest.TestCase): class PythonScannerTestImportsGrandparentModule(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File( @@ -246,7 +246,7 @@ class PythonScannerTestImportsGrandparentModule(unittest.TestCase): class PythonScannerTestImportsParentModule(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File( @@ -258,7 +258,7 @@ class PythonScannerTestImportsParentModule(unittest.TestCase): class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: env = DummyEnvironment() s = SCons.Scanner.Python.PythonScanner node = env.File( @@ -270,7 +270,7 @@ class PythonScannerTestImportsParentThenSubmodule(unittest.TestCase): class PythonScannerTestImportsModuleWithFunc(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ This test case tests the following import statement: `from simple_package.module1 import somefunc` with somefunc.py existing @@ -287,7 +287,7 @@ class PythonScannerTestImportsModuleWithFunc(unittest.TestCase): class PythonScannerTestFromNested1ImportNested2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ This test case tests the following import statement: `from nested1 import module, nested2`. In this test, module is a Python @@ -305,7 +305,7 @@ class PythonScannerTestFromNested1ImportNested2(unittest.TestCase): class PythonScannerTestImportUnknownFiles(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ This test case tests importing files that are not found. If Python really can't find those files, it will fail. But this is intended to diff --git a/SCons/Scanner/RCTests.py b/SCons/Scanner/RCTests.py index 3655269e9..120c7f84b 100644 --- a/SCons/Scanner/RCTests.py +++ b/SCons/Scanner/RCTests.py @@ -71,7 +71,7 @@ for h in headers: # define some helpers: class DummyEnvironment(collections.UserDict): - def __init__(self, **kwargs): + def __init__(self, **kwargs) -> None: super().__init__() self.data.update(kwargs) self.fs = SCons.Node.FS.FS(test.workpath('')) @@ -89,7 +89,7 @@ class DummyEnvironment(collections.UserDict): path = [path] return list(map(self.subst, path)) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.data def get_calculator(self): @@ -110,7 +110,7 @@ my_normpath = os.path.normpath if os.path.normcase('foo') == os.path.normcase('FOO'): my_normpath = os.path.normcase -def deps_match(self, deps, headers): +def deps_match(self, deps, headers) -> None: scanned = sorted(map(my_normpath, list(map(str, deps)))) expect = sorted(map(my_normpath, headers)) self.assertTrue(scanned == expect, "expect %s != scanned %s" % (expect, scanned)) @@ -118,7 +118,7 @@ def deps_match(self, deps, headers): # define some tests: class RCScannerTestCase1(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(RCSUFFIXES=['.rc','.rc2'], CPPPATH=path) @@ -128,7 +128,7 @@ class RCScannerTestCase1(unittest.TestCase): deps_match(self, deps, headers) class RCScannerTestCase2(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(RCSUFFIXES=['.rc','.rc2'], CPPPATH=path) @@ -145,7 +145,7 @@ class RCScannerTestCase2(unittest.TestCase): deps_match(self, deps, headers) class RCScannerTestCase3(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: path = [] env = DummyEnvironment(RCSUFFIXES=['.rc','.rc2'], CPPPATH=path) diff --git a/SCons/Scanner/ScannerTests.py b/SCons/Scanner/ScannerTests.py index b9cb209f6..1fbbb62bc 100644 --- a/SCons/Scanner/ScannerTests.py +++ b/SCons/Scanner/ScannerTests.py @@ -35,7 +35,7 @@ class DummyFS: return DummyNode(name) class DummyEnvironment(collections.UserDict): - def __init__(self, mapping=None, **kwargs): + def __init__(self, mapping=None, **kwargs) -> None: super().__init__(mapping) self.data.update(kwargs) self.fs = DummyFS() @@ -55,31 +55,31 @@ class DummyEnvironment(collections.UserDict): return factory or self.fs.File class DummyNode: - def __init__(self, name, search_result=()): + def __init__(self, name, search_result=()) -> None: self.name = name self.search_result = tuple(search_result) - def rexists(self): + def rexists(self) -> bool: return True - def __str__(self): + def __str__(self) -> str: return self.name def Rfindalldirs(self, pathlist): return self.search_result + pathlist - def __repr__(self): + def __repr__(self) -> str: return self.name def __eq__(self, other): return self.name == other.name - def __repr__(self): + def __repr__(self) -> str: return self.name def __eq__(self, other): return self.name == other.name class FindPathDirsTestCase(unittest.TestCase): - def test_FindPathDirs(self): + def test_FindPathDirs(self) -> None: """Test the FindPathDirs callable class""" env = DummyEnvironment(LIBPATH = [ 'foo' ]) @@ -95,9 +95,9 @@ class FindPathDirsTestCase(unittest.TestCase): class ScannerTestCase(unittest.TestCase): - def test_creation(self): + def test_creation(self) -> None: """Test creation of Scanner objects""" - def func(self): + def func(self) -> None: pass s = ScannerBase(func) assert isinstance(s, ScannerBase), s @@ -120,11 +120,11 @@ class ScannerTestCase(unittest.TestCase): class ScannerBaseTestCase(unittest.TestCase): class skey_node: - def __init__(self, key): + def __init__(self, key) -> None: self.key = key def scanner_key(self): return self.key - def rexists(self): + def rexists(self) -> int: return 1 def func(self, filename, env, target, *args): @@ -137,7 +137,7 @@ class ScannerBaseTestCase(unittest.TestCase): return self.deps - def test(self, scanner, env, filename, deps, *args): + def test(self, scanner, env, filename, deps, *args) -> None: self.deps = deps path = scanner.path(env) scanned = scanner(filename, env, path) @@ -154,7 +154,7 @@ class ScannerBaseTestCase(unittest.TestCase): else: self.assertFalse(hasattr(self, "arg"), "an argument was given when it shouldn't have been") - def test___call__dict(self): + def test___call__dict(self) -> None: """Test calling ScannerBase objects with a dictionary""" called = [] def s1func(node, env, path, called=called): @@ -177,9 +177,9 @@ class ScannerBaseTestCase(unittest.TestCase): selector(ny, env, []) assert called == ['s2func', ny], called - def test_path(self): + def test_path(self) -> None: """Test the ScannerBase path() method""" - def pf(env, cwd, target, source, argument=None): + def pf(env, cwd, target, source, argument=None) -> str: return "pf: %s %s %s %s %s" % \ (env.VARIABLE, cwd, target[0], source[0], argument) @@ -196,7 +196,7 @@ class ScannerBaseTestCase(unittest.TestCase): p = s.path(env, 'here', [target], [source]) assert p == "pf: v1 here target source xyz", p - def test_positional(self): + def test_positional(self) -> None: """Test the ScannerBase class using positional arguments""" s = ScannerBase(self.func, "Pos") env = DummyEnvironment() @@ -207,7 +207,7 @@ class ScannerBaseTestCase(unittest.TestCase): env.VARIABLE = "i1" self.test(s, env, DummyNode('i1.cpp'), ['i1.h', 'i1.hpp']) - def test_keywords(self): + def test_keywords(self) -> None: """Test the ScannerBase class using keyword arguments""" s = ScannerBase(function = self.func, name = "Key") env = DummyEnvironment() @@ -219,7 +219,7 @@ class ScannerBaseTestCase(unittest.TestCase): self.test(s, env, DummyNode('i2.cpp'), ['i2.h', 'i2.hpp']) - def test_pos_opt(self): + def test_pos_opt(self) -> None: """Test the ScannerBase class using both position and optional arguments""" arg = "this is the argument" s = ScannerBase(self.func, "PosArg", arg) @@ -231,7 +231,7 @@ class ScannerBaseTestCase(unittest.TestCase): env.VARIABLE = "i3" self.test(s, env, DummyNode('i3.cpp'), ['i3.h', 'i3.hpp'], arg) - def test_key_opt(self): + def test_key_opt(self) -> None: """Test the ScannerBase class using both keyword and optional arguments""" arg = "this is another argument" s = ScannerBase(function = self.func, name = "KeyArg", argument = arg) @@ -243,12 +243,12 @@ class ScannerBaseTestCase(unittest.TestCase): env.VARIABLE = "i4" self.test(s, env, DummyNode('i4.cpp'), ['i4.h', 'i4.hpp'], arg) - def test___cmp__(self): + def test___cmp__(self) -> None: """Test the ScannerBase class __cmp__() method""" s = ScannerBase(self.func, "Cmp") assert s is not None - def test_hash(self): + def test_hash(self) -> None: """Test the ScannerBase class __hash__() method""" s = ScannerBase(self.func, "Hash") mapping = {} @@ -258,11 +258,11 @@ class ScannerBaseTestCase(unittest.TestCase): self.assertTrue(h == i, "hash Scanner base class expected %s, got %s" % (i, h)) - def test_scan_check(self): + def test_scan_check(self) -> None: """Test the ScannerBase class scan_check() method""" def my_scan(filename, env, target, *args): return [] - def check(node, env, s=self): + def check(node, env, s=self) -> int: s.checked[str(node)] = 1 return 1 env = DummyEnvironment() @@ -273,7 +273,7 @@ class ScannerBaseTestCase(unittest.TestCase): self.assertTrue(self.checked['x'] == 1, "did not call check function") - def test_recursive(self): + def test_recursive(self) -> None: """Test the ScannerBase class recursive flag""" nodes = [1, 2, 3, 4] @@ -295,7 +295,7 @@ class ScannerBaseTestCase(unittest.TestCase): n = s.recurse_nodes(nodes) self.assertTrue(n == [1, 3], "recursive = 1 didn't return all nodes: %s" % n) - def test_get_skeys(self): + def test_get_skeys(self) -> None: """Test the ScannerBase get_skeys() method""" s = ScannerBase(function = self.func) sk = s.get_skeys() @@ -310,7 +310,7 @@ class ScannerBaseTestCase(unittest.TestCase): sk = s.get_skeys(env) self.assertTrue(sk == ['.3', '.4'], "sk was %s, not ['.3', '.4']") - def test_select(self): + def test_select(self) -> None: """Test the ScannerBase select() method""" scanner = ScannerBase(function = self.func) s = scanner.select('.x') @@ -324,7 +324,7 @@ class ScannerBaseTestCase(unittest.TestCase): s = selector.select(self.skey_node('.z')) assert s is None, s - def test_add_scanner(self): + def test_add_scanner(self) -> None: """Test the ScannerBase add_scanner() method""" selector = ScannerBase({'.x' : 1, '.y' : 2}) s = selector.select(self.skey_node('.z')) @@ -333,7 +333,7 @@ class ScannerBaseTestCase(unittest.TestCase): s = selector.select(self.skey_node('.z')) assert s == 3, s - def test___str__(self): + def test___str__(self) -> None: """Test the ScannerBase __str__() method""" scanner = ScannerBase(function = self.func) s = str(scanner) @@ -344,20 +344,20 @@ class ScannerBaseTestCase(unittest.TestCase): class SelectorTestCase(unittest.TestCase): class skey_node: - def __init__(self, key): + def __init__(self, key) -> None: self.key = key def scanner_key(self): return self.key - def rexists(self): + def rexists(self) -> int: return 1 - def test___init__(self): + def test___init__(self) -> None: """Test creation of Scanner.Selector object""" s = Selector({}) assert isinstance(s, Selector), s assert s.mapping == {}, s.mapping - def test___call__(self): + def test___call__(self) -> None: """Test calling Scanner.Selector objects""" called = [] def s1func(node, env, path, called=called): @@ -380,7 +380,7 @@ class SelectorTestCase(unittest.TestCase): selector(ny, env, []) assert called == ['s2func', ny], called - def test_select(self): + def test_select(self) -> None: """Test the Scanner.Selector select() method""" selector = Selector({'.x' : 1, '.y' : 2}) s = selector.select(self.skey_node('.x')) @@ -390,7 +390,7 @@ class SelectorTestCase(unittest.TestCase): s = selector.select(self.skey_node('.z')) assert s is None, s - def test_add_scanner(self): + def test_add_scanner(self) -> None: """Test the Scanner.Selector add_scanner() method""" selector = Selector({'.x' : 1, '.y' : 2}) s = selector.select(self.skey_node('.z')) @@ -400,31 +400,31 @@ class SelectorTestCase(unittest.TestCase): assert s == 3, s class CurrentTestCase(unittest.TestCase): - def test_class(self): + def test_class(self) -> None: """Test the Scanner.Current class""" class MyNode: - def __init__(self): + def __init__(self) -> None: self.called_has_builder = None self.called_is_up_to_date = None self.func_called = None - def rexists(self): + def rexists(self) -> int: return 1 class HasNoBuilder(MyNode): def has_builder(self): self.called_has_builder = 1 return None class IsNotCurrent(MyNode): - def has_builder(self): + def has_builder(self) -> int: self.called_has_builder = 1 return 1 def is_up_to_date(self): self.called_is_up_to_date = 1 return None class IsCurrent(MyNode): - def has_builder(self): + def has_builder(self) -> int: self.called_has_builder = 1 return 1 - def is_up_to_date(self): + def is_up_to_date(self) -> int: self.called_is_up_to_date = 1 return 1 def func(node, env, path): @@ -461,7 +461,7 @@ class ClassicTestCase(unittest.TestCase): return self.deps - def test_find_include(self): + def test_find_include(self) -> None: """Test the Scanner.Classic find_include() method""" env = DummyEnvironment() s = Classic("t", ['.suf'], 'MYPATH', r'^my_inc (\S+)') @@ -480,15 +480,15 @@ class ClassicTestCase(unittest.TestCase): finally: SCons.Node.FS.find_file = save - def test_name(self): + def test_name(self) -> None: """Test setting the Scanner.Classic name""" s = Classic("my_name", ['.s'], 'MYPATH', r'^my_inc (\S+)') assert s.name == "my_name", s.name - def test_scan(self): + def test_scan(self) -> None: """Test the Scanner.Classic scan() method""" class MyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name self._rfile = self self.includes = None @@ -562,7 +562,7 @@ class ClassicTestCase(unittest.TestCase): ret = s.function(n, env, ('foo5',)) assert ret == ['jkl', 'mno'], ret - def test_recursive(self): + def test_recursive(self) -> None: """Test the Scanner.Classic class recursive flag""" nodes = [1, 2, 3, 4] @@ -582,7 +582,7 @@ class ClassicTestCase(unittest.TestCase): class ClassicCPPTestCase(unittest.TestCase): - def test_find_include(self): + def test_find_include(self) -> None: """Test the Scanner.ClassicCPP find_include() method""" env = DummyEnvironment() s = ClassicCPP("Test", [], None, "") diff --git a/SCons/Scanner/__init__.py b/SCons/Scanner/__init__.py index fe44ee0fc..c8c2732be 100644 --- a/SCons/Scanner/__init__.py +++ b/SCons/Scanner/__init__.py @@ -59,7 +59,7 @@ class FindPathDirs: """Class to bind a specific E{*}PATH variable name to a function that will return all of the E{*}path directories. """ - def __init__(self, variable): + def __init__(self, variable) -> None: self.variable = variable def __call__(self, env, dir=None, target=None, source=None, argument=None): @@ -149,7 +149,7 @@ class ScannerBase: def __init__( self, function, - name="NONE", + name: str="NONE", argument=_null, skeys=_null, path_function=None, @@ -159,7 +159,7 @@ class ScannerBase: node_factory=None, scan_check=None, recursive=None, - ): + ) -> None: """Construct a new scanner object given a scanner function.""" # Note: this class could easily work with scanner functions that take # something other than a filename as an argument (e.g. a database @@ -238,10 +238,10 @@ class ScannerBase: def __hash__(self): return id(self) - def __str__(self): + def __str__(self) -> str: return self.name - def add_skey(self, skey): + def add_skey(self, skey) -> None: """Add a skey to the list of skeys""" self.skeys.append(skey) @@ -270,7 +270,7 @@ class ScannerBase: # recurse_nodes = _recurse_no_nodes - def add_scanner(self, skey, scanner): + def add_scanner(self, skey, scanner) -> None: self.function[skey] = scanner self.add_skey(skey) @@ -292,7 +292,7 @@ class Selector(ScannerBase): used by various Tool modules and therefore was likely a template for custom modules that may be out there.) """ - def __init__(self, mapping, *args, **kwargs): + def __init__(self, mapping, *args, **kwargs) -> None: super().__init__(None, *args, **kwargs) self.mapping = mapping self.skeys = list(mapping.keys()) @@ -306,7 +306,7 @@ class Selector(ScannerBase): except KeyError: return None - def add_scanner(self, skey, scanner): + def add_scanner(self, skey, scanner) -> None: self.mapping[skey] = scanner self.add_skey(skey) @@ -318,7 +318,7 @@ class Current(ScannerBase): either locally or in a repository). """ - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: def current_check(node, env): return not node.has_builder() or node.is_up_to_date() @@ -337,7 +337,7 @@ class Classic(Current): name of the include file in group 0. """ - def __init__(self, name, suffixes, path_variable, regex, *args, **kwargs): + def __init__(self, name, suffixes, path_variable, regex, *args, **kwargs) -> None: self.cre = re.compile(regex, re.M) def _scan(node, _, path=(), self=self): diff --git a/SCons/Script/Interactive.py b/SCons/Script/Interactive.py index d6947402e..8fd3aa014 100644 --- a/SCons/Script/Interactive.py +++ b/SCons/Script/Interactive.py @@ -112,7 +112,7 @@ version Prints SCons version information. 'sh' : 'shell', } - def __init__(self, **kw): + def __init__(self, **kw) -> None: cmd.Cmd.__init__(self) for key, val in kw.items(): setattr(self, key, val) @@ -122,7 +122,7 @@ version Prints SCons version information. else: self.shell_variable = 'SHELL' - def default(self, argv): + def default(self, argv) -> None: print("*** Unknown command: %s" % argv[0]) def onecmd(self, line): @@ -148,7 +148,7 @@ version Prints SCons version information. return self.default(argv) return func(argv) - def do_build(self, argv): + def do_build(self, argv) -> None: """\ build [TARGETS] Build the specified TARGETS and their dependencies. 'b' is a synonym. @@ -213,11 +213,11 @@ version Prints SCons version information. seen_nodes = {} def get_unseen_children(node, parent, seen_nodes=seen_nodes): - def is_unseen(node, seen_nodes=seen_nodes): + def is_unseen(node, seen_nodes=seen_nodes) -> bool: return node not in seen_nodes return [child for child in node.children(scan=1) if is_unseen(child)] - def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes): + def add_to_seen_nodes(node, parent, seen_nodes=seen_nodes) -> None: seen_nodes[node] = 1 # If this file is in a VariantDir and has a @@ -272,11 +272,11 @@ version Prints SCons version information. """ return self.do_build(['build', '--clean'] + argv[1:]) - def do_EOF(self, argv): + def do_EOF(self, argv) -> None: print() self.do_exit(argv) - def _do_one_help(self, arg): + def _do_one_help(self, arg) -> None: try: # If help_() exists, then call it. func = getattr(self, 'help_' + arg) @@ -312,13 +312,13 @@ version Prints SCons version information. lines = list(map(strip_spaces, lines)) return '\n'.join(lines) - def do_exit(self, argv): + def do_exit(self, argv) -> None: """\ exit Exit SCons interactive mode. """ sys.exit(0) - def do_help(self, argv): + def do_help(self, argv) -> None: """\ help [COMMAND] Prints help for the specified COMMAND. 'h' and '?' are synonyms. @@ -335,7 +335,7 @@ version Prints SCons version information. sys.stdout.write(doc + '\n') sys.stdout.flush() - def do_shell(self, argv): + def do_shell(self, argv) -> None: """\ shell [COMMANDLINE] Execute COMMANDLINE in a subshell. 'sh' and '!' are synonyms. @@ -355,13 +355,13 @@ version Prints SCons version information. else: p.wait() - def do_version(self, argv): + def do_version(self, argv) -> None: """\ version Prints SCons version information. """ sys.stdout.write(self.parser.version + '\n') -def interact(fs, parser, options, targets, target_top): +def interact(fs, parser, options, targets, target_top) -> None: c = SConsInteractiveCmd(prompt = 'scons>>> ', fs = fs, parser = parser, diff --git a/SCons/Script/Main.py b/SCons/Script/Main.py index d4228facb..05e070f61 100644 --- a/SCons/Script/Main.py +++ b/SCons/Script/Main.py @@ -82,7 +82,7 @@ num_jobs = None delayed_warnings = [] -def revert_io(): +def revert_io() -> None: # This call is added to revert stderr and stdout to the original # ones just in case some build rule or something else in the system # has redirected them elsewhere. @@ -103,7 +103,7 @@ class Progressor: count = 0 target_string = '$TARGET' - def __init__(self, obj, interval=1, file=None, overwrite=False): + def __init__(self, obj, interval: int=1, file=None, overwrite: bool=False) -> None: if file is None: file = sys.stdout @@ -121,12 +121,12 @@ class Progressor: else: self.func = self.string - def write(self, s): + def write(self, s) -> None: self.file.write(s) self.file.flush() self.prev = s - def erase_previous(self): + def erase_previous(self) -> None: if self.prev: length = len(self.prev) if self.prev[-1] in ('\n', '\r'): @@ -134,16 +134,16 @@ class Progressor: self.write(' ' * length + '\r') self.prev = '' - def spinner(self, node): + def spinner(self, node) -> None: self.write(self.obj[self.count % len(self.obj)]) - def string(self, node): + def string(self, node) -> None: self.write(self.obj) - def replace_string(self, node): + def replace_string(self, node) -> None: self.write(self.obj.replace(self.target_string, str(node))) - def __call__(self, node): + def __call__(self, node) -> None: self.count = self.count + 1 if (self.count % self.interval) == 0: if self.overwrite: @@ -152,7 +152,7 @@ class Progressor: ProgressObject = SCons.Util.Null() -def Progress(*args, **kw): +def Progress(*args, **kw) -> None: global ProgressObject ProgressObject = Progressor(*args, **kw) @@ -170,7 +170,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): """An SCons build task.""" progress = ProgressObject - def display(self, message): + def display(self, message) -> None: display('scons: ' + message) def prepare(self): @@ -179,14 +179,14 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): self.progress(target) return SCons.Taskmaster.OutOfDateTask.prepare(self) - def needs_execute(self): + def needs_execute(self) -> bool: if SCons.Taskmaster.OutOfDateTask.needs_execute(self): return True if self.top and self.targets[0].has_builder(): display("scons: `%s' is up to date." % str(self.node)) return False - def execute(self): + def execute(self) -> None: if print_time: start_time = time.time() global first_command_start @@ -213,7 +213,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): % (str(self.node), (finish_time - start_time)) ) - def do_failed(self, status=2): + def do_failed(self, status: int=2) -> None: _BuildFailures.append(self.exception[1]) global exit_status global this_build_status @@ -253,7 +253,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): else: SCons.Taskmaster.OutOfDateTask.executed(self) - def failed(self): + def failed(self) -> None: # Handle the failure of a build task. The primary purpose here # is to display the various types of Errors and Exceptions # appropriately. @@ -309,7 +309,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): self.exc_clear() - def postprocess(self): + def postprocess(self) -> None: if self.top: t = self.targets[0] for tp in self.options.tree_printers: @@ -321,7 +321,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): print(tree) SCons.Taskmaster.OutOfDateTask.postprocess(self) - def make_ready(self): + def make_ready(self) -> None: """Make a task ready for execution""" SCons.Taskmaster.OutOfDateTask.make_ready(self) if self.out_of_date and self.options.debug_explain: @@ -332,7 +332,7 @@ class BuildTask(SCons.Taskmaster.OutOfDateTask): class CleanTask(SCons.Taskmaster.AlwaysTask): """An SCons clean task.""" - def fs_delete(self, path, pathstr, remove=True): + def fs_delete(self, path, pathstr, remove: bool=True): try: if os.path.lexists(path): if os.path.isfile(path) or os.path.islink(path): @@ -366,20 +366,20 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): result = [t for t in self.targets if not t.noclean] return result - def _clean_targets(self, remove=True): + def _clean_targets(self, remove: bool=True) -> None: target = self.targets[0] if target in SCons.Environment.CleanTargets: files = SCons.Environment.CleanTargets[target] for f in files: self.fs_delete(f.get_abspath(), str(f), remove) - def show(self): + def show(self) -> None: for t in self._get_files_to_clean(): if not t.isdir(): display("Removed " + str(t)) self._clean_targets(remove=False) - def remove(self): + def remove(self) -> None: for t in self._get_files_to_clean(): try: removed = t.remove() @@ -408,15 +408,15 @@ class CleanTask(SCons.Taskmaster.AlwaysTask): # anything really needs to be done. make_ready = SCons.Taskmaster.Task.make_ready_all - def prepare(self): + def prepare(self) -> None: pass class QuestionTask(SCons.Taskmaster.AlwaysTask): """An SCons task for the -q (question) option.""" - def prepare(self): + def prepare(self) -> None: pass - def execute(self): + def execute(self) -> None: if self.targets[0].get_state() != SCons.Node.up_to_date or \ (self.top and not self.targets[0].exists()): global exit_status @@ -425,12 +425,12 @@ class QuestionTask(SCons.Taskmaster.AlwaysTask): this_build_status = 1 self.tm.stop() - def executed(self): + def executed(self) -> None: pass class TreePrinter: - def __init__(self, derived=False, prune=False, status=False, sLineDraw=False): + def __init__(self, derived: bool=False, prune: bool=False, status: bool=False, sLineDraw: bool=False) -> None: self.derived = derived self.prune = prune self.status = status @@ -440,7 +440,7 @@ class TreePrinter: def get_derived_children(self, node): children = node.all_children(None) return [x for x in children if x.has_builder()] - def display(self, t): + def display(self, t) -> None: if self.derived: func = self.get_derived_children else: @@ -475,7 +475,7 @@ class FakeOptionParser: def __getattr__(self, attr): return None values = FakeOptionValues() - def add_local_option(self, *args, **kw): + def add_local_option(self, *args, **kw) -> None: pass OptionsParser = FakeOptionParser() @@ -493,7 +493,7 @@ def SetOption(name, value): return OptionsParser.values.set_option(name, value) -def ValidateOptions(throw_exception=False) -> None: +def ValidateOptions(throw_exception: bool=False) -> None: """Validate options passed to SCons on the command line. If you call this after you set all your command line options with AddOption(), @@ -512,27 +512,27 @@ def ValidateOptions(throw_exception=False) -> None: OptionsParser.preserve_unknown_options = False OptionsParser.parse_args(OptionsParser.largs, OptionsParser.values) -def PrintHelp(file=None): +def PrintHelp(file=None) -> None: OptionsParser.print_help(file=file) class Stats: - def __init__(self): + def __init__(self) -> None: self.stats = [] self.labels = [] self.append = self.do_nothing self.print_stats = self.do_nothing - def enable(self, outfp): + def enable(self, outfp) -> None: self.outfp = outfp self.append = self.do_append self.print_stats = self.do_print - def do_nothing(self, *args, **kw): + def do_nothing(self, *args, **kw) -> None: pass class CountStats(Stats): - def do_append(self, label): + def do_append(self, label) -> None: self.labels.append(label) self.stats.append(SCons.Debug.fetchLoggedInstances()) - def do_print(self): + def do_print(self) -> None: stats_table = {} for s in self.stats: for n in [t[0] for t in s]: @@ -559,10 +559,10 @@ class CountStats(Stats): count_stats = CountStats() class MemStats(Stats): - def do_append(self, label): + def do_append(self, label) -> None: self.labels.append(label) self.stats.append(SCons.Debug.memory()) - def do_print(self): + def do_print(self) -> None: fmt = 'Memory %-32s %12d\n' for label, stats in zip(self.labels, self.stats): self.outfp.write(fmt % (label, stats)) @@ -571,7 +571,7 @@ memory_stats = MemStats() # utility functions -def _scons_syntax_error(e): +def _scons_syntax_error(e) -> None: """Handle syntax errors. Print out a message and show where the error occurred. """ @@ -599,7 +599,7 @@ def find_deepest_user_frame(tb): return frame return tb[0] -def _scons_user_error(e): +def _scons_user_error(e) -> None: """Handle user errors. Print out a message and a description of the error, along with the line number and routine where it occured. The file and line number will be the deepest stack frame that is @@ -614,7 +614,7 @@ def _scons_user_error(e): sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) sys.exit(2) -def _scons_user_warning(e): +def _scons_user_warning(e) -> None: """Handle user warnings. Print out a message and a description of the warning, along with the line number and routine where it occured. The file and line number will be the deepest stack frame that is @@ -625,7 +625,7 @@ def _scons_user_warning(e): sys.stderr.write("\nscons: warning: %s\n" % e) sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) -def _scons_internal_warning(e): +def _scons_internal_warning(e) -> None: """Slightly different from _scons_user_warning in that we use the *current call stack* rather than sys.exc_info() to get our stack trace. This is used by the warnings framework to print warnings.""" @@ -633,7 +633,7 @@ def _scons_internal_warning(e): sys.stderr.write("\nscons: warning: %s\n" % e.args[0]) sys.stderr.write('File "%s", line %d, in %s\n' % (filename, lineno, routine)) -def _scons_internal_error(): +def _scons_internal_error() -> None: """Handle all errors but user errors. Print out a message telling the user what to do in this case and print a normal trace. """ @@ -641,7 +641,7 @@ def _scons_internal_error(): traceback.print_exc() sys.exit(2) -def _SConstruct_exists(dirname='', repositories=[], filelist=None): +def _SConstruct_exists(dirname: str='', repositories=[], filelist=None): """This function checks that an SConstruct file exists in a directory. If so, it returns the path of the file. By default, it checks the current directory. @@ -658,7 +658,7 @@ def _SConstruct_exists(dirname='', repositories=[], filelist=None): return sfile return None -def _set_debug_values(options): +def _set_debug_values(options) -> None: global print_memoizer, print_objects, print_stacktrace, print_time, print_action_timestamps debug_values = options.debug @@ -798,7 +798,7 @@ def _load_site_scons_dir(topdir, site_dir_name=None): raise -def _load_all_site_scons_dirs(topdir, verbose=False): +def _load_all_site_scons_dirs(topdir, verbose: bool=False) -> None: """Load all of the predefined site_scons dir. Order is significant; we load them in order from most generic (machine-wide) to most specific (topdir). @@ -841,7 +841,7 @@ def _load_all_site_scons_dirs(topdir, verbose=False): print("Loading site dir ", d) _load_site_scons_dir(d) -def test_load_all_site_scons_dirs(d): +def test_load_all_site_scons_dirs(d) -> None: _load_all_site_scons_dirs(d, True) def version_string(label, module): @@ -858,7 +858,7 @@ def version_string(label, module): module.__developer__, module.__buildsys__) -def path_string(label, module): +def path_string(label, module) -> str: path = module.__path__ return "\t%s path: %s\n"%(label,path) @@ -1327,7 +1327,7 @@ def _build_targets(fs, options, targets, target_top): options=options, closing_message=closing_message, failure_message=failure_message - ): + ) -> None: if jobs.were_interrupted(): if not options.no_progress and not options.silent: sys.stderr.write("scons: Build interrupted.\n") @@ -1353,7 +1353,7 @@ def _build_targets(fs, options, targets, target_top): return nodes -def _exec_main(parser, values): +def _exec_main(parser, values) -> None: sconsflags = os.environ.get('SCONSFLAGS', '') all_args = sconsflags.split() + sys.argv[1:] @@ -1374,7 +1374,7 @@ def _exec_main(parser, values): _main(parser) -def main(): +def main() -> None: global OptionsParser global exit_status global first_command_start diff --git a/SCons/Script/SConsOptions.py b/SCons/Script/SConsOptions.py index 8391d6208..fda744535 100644 --- a/SCons/Script/SConsOptions.py +++ b/SCons/Script/SConsOptions.py @@ -98,7 +98,7 @@ class SConsValues(optparse.Values): in the set_option() method. """ - def __init__(self, defaults): + def __init__(self, defaults) -> None: self.__defaults__ = defaults self.__SConscript_settings__ = {} @@ -300,11 +300,11 @@ class SConsBadOptionError(optparse.BadOptionError): """ - def __init__(self, opt_str, parser=None): + def __init__(self, opt_str, parser=None) -> None: self.opt_str = opt_str self.parser = parser - def __str__(self): + def __str__(self) -> str: return _("no such option: %s") % self.opt_str @@ -396,7 +396,7 @@ class SConsOptionParser(optparse.OptionParser): option.process(opt, value, values, self) - def reparse_local_options(self): + def reparse_local_options(self) -> None: """ Re-parse the leftover command-line options. Parse options stored in `self.largs`, so that any value @@ -491,7 +491,7 @@ class SConsOptionParser(optparse.OptionParser): class SConsIndentedHelpFormatter(optparse.IndentedHelpFormatter): - def format_usage(self, usage): + def format_usage(self, usage) -> str: """ Formats the usage message. """ return "usage: %s\n" % usage @@ -610,7 +610,7 @@ def Parser(version): op.version = version # options ignored for compatibility - def opt_ignore(option, opt, value, parser): + def opt_ignore(option, opt, value, parser) -> None: sys.stderr.write("Warning: ignoring %s option\n" % opt) op.add_option("-b", "-d", "-e", "-m", "-S", "-t", "-w", @@ -822,7 +822,7 @@ def Parser(version): action="help", help="Print this message and exit") - def warn_md5_chunksize_deprecated(option, opt, value, parser): + def warn_md5_chunksize_deprecated(option, opt, value, parser) -> None: if opt == '--md5-chunksize': SCons.Warnings.warn(SCons.Warnings.DeprecatedWarning, "Parameter %s is deprecated. Use " @@ -865,7 +865,7 @@ def Parser(version): action="store_true", help="Cache implicit dependencies") - def opt_implicit_deps(option, opt, value, parser): + def opt_implicit_deps(option, opt, value, parser) -> None: setattr(parser.values, 'implicit_cache', True) setattr(parser.values, option.dest, True) @@ -1002,7 +1002,7 @@ def Parser(version): help="Search up directory tree for SConstruct, " "build Default() targets from local SConscript") - def opt_version(option, opt, value, parser): + def opt_version(option, opt, value, parser) -> None: sys.stdout.write(parser.version + '\n') sys.exit(0) @@ -1010,7 +1010,7 @@ def Parser(version): action="callback", callback=opt_version, help="Print the SCons version number and exit") - def opt_warn(option, opt, value, parser, tree_options=tree_options): + def opt_warn(option, opt, value, parser, tree_options=tree_options) -> None: if SCons.Util.is_String(value): value = value.split(',') parser.values.warn.extend(value) @@ -1033,7 +1033,7 @@ def Parser(version): # we don't want to change. These all get a "the -X option is not # yet implemented" message and don't show up in the help output. - def opt_not_yet(option, opt, value, parser): + def opt_not_yet(option, opt, value, parser) -> None: msg = "Warning: the %s option is not yet implemented\n" % opt sys.stderr.write(msg) diff --git a/SCons/Script/SConscript.py b/SCons/Script/SConscript.py index b72f30eee..c0b556c68 100644 --- a/SCons/Script/SConscript.py +++ b/SCons/Script/SConscript.py @@ -104,7 +104,7 @@ def compute_exports(exports): class Frame: """A frame on the SConstruct/SConscript call stack""" - def __init__(self, fs, exports, sconscript): + def __init__(self, fs, exports, sconscript) -> None: self.globals = BuildDefaultGlobals() self.retval = None self.prev_dir = fs.getcwd() @@ -332,7 +332,7 @@ def _SConscript(fs, *files, **kw): else: return tuple(results) -def SConscript_exception(file=sys.stderr): +def SConscript_exception(file=sys.stderr) -> None: """Print an exception stack trace just for the SConscript file(s). This will show users who have Python errors where the problem is, without cluttering the output with all of the internal calls leading @@ -481,11 +481,11 @@ class SConsEnvironment(SCons.Environment.Base): kw['_depth'] = kw.get('_depth', 0) + 1 return SCons.Environment.Base.Configure(self, *args, **kw) - def Default(self, *targets): + def Default(self, *targets) -> None: SCons.Script._Set_Default_Targets(self, targets) @staticmethod - def EnsureSConsVersion(major, minor, revision=0): + def EnsureSConsVersion(major, minor, revision: int=0) -> None: """Exit abnormally if the SCons version is not late enough.""" # split string to avoid replacement during build process if SCons.__version__ == '__' + 'VERSION__': @@ -503,7 +503,7 @@ class SConsEnvironment(SCons.Environment.Base): sys.exit(2) @staticmethod - def EnsurePythonVersion(major, minor): + def EnsurePythonVersion(major, minor) -> None: """Exit abnormally if the Python version is not late enough.""" if sys.version_info < (major, minor): v = sys.version.split()[0] @@ -511,10 +511,10 @@ class SConsEnvironment(SCons.Environment.Base): sys.exit(2) @staticmethod - def Exit(value=0): + def Exit(value: int=0) -> None: sys.exit(value) - def Export(self, *vars, **kw): + def Export(self, *vars, **kw) -> None: for var in vars: global_exports.update(compute_exports(self.Split(var))) global_exports.update(kw) @@ -529,7 +529,7 @@ class SConsEnvironment(SCons.Environment.Base): return SCons.Script.Main.GetOption(name) - def Help(self, text, append=False): + def Help(self, text, append: bool=False) -> None: text = self.subst(text, raw=1) SCons.Script.HelpFunction(text, append=append) @@ -602,7 +602,7 @@ class SConsEnvironment(SCons.Environment.Base): global sconscript_chdir sconscript_chdir = flag - def SetOption(self, name, value): + def SetOption(self, name, value) -> None: name = self.subst(name) SCons.Script.Main.SetOption(name, value) @@ -650,7 +650,7 @@ class DefaultEnvironmentCall: thereby prevent expansion of construction variables (since from the user's point of view this was called as a global function, with no associated construction environment).""" - def __init__(self, method_name, subst=0): + def __init__(self, method_name, subst: int=0) -> None: self.method_name = method_name if subst: self.factory = SCons.Defaults.DefaultEnvironment @@ -674,7 +674,7 @@ def BuildDefaultGlobals(): import SCons.Script d = SCons.Script.__dict__ - def not_a_module(m, d=d, mtype=type(SCons.Script)): + def not_a_module(m, d=d, mtype=type(SCons.Script)) -> bool: return not isinstance(d[m], mtype) for m in filter(not_a_module, dir(SCons.Script)): GlobalDict[m] = d[m] diff --git a/SCons/Script/__init__.py b/SCons/Script/__init__.py index 6cfea1b43..c8666c4ca 100644 --- a/SCons/Script/__init__.py +++ b/SCons/Script/__init__.py @@ -175,11 +175,11 @@ DefaultEnvironment = SCons.Defaults.DefaultEnvironment # Other variables we provide. class TargetList(collections.UserList): - def _do_nothing(self, *args, **kw): + def _do_nothing(self, *args, **kw) -> None: pass - def _add_Default(self, list): + def _add_Default(self, list) -> None: self.extend(list) - def _clear(self): + def _clear(self) -> None: del self[:] ARGUMENTS = {} @@ -199,13 +199,13 @@ DEFAULT_TARGETS = [] # own targets to BUILD_TARGETS. _build_plus_default = TargetList() -def _Add_Arguments(alist): +def _Add_Arguments(alist) -> None: for arg in alist: a, b = arg.split('=', 1) ARGUMENTS[a] = b ARGLIST.append((a, b)) -def _Add_Targets(tlist): +def _Add_Targets(tlist) -> None: if tlist: COMMAND_LINE_TARGETS.extend(tlist) BUILD_TARGETS.extend(tlist) @@ -225,7 +225,7 @@ def _Set_Default_Targets_Has_Not_Been_Called(d, fs): _Get_Default_Targets = _Set_Default_Targets_Has_Not_Been_Called -def _Set_Default_Targets(env, tlist): +def _Set_Default_Targets(env, tlist) -> None: global DEFAULT_TARGETS global _Get_Default_Targets _Get_Default_Targets = _Set_Default_Targets_Has_Been_Called @@ -250,7 +250,7 @@ def _Set_Default_Targets(env, tlist): # help_text = None -def HelpFunction(text, append=False): +def HelpFunction(text, append: bool=False) -> None: global help_text if help_text is None: if append: @@ -271,7 +271,7 @@ sconscript_reading = 0 _no_missing_sconscript = False _warn_missing_sconscript_deprecated = True -def set_missing_sconscript_error(flag=1): +def set_missing_sconscript_error(flag: int=1): """Set behavior on missing file in SConscript() call. Returns: diff --git a/SCons/Subst.py b/SCons/Subst.py index 645639b49..8e6d22ea7 100644 --- a/SCons/Subst.py +++ b/SCons/Subst.py @@ -40,7 +40,7 @@ _strconv = [ AllowableExceptions = (IndexError, NameError) -def SetAllowableExceptions(*excepts): +def SetAllowableExceptions(*excepts) -> None: global AllowableExceptions AllowableExceptions = [_f for _f in excepts if _f] @@ -59,10 +59,10 @@ class Literal: around a string, then it will be interpreted as literal. When passed to the command interpreter, all special characters will be escaped.""" - def __init__(self, lstr): + def __init__(self, lstr) -> None: self.lstr = lstr - def __str__(self): + def __str__(self) -> str: return self.lstr def escape(self, escape_func): @@ -71,7 +71,7 @@ class Literal: def for_signature(self): return self.lstr - def is_literal(self): + def is_literal(self) -> int: return 1 def __eq__(self, other): @@ -79,7 +79,7 @@ class Literal: return False return self.lstr == other.lstr - def __neq__(self, other): + def __neq__(self, other) -> bool: return not self.__eq__(other) def __hash__(self): @@ -94,7 +94,7 @@ class SpecialAttrWrapper: such that we can return some canonical string during signature calculation to avoid unnecessary rebuilds.""" - def __init__(self, lstr, for_signature=None): + def __init__(self, lstr, for_signature=None) -> None: """The for_signature parameter, if supplied, will be the canonical string we return from for_signature(). Else we will simply return lstr.""" @@ -104,7 +104,7 @@ class SpecialAttrWrapper: else: self.forsig = lstr - def __str__(self): + def __str__(self) -> str: return self.lstr def escape(self, escape_func): @@ -113,7 +113,7 @@ class SpecialAttrWrapper: def for_signature(self): return self.forsig - def is_literal(self): + def is_literal(self) -> int: return 1 def quote_spaces(arg): @@ -131,7 +131,7 @@ class CmdStringHolder(collections.UserString): particular platform, it will return the contained string with the proper escape sequences inserted. """ - def __init__(self, cmd, literal=None): + def __init__(self, cmd, literal=None) -> None: super().__init__(cmd) self.literal = literal @@ -180,7 +180,7 @@ class NLWrapper: cleaner conceptually... """ - def __init__(self, list, func): + def __init__(self, list, func) -> None: self.list = list self.func = func def _return_nodelist(self): @@ -209,7 +209,7 @@ class Targets_or_Sources(collections.UserList): a list during variable expansion. We're not really using any collections.UserList methods in practice. """ - def __init__(self, nl): + def __init__(self, nl) -> None: self.nl = nl def __getattr__(self, attr): nl = self.nl._create_nodelist() @@ -217,10 +217,10 @@ class Targets_or_Sources(collections.UserList): def __getitem__(self, i): nl = self.nl._create_nodelist() return nl[i] - def __str__(self): + def __str__(self) -> str: nl = self.nl._create_nodelist() return str(nl) - def __repr__(self): + def __repr__(self) -> str: nl = self.nl._create_nodelist() return repr(nl) @@ -230,7 +230,7 @@ class Target_or_Source: to access an individual proxy Node, calling the NLWrapper to create a proxy on demand. """ - def __init__(self, nl): + def __init__(self, nl) -> None: self.nl = nl def __getattr__(self, attr): nl = self.nl._create_nodelist() @@ -241,20 +241,20 @@ class Target_or_Source: # pass through, so raise AttributeError for everything. raise AttributeError("NodeList has no attribute: %s" % attr) return getattr(nl0, attr) - def __str__(self): + def __str__(self) -> str: nl = self.nl._create_nodelist() if nl: return str(nl[0]) return '' - def __repr__(self): + def __repr__(self) -> str: nl = self.nl._create_nodelist() if nl: return repr(nl[0]) return '' class NullNodeList(SCons.Util.NullSeq): - def __call__(self, *args, **kwargs): return '' - def __str__(self): return '' + def __call__(self, *args, **kwargs) -> str: return '' + def __str__(self) -> str: return '' NullNodesList = NullNodeList() @@ -335,7 +335,7 @@ class StringSubber: """ - def __init__(self, env, mode, conv, gvars): + def __init__(self, env, mode, conv, gvars) -> None: self.env = env self.mode = mode self.conv = conv @@ -489,7 +489,7 @@ class ListSubber(collections.UserList): and the rest of the object takes care of doing the right thing internally. """ - def __init__(self, env, mode, conv, gvars): + def __init__(self, env, mode, conv, gvars) -> None: super().__init__([]) self.env = env self.mode = mode @@ -503,7 +503,7 @@ class ListSubber(collections.UserList): self.in_strip = None self.next_line() - def expanded(self, s): + def expanded(self, s) -> bool: """Determines if the string s requires further expansion. Due to the implementation of ListSubber expand will call @@ -620,7 +620,7 @@ class ListSubber(collections.UserList): else: self.append(s) - def substitute(self, args, lvars, within_list): + def substitute(self, args, lvars, within_list) -> None: """Substitute expansions in an argument or list of arguments. This serves as a wrapper for splitting up a string into @@ -643,23 +643,23 @@ class ListSubber(collections.UserList): else: self.expand(args, lvars, within_list) - def next_line(self): + def next_line(self) -> None: """Arrange for the next word to start a new line. This is like starting a new word, except that we have to append another line to the result.""" collections.UserList.append(self, []) self.next_word() - def this_word(self): + def this_word(self) -> None: """Arrange for the next word to append to the end of the current last word in the result.""" self.append = self.add_to_current_word - def next_word(self): + def next_word(self) -> None: """Arrange for the next word to start a new word.""" self.append = self.add_new_word - def add_to_current_word(self, x): + def add_to_current_word(self, x) -> None: """Append the string x to the end of the current last word in the result. If that is not possible, then just add it as a new word. Make sure the entire concatenated string @@ -707,7 +707,7 @@ class ListSubber(collections.UserList): y = CmdStringHolder(y, None) self[-1][-1] = y - def add_new_word(self, x): + def add_new_word(self, x) -> None: if not self.in_strip or self.mode != SUBST_SIG: literal = self.literal(x) x = self.conv(x) @@ -724,12 +724,12 @@ class ListSubber(collections.UserList): else: return l() - def open_strip(self, x): + def open_strip(self, x) -> None: """Handle the "open strip" $( token.""" self.add_strip(x) self.in_strip = 1 - def close_strip(self, x): + def close_strip(self, x) -> None: """Handle the "close strip" $) token.""" self.add_strip(x) self.in_strip = None @@ -805,7 +805,7 @@ _separate_args = re.compile(r'(%s|\s+|[^\s$]+|\$)' % _dollar_exps_str) _space_sep = re.compile(r'[\t ]+(?![^{]*})') -def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None, overrides=False): +def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None, overrides: bool=False): """Expand a string or list containing construction variable substitutions. @@ -887,7 +887,7 @@ def scons_subst(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={ return result -def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None,overrides=False): +def scons_subst_list(strSubst, env, mode=SUBST_RAW, target=None, source=None, gvars={}, lvars={}, conv=None,overrides: bool=False): """Substitute construction variables in a string (or list or other object) and separate the arguments into a command list. diff --git a/SCons/SubstTests.py b/SCons/SubstTests.py index 16bd3c771..dead45864 100644 --- a/SCons/SubstTests.py +++ b/SCons/SubstTests.py @@ -36,11 +36,11 @@ from SCons.Subst import (Literal, SUBST_CMD, SUBST_RAW, SUBST_SIG, SpecialAttrWr class DummyNode: """Simple node work-alike.""" - def __init__(self, name): + def __init__(self, name) -> None: self.name = os.path.normpath(name) - def __str__(self): + def __str__(self) -> str: return self.name - def is_literal(self): + def is_literal(self) -> int: return 1 def rfile(self): return self @@ -48,7 +48,7 @@ class DummyNode: return self class DummyEnv: - def __init__(self, dict={}): + def __init__(self, dict={}) -> None: self.dict = dict def Dictionary(self, key = None): @@ -68,13 +68,13 @@ class DummyEnv: dict["SOURCES"] = 'ssig' return dict -def cs(target=None, source=None, env=None, for_signature=None): +def cs(target=None, source=None, env=None, for_signature=None) -> str: return 'cs' def cl(target=None, source=None, env=None, for_signature=None): return ['cl'] -def CmdGen1(target, source, env, for_signature): +def CmdGen1(target, source, env, for_signature) -> str: # Nifty trick...since Environment references are interpolated, # instantiate an instance of a callable class with this one, # which will then get evaluated. @@ -83,7 +83,7 @@ def CmdGen1(target, source, env, for_signature): return "${CMDGEN2('foo', %d)}" % for_signature class CmdGen2: - def __init__(self, mystr, forsig): + def __init__(self, mystr, forsig) -> None: self.mystr = mystr self.expect_for_signature = forsig @@ -94,14 +94,14 @@ class CmdGen2: return [ self.mystr, env.Dictionary('BAR') ] -def CallableWithDefault(target, source, env, for_signature, other_value="default"): +def CallableWithDefault(target, source, env, for_signature, other_value: str="default") -> str: assert str(target) == 't', target assert str(source) == 's', source return "CallableWithDefault: %s"%other_value PartialCallable = partial(CallableWithDefault, other_value="partial") -def CallableWithNoDefault(target, source, env, for_signature, other_value): +def CallableWithNoDefault(target, source, env, for_signature, other_value) -> str: assert str(target) == 't', target assert str(source) == 's', source return "CallableWithNoDefault: %s"%other_value @@ -120,7 +120,7 @@ else: class SubstTestCase(unittest.TestCase): class MyNode(DummyNode): """Simple node work-alike with some extra stuff for testing.""" - def __init__(self, name): + def __init__(self, name) -> None: super().__init__(name) class Attribute: pass @@ -132,19 +132,19 @@ class SubstTestCase(unittest.TestCase): foo = 1 class TestLiteral: - def __init__(self, literal): + def __init__(self, literal) -> None: self.literal = literal - def __str__(self): + def __str__(self) -> str: return self.literal - def is_literal(self): + def is_literal(self) -> int: return 1 class TestCallable: - def __init__(self, value): + def __init__(self, value) -> None: self.value = value - def __call__(self): + def __call__(self) -> None: pass - def __str__(self): + def __str__(self) -> str: return self.value # only use of this is currently commented out below @@ -253,7 +253,7 @@ class SubstTestCase(unittest.TestCase): 'DEFS' : [ ('Q1', '"q1"'), ('Q2', '"$AAA"') ], } - def basic_comparisons(self, function, convert): + def basic_comparisons(self, function, convert) -> None: env = DummyEnv(self.loc) cases = self.basic_cases[:] kwargs = {'target' : self.target, 'source' : self.source, @@ -476,7 +476,7 @@ class scons_subst_TestCase(SubstTestCase): ["|", "|", "c", "1"], ] - def test_subst_env(self): + def test_subst_env(self) -> None: """Test scons_subst(): expansion dictionary""" # The expansion dictionary no longer comes from the construction # environment automatically. @@ -484,7 +484,7 @@ class scons_subst_TestCase(SubstTestCase): s = scons_subst('$AAA', env) assert s == '', s - def test_subst_SUBST_modes(self): + def test_subst_SUBST_modes(self) -> None: """Test scons_subst(): SUBST_* modes""" env = DummyEnv(self.loc) subst_cases = self.subst_cases[:] @@ -512,7 +512,7 @@ class scons_subst_TestCase(SubstTestCase): del subst_cases[:4] assert failed == 0, "%d subst() mode cases failed" % failed - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test scons_subst(): target= and source= arguments""" env = DummyEnv(self.loc) t1 = self.MyNode('t1') @@ -534,7 +534,7 @@ class scons_subst_TestCase(SubstTestCase): result = scons_subst("$TARGETS $SOURCE", env, target=[], source=[]) assert result == " ", result - def test_subst_callable_expansion(self): + def test_subst_callable_expansion(self) -> None: """Test scons_subst(): expanding a callable""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -543,7 +543,7 @@ class scons_subst_TestCase(SubstTestCase): gvars=gvars) assert newcom == "test foo bar with spaces.out s t", newcom - def test_subst_callable_with_default_expansion(self): + def test_subst_callable_with_default_expansion(self) -> None: """Test scons_subst(): expanding a callable with a default value arg""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -552,7 +552,7 @@ class scons_subst_TestCase(SubstTestCase): gvars=gvars) assert newcom == "test CallableWithDefault: default s t", newcom - def test_subst_partial_callable_with_default_expansion(self): + def test_subst_partial_callable_with_default_expansion(self) -> None: """Test scons_subst(): expanding a functools.partial callable which sets the default value in the callable""" env = DummyEnv(self.loc) @@ -562,7 +562,7 @@ class scons_subst_TestCase(SubstTestCase): gvars=gvars) assert newcom == "test CallableWithDefault: partial s t", newcom - def test_subst_partial_callable_with_no_default_expansion(self): + def test_subst_partial_callable_with_no_default_expansion(self) -> None: """Test scons_subst(): expanding a functools.partial callable which sets the value for extraneous function argument""" env = DummyEnv(self.loc) @@ -640,7 +640,7 @@ class scons_subst_TestCase(SubstTestCase): raise AssertionError("did not catch expected UserError") try: - def func(a, b, c): + def func(a, b, c) -> None: pass scons_subst("${func(1)}", env, gvars={'func':func}) except SCons.Errors.UserError as e: @@ -654,7 +654,7 @@ class scons_subst_TestCase(SubstTestCase): else: raise AssertionError("did not catch expected UserError") - def test_subst_raw_function(self): + def test_subst_raw_function(self) -> None: """Test scons_subst(): fetch function with SUBST_RAW plus conv""" # Test that the combination of SUBST_RAW plus a pass-through # conversion routine allows us to fetch a function through the @@ -682,7 +682,7 @@ class scons_subst_TestCase(SubstTestCase): node = scons_subst("$NODE", env, mode=SUBST_SIG, conv=s, gvars=gvars) assert node is n1, node - def test_subst_overriding_gvars(self): + def test_subst_overriding_gvars(self) -> None: """Test scons_subst(): supplying an overriding gvars dictionary""" env = DummyEnv({'XXX' : 'xxx'}) result = scons_subst('$XXX', env, gvars=env.Dictionary()) @@ -691,7 +691,7 @@ class scons_subst_TestCase(SubstTestCase): assert result == 'yyy', result class CLVar_TestCase(unittest.TestCase): - def test_CLVar(self): + def test_CLVar(self) -> None: """Test scons_subst() and scons_subst_list() with CLVar objects""" loc = {} @@ -714,7 +714,7 @@ class CLVar_TestCase(unittest.TestCase): assert cmd_list[0][4] == "test", cmd_list[0][4] - def test_subst_overriding_lvars_overrides(self): + def test_subst_overriding_lvars_overrides(self) -> None: """Test that optional passed arg overrides overrides gvars, and existing lvars.""" env=DummyEnv({'XXX' : 'xxx'}) result = scons_subst('$XXX', env, gvars=env.Dictionary(), overrides={'XXX': 'yyz'}) @@ -931,7 +931,7 @@ class scons_subst_list_TestCase(SubstTestCase): [["|", "|", "c", "1"]], ] - def test_subst_env(self): + def test_subst_env(self) -> None: """Test scons_subst_list(): expansion dictionary""" # The expansion dictionary no longer comes from the construction # environment automatically. @@ -939,7 +939,7 @@ class scons_subst_list_TestCase(SubstTestCase): s = scons_subst_list('$AAA', env) assert s == [[]], s - def test_subst_target_source(self): + def test_subst_target_source(self) -> None: """Test scons_subst_list(): target= and source= arguments""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -966,7 +966,7 @@ class scons_subst_list_TestCase(SubstTestCase): gvars=gvars) assert cmd_list == [['testing', 'foo', 'bar with spaces.out', 't', 's']], cmd_list - def test_subst_escape(self): + def test_subst_escape(self) -> None: """Test scons_subst_list(): escape functionality""" env = DummyEnv(self.loc) gvars = env.Dictionary() @@ -1009,7 +1009,7 @@ class scons_subst_list_TestCase(SubstTestCase): c = cmd_list[0][2].escape(escape_func) assert c == 't"', c - def test_subst_SUBST_modes(self): + def test_subst_SUBST_modes(self) -> None: """Test scons_subst_list(): SUBST_* modes""" env = DummyEnv(self.loc) subst_list_cases = self.subst_list_cases[:] @@ -1073,7 +1073,7 @@ class scons_subst_list_TestCase(SubstTestCase): else: raise AssertionError("did not catch expected SyntaxError") - def test_subst_raw_function(self): + def test_subst_raw_function(self) -> None: """Test scons_subst_list(): fetch function with SUBST_RAW plus conv""" # Test that the combination of SUBST_RAW plus a pass-through # conversion routine allows us to fetch a function through the @@ -1086,7 +1086,7 @@ class scons_subst_list_TestCase(SubstTestCase): r = scons_subst_list("$CALLABLE2", env, mode=SUBST_RAW, gvars=gvars) assert r == [['callable-2']], repr(r) - def test_subst_list_overriding_gvars(self): + def test_subst_list_overriding_gvars(self) -> None: """Test scons_subst_list(): overriding conv()""" env = DummyEnv() def s(obj): @@ -1102,7 +1102,7 @@ class scons_subst_list_TestCase(SubstTestCase): node = scons_subst_list("$NODE", env, mode=SUBST_SIG, conv=s, gvars=gvars) assert node == [[n1]], node - def test_subst_list_overriding_gvars2(self): + def test_subst_list_overriding_gvars2(self) -> None: """Test scons_subst_list(): supplying an overriding gvars dictionary""" env = DummyEnv({'XXX' : 'xxx'}) result = scons_subst_list('$XXX', env, gvars=env.Dictionary()) @@ -1110,7 +1110,7 @@ class scons_subst_list_TestCase(SubstTestCase): result = scons_subst_list('$XXX', env, gvars={'XXX' : 'yyy'}) assert result == [['yyy']], result - def test_subst_list_overriding_lvars_overrides(self): + def test_subst_list_overriding_lvars_overrides(self) -> None: """Test that optional passed arg overrides overrides gvars, and existing lvars.""" env = DummyEnv({'XXX':'xxx'}) result = scons_subst_list('$XXX', env, gvars=env.Dictionary(), overrides={'XXX': 'yyy'}) @@ -1168,7 +1168,7 @@ class scons_subst_once_TestCase(unittest.TestCase): ['x', 'x $RECURSE y', 'y'], ] - def test_subst_once(self): + def test_subst_once(self) -> None: """Test the scons_subst_once() function""" env = DummyEnv(self.loc) cases = self.basic_cases[:] @@ -1185,7 +1185,7 @@ class scons_subst_once_TestCase(unittest.TestCase): assert failed == 0, "%d subst() cases failed" % failed class quote_spaces_TestCase(unittest.TestCase): - def test_quote_spaces(self): + def test_quote_spaces(self) -> None: """Test the quote_spaces() method...""" q = quote_spaces('x') assert q == 'x', q @@ -1197,30 +1197,30 @@ class quote_spaces_TestCase(unittest.TestCase): assert q == '"x\tx"', q class Node: - def __init__(self, name, children=[]): + def __init__(self, name, children=[]) -> None: self.children = children self.name = name - def __str__(self): + def __str__(self) -> str: return self.name - def exists(self): + def exists(self) -> int: return 1 - def rexists(self): + def rexists(self) -> int: return 1 - def has_builder(self): + def has_builder(self) -> int: return 1 - def has_explicit_builder(self): + def has_explicit_builder(self) -> int: return 1 - def side_effect(self): + def side_effect(self) -> int: return 1 - def precious(self): + def precious(self) -> int: return 1 - def always_build(self): + def always_build(self) -> int: return 1 - def current(self): + def current(self) -> int: return 1 class LiteralTestCase(unittest.TestCase): - def test_Literal(self): + def test_Literal(self) -> None: """Test the Literal() function.""" input_list = [ '$FOO', Literal('$BAR') ] gvars = { 'FOO' : 'BAZ', 'BAR' : 'BLAT' } @@ -1232,13 +1232,13 @@ class LiteralTestCase(unittest.TestCase): cmd_list = escape_list(cmd_list[0], escape_func) assert cmd_list == ['BAZ', '**$BAR**'], cmd_list - def test_LiteralEqualsTest(self): + def test_LiteralEqualsTest(self) -> None: """Test that Literals compare for equality properly""" assert Literal('a literal') == Literal('a literal') assert Literal('a literal') != Literal('b literal') class SpecialAttrWrapperTestCase(unittest.TestCase): - def test_SpecialAttrWrapper(self): + def test_SpecialAttrWrapper(self) -> None: """Test the SpecialAttrWrapper() function.""" input_list = [ '$FOO', SpecialAttrWrapper('$BAR', 'BLEH') ] gvars = { 'FOO' : 'BAZ', 'BAR' : 'BLAT' } @@ -1255,7 +1255,7 @@ class SpecialAttrWrapperTestCase(unittest.TestCase): assert cmd_list == ['BAZ', '**BLEH**'], cmd_list class subst_dict_TestCase(unittest.TestCase): - def test_subst_dict(self): + def test_subst_dict(self) -> None: """Test substituting dictionary values in an Action """ t = DummyNode('t') @@ -1280,9 +1280,9 @@ class subst_dict_TestCase(unittest.TestCase): class V: # Fake Value node with no rfile() method. - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return 'v-'+self.name def get_subst_proxy(self): return self diff --git a/SCons/Taskmaster/Job.py b/SCons/Taskmaster/Job.py index a63b5291b..572464ba6 100644 --- a/SCons/Taskmaster/Job.py +++ b/SCons/Taskmaster/Job.py @@ -55,10 +55,10 @@ default_stack_size = 256 interrupt_msg = 'Build interrupted.' class InterruptState: - def __init__(self): + def __init__(self) -> None: self.interrupted = False - def set(self): + def set(self) -> None: self.interrupted = True def __call__(self): @@ -70,7 +70,7 @@ class Jobs: methods for starting, stopping, and waiting on all N jobs. """ - def __init__(self, num, taskmaster): + def __init__(self, num, taskmaster) -> None: """ Create 'num' jobs using the given taskmaster. @@ -109,7 +109,7 @@ class Jobs: self.job = Serial(taskmaster) self.num_jobs = 1 - def run(self, postfunc=lambda: None): + def run(self, postfunc=lambda: None) -> None: """Run the jobs. postfunc() will be invoked after the jobs has run. It will be @@ -129,7 +129,7 @@ class Jobs: """Returns whether the jobs were interrupted by a signal.""" return self.job.interrupted() - def _setup_sig_handler(self): + def _setup_sig_handler(self) -> None: """Setup an interrupt handler so that SCons can shutdown cleanly in various conditions: @@ -150,7 +150,7 @@ class Jobs: SCons forks before executing another process. In that case, we want the child to exit immediately. """ - def handler(signum, stack, self=self, parentpid=os.getpid()): + def handler(signum, stack, self=self, parentpid=os.getpid()) -> None: if os.getpid() == parentpid: self.job.taskmaster.stop() self.job.interrupted.set() @@ -169,7 +169,7 @@ class Jobs: "Will not be able to reinstate and so will return to default handler." SCons.Warnings.warn(SCons.Warnings.SConsWarning, msg) - def _reset_sig_handler(self): + def _reset_sig_handler(self) -> None: """Restore the signal handlers to their previous state (before the call to _setup_sig_handler().""" sigint_to_use = self.old_sigint if self.old_sigint is not None else signal.SIG_DFL @@ -191,7 +191,7 @@ class Serial: This class is not thread safe. """ - def __init__(self, taskmaster): + def __init__(self, taskmaster) -> None: """Create a new serial job given a taskmaster. The taskmaster's next_task() method should return the next task @@ -253,7 +253,7 @@ else: dequeues the task, executes it, and posts a tuple including the task and a boolean indicating whether the task executed successfully. """ - def __init__(self, requestQueue, resultsQueue, interrupted): + def __init__(self, requestQueue, resultsQueue, interrupted) -> None: super().__init__() self.daemon = True self.requestQueue = requestQueue @@ -287,7 +287,7 @@ else: class ThreadPool: """This class is responsible for spawning and managing worker threads.""" - def __init__(self, num, stack_size, interrupted): + def __init__(self, num, stack_size, interrupted) -> None: """Create the request and reply queues, and 'num' worker threads. One must specify the stack size of the worker threads. The @@ -318,7 +318,7 @@ else: if 'prev_size' in locals(): threading.stack_size(prev_size) - def put(self, task): + def put(self, task) -> None: """Put task into request queue.""" self.requestQueue.put(task) @@ -326,10 +326,10 @@ else: """Remove and return a result tuple from the results queue.""" return self.resultsQueue.get() - def preparation_failed(self, task): + def preparation_failed(self, task) -> None: self.resultsQueue.put((task, False)) - def cleanup(self): + def cleanup(self) -> None: """ Shuts down the thread pool, giving each worker thread a chance to shut down gracefully. @@ -365,7 +365,7 @@ else: This class is thread safe. """ - def __init__(self, taskmaster, num, stack_size): + def __init__(self, taskmaster, num, stack_size) -> None: """Create a new parallel job given a taskmaster. The taskmaster's next_task() method should return the next @@ -459,16 +459,16 @@ else: COMPLETED = 3 class Worker(threading.Thread): - def __init__(self, owner): + def __init__(self, owner) -> None: super().__init__() self.daemon = True self.owner = owner self.start() - def run(self): + def run(self) -> None: self.owner._work() - def __init__(self, taskmaster, num, stack_size): + def __init__(self, taskmaster, num, stack_size) -> None: self.taskmaster = taskmaster self.num_workers = num self.stack_size = stack_size @@ -507,21 +507,21 @@ else: jl.addHandler(self.taskmaster.trace.log_handler) return jl - def trace_message(self, message): + def trace_message(self, message) -> None: # This grabs the name of the function which calls trace_message() method_name = sys._getframe(1).f_code.co_name + "():" thread_id=threading.get_ident() self.trace.debug('%s.%s [Thread:%s] %s' % (type(self).__name__, method_name, thread_id, message)) # print('%-15s %s' % (method_name, message)) - def start(self): + def start(self) -> None: self._start_workers() for worker in self.workers: worker.join() self.workers = [] self.taskmaster.cleanup() - def _start_workers(self): + def _start_workers(self) -> None: prev_size = self._adjust_stack_size() for _ in range(self.num_workers): self.workers.append(NewParallel.Worker(self)) @@ -544,7 +544,7 @@ else: return None - def _restore_stack_size(self, prev_size): + def _restore_stack_size(self, prev_size) -> None: if prev_size is not None: threading.stack_size(prev_size) diff --git a/SCons/Taskmaster/JobTests.py b/SCons/Taskmaster/JobTests.py index 9e7b08024..3faa97d53 100644 --- a/SCons/Taskmaster/JobTests.py +++ b/SCons/Taskmaster/JobTests.py @@ -63,37 +63,37 @@ num_tasks = num_jobs*5 class DummyLock: """fake lock class to use if threads are not supported""" - def acquire(self): + def acquire(self) -> None: pass - def release(self): + def release(self) -> None: pass class NoThreadsException(Exception): """raised by the ParallelTestCase if threads are not supported""" - def __str__(self): + def __str__(self) -> str: return "the interpreter doesn't support threads" class Task: """A dummy task class for testing purposes.""" - def __init__(self, i, taskmaster): + def __init__(self, i, taskmaster) -> None: self.i = i self.taskmaster = taskmaster self.was_executed = 0 self.was_prepared = 0 - def prepare(self): + def prepare(self) -> None: self.was_prepared = 1 - def _do_something(self): + def _do_something(self) -> None: pass - def needs_execute(self): + def needs_execute(self) -> bool: return True - def execute(self): + def execute(self) -> None: self.taskmaster.test_case.assertTrue(self.was_prepared, "the task wasn't prepared") @@ -119,7 +119,7 @@ class Task: self.taskmaster.end_list.append(self.i) self.taskmaster.guard.release() - def executed(self): + def executed(self) -> None: self.taskmaster.num_executed = self.taskmaster.num_executed + 1 self.taskmaster.test_case.assertTrue(self.was_prepared, @@ -129,20 +129,20 @@ class Task: self.taskmaster.test_case.assertTrue(isinstance(self, Task), "the task wasn't really a Task instance") - def failed(self): + def failed(self) -> None: self.taskmaster.num_failed = self.taskmaster.num_failed + 1 self.taskmaster.stop = 1 self.taskmaster.test_case.assertTrue(self.was_prepared, "the task wasn't prepared") - def postprocess(self): + def postprocess(self) -> None: self.taskmaster.num_postprocessed = self.taskmaster.num_postprocessed + 1 - def exception_set(self): + def exception_set(self) -> None: pass class RandomTask(Task): - def _do_something(self): + def _do_something(self) -> None: # do something that will take some random amount of time: for i in range(random.randrange(0, 100 + num_sines, 1)): x = math.sin(i) @@ -151,20 +151,20 @@ class RandomTask(Task): class ExceptionTask: """A dummy task class for testing purposes.""" - def __init__(self, i, taskmaster): + def __init__(self, i, taskmaster) -> None: self.taskmaster = taskmaster self.was_prepared = 0 - def prepare(self): + def prepare(self) -> None: self.was_prepared = 1 - def needs_execute(self): + def needs_execute(self) -> bool: return True def execute(self): raise Exception - def executed(self): + def executed(self) -> None: self.taskmaster.num_executed = self.taskmaster.num_executed + 1 self.taskmaster.test_case.assertTrue(self.was_prepared, @@ -174,22 +174,22 @@ class ExceptionTask: self.taskmaster.test_case.assertTrue(self.__class__ is Task, "the task wasn't really a Task instance") - def failed(self): + def failed(self) -> None: self.taskmaster.num_failed = self.taskmaster.num_failed + 1 self.taskmaster.stop = 1 self.taskmaster.test_case.assertTrue(self.was_prepared, "the task wasn't prepared") - def postprocess(self): + def postprocess(self) -> None: self.taskmaster.num_postprocessed = self.taskmaster.num_postprocessed + 1 - def exception_set(self): + def exception_set(self) -> None: self.taskmaster.exception_set() class Taskmaster: """A dummy taskmaster class for testing the job classes.""" - def __init__(self, n, test_case, Task): + def __init__(self, n, test_case, Task) -> None: """n is the number of dummy tasks to perform.""" self.test_case = test_case @@ -232,14 +232,14 @@ class Taskmaster: def all_tasks_are_postprocessed(self): return self.num_postprocessed == self.num_tasks - def tasks_were_serial(self): + def tasks_were_serial(self) -> bool: """analyze the task order to see if they were serial""" return not self.found_parallel - def exception_set(self): + def exception_set(self) -> None: pass - def cleanup(self): + def cleanup(self) -> None: pass @@ -292,7 +292,7 @@ class ParallelTestCase(JobTestCase): # tasks complete and get their notifications on the resultsQueue. class SleepTask(Task): - def _do_something(self): + def _do_something(self) -> None: time.sleep(0.01) global SaveThreadPool @@ -329,7 +329,7 @@ class ParallelTestCase(JobTestCase): SCons.Taskmaster.Job.ThreadPool = SaveThreadPool class SerialTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """test a serial job""" taskmaster = Taskmaster(num_tasks, self, RandomTask) @@ -350,7 +350,7 @@ class SerialTestCase(unittest.TestCase): class NoParallelTestCase(JobTestCase): - def runTest(self): + def runTest(self) -> None: """test handling lack of parallel support""" def NoParallel(tm, num, stack_size): raise NameError @@ -377,7 +377,7 @@ class NoParallelTestCase(JobTestCase): class SerialExceptionTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """test a serial job with tasks that raise exceptions""" taskmaster = Taskmaster(num_tasks, self, ExceptionTask) @@ -396,7 +396,7 @@ class SerialExceptionTestCase(unittest.TestCase): class ParallelExceptionTestCase(JobTestCase): - def runTest(self): + def runTest(self) -> None: """test parallel jobs with tasks that raise exceptions""" taskmaster = Taskmaster(num_tasks, self, ExceptionTask) @@ -421,23 +421,23 @@ import SCons.Node import time class DummyNodeInfo: - def update(self, obj): + def update(self, obj) -> None: pass class testnode (SCons.Node.Node): - def __init__(self): + def __init__(self) -> None: super().__init__() self.expect_to_be = SCons.Node.executed self.ninfo = DummyNodeInfo() class goodnode (testnode): - def __init__(self): + def __init__(self) -> None: super().__init__() self.expect_to_be = SCons.Node.up_to_date self.ninfo = DummyNodeInfo() class slowgoodnode (goodnode): - def prepare(self): + def prepare(self) -> None: # Delay to allow scheduled Jobs to run while the dispatcher # sleeps. Keep this short because it affects the time taken # by this test. @@ -445,7 +445,7 @@ class slowgoodnode (goodnode): goodnode.prepare(self) class badnode (goodnode): - def __init__(self): + def __init__(self) -> None: super().__init__() self.expect_to_be = SCons.Node.failed def build(self, **kw): @@ -467,7 +467,7 @@ class badpreparenode (badnode): class _SConsTaskTest(JobTestCase): - def _test_seq(self, num_jobs): + def _test_seq(self, num_jobs) -> None: for node_seq in [ [goodnode], [badnode], @@ -484,7 +484,7 @@ class _SConsTaskTest(JobTestCase): self._do_test(num_jobs, node_seq) - def _do_test(self, num_jobs, node_seq): + def _do_test(self, num_jobs, node_seq) -> None: testnodes = [] for tnum in range(num_tasks): @@ -549,13 +549,13 @@ class _SConsTaskTest(JobTestCase): class SerialTaskTest(_SConsTaskTest): - def runTest(self): + def runTest(self) -> None: """test serial jobs with actual Taskmaster and Task""" self._test_seq(1) class ParallelTaskTest(_SConsTaskTest): - def runTest(self): + def runTest(self) -> None: """test parallel jobs with actual Taskmaster and Task""" self._test_seq(num_jobs) diff --git a/SCons/Taskmaster/TaskmasterTests.py b/SCons/Taskmaster/TaskmasterTests.py index 95150fd98..32959fb0a 100644 --- a/SCons/Taskmaster/TaskmasterTests.py +++ b/SCons/Taskmaster/TaskmasterTests.py @@ -39,7 +39,7 @@ scan_called = 0 class Node: - def __init__(self, name, kids=[], scans=[]): + def __init__(self, name, kids=[], scans=[]) -> None: self.name = name self.kids = kids self.scans = scans @@ -72,7 +72,7 @@ class Node: def disambiguate(self): return self - def push_to_cache(self): + def push_to_cache(self) -> None: pass def retrieve_from_cache(self): @@ -81,18 +81,18 @@ class Node: cache_text.append(self.name + " retrieved") return self.cached - def make_ready(self): + def make_ready(self) -> None: pass - def prepare(self): + def prepare(self) -> None: self.prepared = 1 self.get_binfo() - def build(self): + def build(self) -> None: global built_text built_text = self.name + " built" - def remove(self): + def remove(self) -> None: pass # The following four methods new_binfo(), del_binfo(), @@ -104,7 +104,7 @@ class Node: binfo = "binfo" return binfo - def del_binfo(self): + def del_binfo(self) -> None: """Delete the build info from this node.""" try: delattr(self, 'binfo') @@ -123,13 +123,13 @@ class Node: return binfo - def clear(self): + def clear(self) -> None: # The del_binfo() call here isn't necessary for normal execution, # but is for interactive mode, where we might rebuild the same # target and need to start from scratch. self.del_binfo() - def built(self): + def built(self) -> None: global built_text if not self.cached: built_text = built_text + " really" @@ -141,10 +141,10 @@ class Node: self.clear() - def release_target_info(self): + def release_target_info(self) -> None: pass - def has_builder(self): + def has_builder(self) -> bool: return self.builder is not None def is_derived(self): @@ -153,7 +153,7 @@ class Node: def alter_targets(self): return self.alttargets, None - def visited(self): + def visited(self) -> None: global visited_nodes visited_nodes.append(self.name) @@ -163,7 +163,7 @@ class Node: self.scanned = 1 return self.kids - def scan(self): + def scan(self) -> None: global scan_called scan_called = scan_called + 1 self.kids = self.kids + self.scans @@ -172,7 +172,7 @@ class Node: def scanner_key(self): return self.name - def add_to_waiting_parents(self, node): + def add_to_waiting_parents(self, node) -> int: wp = self.waiting_parents if node in wp: return 0 @@ -182,44 +182,44 @@ class Node: def get_state(self): return self.state - def set_state(self, state): + def set_state(self, state) -> None: self.state = state - def set_bsig(self, bsig): + def set_bsig(self, bsig) -> None: self.bsig = bsig - def set_csig(self, csig): + def set_csig(self, csig) -> None: self.csig = csig - def store_csig(self): + def store_csig(self) -> None: pass - def store_bsig(self): + def store_bsig(self) -> None: pass - def is_pseudo_derived(self): + def is_pseudo_derived(self) -> None: pass def is_up_to_date(self): return self._current_val - def depends_on(self, nodes): + def depends_on(self, nodes) -> int: for node in nodes: if node in self.kids: return 1 return 0 - def __str__(self): + def __str__(self) -> str: return self.name - def postprocess(self): + def postprocess(self) -> None: self.postprocessed = 1 self.waiting_parents = set() def get_executor(self): if not hasattr(self, 'executor'): class Executor: - def prepare(self): + def prepare(self) -> None: pass def get_action_targets(self): @@ -261,7 +261,7 @@ class MyException(Exception): class TaskmasterTestCase(unittest.TestCase): - def test_next_task(self): + def test_next_task(self) -> None: """Test fetching the next task """ global built_text @@ -307,7 +307,7 @@ class TaskmasterTestCase(unittest.TestCase): top_node = n3 class MyTask(SCons.Taskmaster.AlwaysTask): - def execute(self): + def execute(self) -> None: global built_text if self.targets[0].get_state() == SCons.Node.up_to_date: if self.top: @@ -550,14 +550,14 @@ class TaskmasterTestCase(unittest.TestCase): s = n2.get_state() assert s == SCons.Node.executed, s - def test_make_ready_out_of_date(self): + def test_make_ready_out_of_date(self) -> None: """Test the Task.make_ready() method's list of out-of-date Nodes """ ood = [] def TaskGen(tm, targets, top, node, ood=ood): class MyTask(SCons.Taskmaster.AlwaysTask): - def make_ready(self): + def make_ready(self) -> None: SCons.Taskmaster.Task.make_ready(self) self.ood.extend(self.out_of_date) @@ -597,7 +597,7 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() assert ood == [a5], ood - def test_make_ready_exception(self): + def test_make_ready_exception(self) -> None: """Test handling exceptions from Task.make_ready() """ @@ -612,7 +612,7 @@ class TaskmasterTestCase(unittest.TestCase): assert exc_type == MyException, repr(exc_type) assert str(exc_value) == "from make_ready()", exc_value - def test_needs_execute(self): + def test_needs_execute(self) -> None: """Test that we can't instantiate a Task subclass without needs_execute We should be getting: @@ -627,7 +627,7 @@ class TaskmasterTestCase(unittest.TestCase): with self.assertRaises(TypeError): _ = tm.next_task() - def test_make_ready_all(self): + def test_make_ready_all(self) -> None: """Test the make_ready_all() method""" class MyTask(SCons.Taskmaster.AlwaysTask): @@ -688,7 +688,7 @@ class TaskmasterTestCase(unittest.TestCase): t = tm.next_task() assert t is None - def test_children_errors(self): + def test_children_errors(self) -> None: """Test errors when fetching the children of a node. """ @@ -697,7 +697,7 @@ class TaskmasterTestCase(unittest.TestCase): raise SCons.Errors.StopError("stop!") class ExitNode(Node): - def children(self): + def children(self) -> None: sys.exit(77) n1 = StopNode("n1") @@ -715,7 +715,7 @@ class TaskmasterTestCase(unittest.TestCase): assert exc_value.node == n2, exc_value.node assert exc_value.status == 77, exc_value.status - def test_cycle_detection(self): + def test_cycle_detection(self) -> None: """Test detecting dependency cycles """ n1 = Node("n1") @@ -731,7 +731,7 @@ class TaskmasterTestCase(unittest.TestCase): else: assert 'Did not catch expected UserError' - def test_next_top_level_candidate(self): + def test_next_top_level_candidate(self) -> None: """Test the next_top_level_candidate() method """ n1 = Node("n1") @@ -745,7 +745,7 @@ class TaskmasterTestCase(unittest.TestCase): assert t.targets == [n3], list(map(str, t.targets)) assert t.top == 1, t.top - def test_stop(self): + def test_stop(self) -> None: """Test the stop() method Both default and overridden in a subclass. @@ -769,7 +769,7 @@ class TaskmasterTestCase(unittest.TestCase): assert tm.next_task() is None class MyTM(SCons.Taskmaster.Taskmaster): - def stop(self): + def stop(self) -> None: global built_text built_text = "MyTM.stop()" SCons.Taskmaster.Taskmaster.stop(self) @@ -787,7 +787,7 @@ class TaskmasterTestCase(unittest.TestCase): assert built_text == "MyTM.stop()" assert tm.next_task() is None - def test_executed(self): + def test_executed(self) -> None: """Test when a task has been executed """ global built_text @@ -945,7 +945,7 @@ class TaskmasterTestCase(unittest.TestCase): else: raise AssertionError("did not catch expected exception") - def test_execute(self): + def test_execute(self) -> None: """Test executing a task """ global built_text @@ -1043,7 +1043,7 @@ class TaskmasterTestCase(unittest.TestCase): assert built_text is None, built_text assert cache_text == ["n7 retrieved", "n8 retrieved"], cache_text - def test_cached_execute(self): + def test_cached_execute(self) -> None: """Test executing a task with cached targets """ # In issue #2720 Alexei Klimkin detected that the previous @@ -1087,7 +1087,7 @@ class TaskmasterTestCase(unittest.TestCase): has_binfo = hasattr(n1, 'binfo') assert has_binfo, has_binfo - def test_cached_execute_target_unlink_fails(self): + def test_cached_execute_target_unlink_fails(self) -> None: """Test executing a task with cached targets where unlinking one of the targets fail """ global cache_text @@ -1114,7 +1114,7 @@ class TaskmasterTestCase(unittest.TestCase): _save_warn = SCons.Warnings.warn issued_warnings = [] - def fake_warnings_warn(clz, message): + def fake_warnings_warn(clz, message) -> None: nonlocal issued_warnings issued_warnings.append((clz, message)) SCons.Warnings.warn = fake_warnings_warn @@ -1136,7 +1136,7 @@ class TaskmasterTestCase(unittest.TestCase): self.assertEqual(cache_text, ["n1 retrieved"], msg=cache_text) - def test_exception(self): + def test_exception(self) -> None: """Test generic Taskmaster exception handling """ @@ -1221,7 +1221,7 @@ class TaskmasterTestCase(unittest.TestCase): else: assert 0, "did not catch expected exception" - def test_postprocess(self): + def test_postprocess(self) -> None: """Test postprocessing targets to give them a chance to clean up """ n1 = Node("n1") @@ -1247,7 +1247,7 @@ class TaskmasterTestCase(unittest.TestCase): assert n2.postprocessed assert n3.postprocessed - def test_trace(self): + def test_trace(self) -> None: """Test Taskmaster tracing """ import io diff --git a/SCons/Taskmaster/__init__.py b/SCons/Taskmaster/__init__.py index 7ab864eee..7965ca818 100644 --- a/SCons/Taskmaster/__init__.py +++ b/SCons/Taskmaster/__init__.py @@ -81,7 +81,7 @@ class Stats: the Taskmaster records its decision each time it processes the Node. (Ideally, that's just once per Node.) """ - def __init__(self): + def __init__(self) -> None: """ Instantiates a Taskmaster.Stats object, initializing all appropriate counters to zero. @@ -106,7 +106,7 @@ fmt = "%(considered)3d "\ "%(build)3d " -def dump_stats(): +def dump_stats() -> None: for n in sorted(StatsNodes, key=lambda a: str(a)): print((fmt % n.attributes.stats.__dict__) + str(n)) @@ -132,19 +132,19 @@ class Task(ABC): LOGGER = None - def __init__(self, tm, targets, top, node): + def __init__(self, tm, targets, top, node) -> None: self.tm = tm self.targets = targets self.top = top self.node = node self.exc_clear() - def trace_message(self, node, description='node'): + def trace_message(self, node, description: str='node') -> None: # This grabs the name of the function which calls trace_message() method_name=sys._getframe(1).f_code.co_name+"():" Task.LOGGER.debug('%-15s %s %s' % (method_name, description, self.tm.tm_trace_node(node))) - def display(self, message): + def display(self, message) -> None: """ Hook to allow the calling interface to display a message. @@ -157,7 +157,7 @@ class Task(ABC): """ pass - def prepare(self): + def prepare(self) -> None: """ Called just before the task is executed. @@ -260,7 +260,7 @@ class Task(ABC): buildError.exc_info = sys.exc_info() raise buildError - def executed_without_callbacks(self): + def executed_without_callbacks(self) -> None: """ Called when the task has been successfully executed and the Taskmaster instance doesn't want to call @@ -276,7 +276,7 @@ class Task(ABC): side_effect.set_state(NODE_NO_STATE) t.set_state(NODE_EXECUTED) - def executed_with_callbacks(self): + def executed_with_callbacks(self) -> None: """ Called when the task has been successfully executed and the Taskmaster instance wants to call the Node's callback @@ -311,7 +311,7 @@ class Task(ABC): executed = executed_with_callbacks - def failed(self): + def failed(self) -> None: """ Default action when a task fails: stop the build. @@ -321,7 +321,7 @@ class Task(ABC): """ self.fail_stop() - def fail_stop(self): + def fail_stop(self) -> None: """ Explicit stop-the-build failure. @@ -349,7 +349,7 @@ class Task(ABC): self.targets = [self.tm.current_top] self.top = 1 - def fail_continue(self): + def fail_continue(self) -> None: """ Explicit continue-the-build failure. @@ -366,7 +366,7 @@ class Task(ABC): self.tm.will_not_build(self.targets, lambda n: n.set_state(NODE_FAILED)) - def make_ready_all(self): + def make_ready_all(self) -> None: """ Marks all targets in a task ready for execution. @@ -431,7 +431,7 @@ class Task(ABC): make_ready = make_ready_current - def postprocess(self): + def postprocess(self) -> None: """ Post-processes a task after it's been executed. @@ -511,7 +511,7 @@ class Task(ABC): """ return self.exception - def exc_clear(self): + def exc_clear(self) -> None: """ Clears any recorded exception. @@ -521,7 +521,7 @@ class Task(ABC): self.exception = (None, None, None) self.exception_raise = self._no_exception_to_raise - def exception_set(self, exception=None): + def exception_set(self, exception=None) -> None: """ Records an exception to be raised at the appropriate time. @@ -533,7 +533,7 @@ class Task(ABC): self.exception = exception self.exception_raise = self._exception_raise - def _no_exception_to_raise(self): + def _no_exception_to_raise(self) -> None: pass def _exception_raise(self): @@ -563,7 +563,7 @@ class Task(ABC): class AlwaysTask(Task): - def needs_execute(self): + def needs_execute(self) -> bool: """ Always returns True (indicating this Task should always be executed). @@ -606,7 +606,7 @@ class Taskmaster: The Taskmaster for walking the dependency DAG. """ - def __init__(self, targets=[], tasker=None, order=None, trace=None): + def __init__(self, targets=[], tasker=None, order=None, trace=None) -> None: self.original_top = targets self.top_targets_left = targets[:] self.top_targets_left.reverse() @@ -623,7 +623,7 @@ class Taskmaster: self.trace = False self.configure_trace(trace) - def configure_trace(self, trace=None): + def configure_trace(self, trace=None) -> None: """ This handles the command line option --taskmastertrace= It can be: @@ -726,7 +726,7 @@ class Taskmaster: self.will_not_build(candidates) return None - def _validate_pending_children(self): + def _validate_pending_children(self) -> None: """ Validate the content of the pending_children set. Assert if an internal error is found. @@ -803,7 +803,7 @@ class Taskmaster: for p in n.waiting_parents: assert p.ref_count > 0, (str(n), str(p), p.ref_count) - def tm_trace_node(self, node): + def tm_trace_node(self, node) -> str: return('<%-10s %-3s %s>' % (StateString[node.get_state()], node.ref_count, repr(str(node)))) @@ -1047,7 +1047,7 @@ class Taskmaster: return task - def will_not_build(self, nodes, node_func=lambda n: None): + def will_not_build(self, nodes, node_func=lambda n: None) -> None: """ Perform clean-up about nodes that will never be built. Invokes a user defined function on all of these nodes (including all @@ -1092,7 +1092,7 @@ class Taskmaster: # allow us to use in-place updates self.pending_children = pending_children - def stop(self): + def stop(self) -> None: """ Stops the current build completely. """ diff --git a/SCons/Tool/386asm.py b/SCons/Tool/386asm.py index 51738ebc1..f19f75810 100644 --- a/SCons/Tool/386asm.py +++ b/SCons/Tool/386asm.py @@ -39,7 +39,7 @@ import SCons.Util as_module = __import__('as', globals(), locals(), [], 1) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" as_module.generate(env) diff --git a/SCons/Tool/DCommon.py b/SCons/Tool/DCommon.py index 128e56165..a4f976d42 100644 --- a/SCons/Tool/DCommon.py +++ b/SCons/Tool/DCommon.py @@ -32,7 +32,7 @@ Coded by Russel Winder (russel@winder.org.uk) import os.path -def isD(env, source): +def isD(env, source) -> int: if not source: return 0 for s in source: @@ -43,7 +43,7 @@ def isD(env, source): return 0 -def addDPATHToEnv(env, executable): +def addDPATHToEnv(env, executable) -> None: dPath = env.WhereIs(executable) if dPath: phobosDir = dPath[:dPath.rindex(executable)] + '/../src/phobos' diff --git a/SCons/Tool/FortranCommon.py b/SCons/Tool/FortranCommon.py index aff0f9238..f893a12b7 100644 --- a/SCons/Tool/FortranCommon.py +++ b/SCons/Tool/FortranCommon.py @@ -30,7 +30,7 @@ from typing import Tuple import SCons.Scanner.Fortran import SCons.Tool import SCons.Util -from SCons.Action import Action +from SCons.Action import Action, ActionBase def isfortran(env, source) -> bool: @@ -115,7 +115,9 @@ def ComputeFortranSuffixes(suffixes, ppsuffixes) -> None: else: suffixes.extend(upper_suffixes) -def CreateDialectActions(dialect) -> Tuple[Action, Action, Action, Action]: +def CreateDialectActions( + dialect: str, +) -> Tuple[ActionBase, ActionBase, ActionBase, ActionBase]: """Create dialect specific actions.""" CompAction = Action(f'${dialect}COM ', cmdstr=f'${dialect}COMSTR') CompPPAction = Action(f'${dialect}PPCOM ', cmdstr=f'${dialect}PPCOMSTR') @@ -124,7 +126,7 @@ def CreateDialectActions(dialect) -> Tuple[Action, Action, Action, Action]: return CompAction, CompPPAction, ShCompAction, ShCompPPAction -def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_mods=False) -> None: +def DialectAddToEnv(env, dialect, suffixes, ppsuffixes, support_mods: bool=False) -> None: """Add dialect specific construction variables. Args: diff --git a/SCons/Tool/FortranCommonTests.py b/SCons/Tool/FortranCommonTests.py index 56f41c7e7..a2960d6d3 100644 --- a/SCons/Tool/FortranCommonTests.py +++ b/SCons/Tool/FortranCommonTests.py @@ -44,21 +44,21 @@ os.chdir(test.workpath('')) class DummyEnvironment: dictionary = None # type: Dict[Any, Any] - def __init__(self, list_cpp_path): + def __init__(self, list_cpp_path) -> None: self.path = list_cpp_path self.fs = SCons.Node.FS.FS(test.workpath('')) self.dictionary = {} - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dictionary def __getitem__(self, key): return self.dictionary[key] - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.dictionary[key] = value - def __delitem__(self, key): + def __delitem__(self, key) -> None: del self.dictionary[key] def subst(self, arg, target=None, source=None, conv=None): @@ -85,7 +85,7 @@ class DummyEnvironment: class FortranScannerSubmodulesTestCase(unittest.TestCase): - def runTest(self): + def runTest(self) -> None: """ Check that test_1.f90 and test_2.f90 which have interface specifications Don't generate targets for those modules listed in the interface section diff --git a/SCons/Tool/GettextCommon.py b/SCons/Tool/GettextCommon.py index 058b9971e..ba9ce3102 100644 --- a/SCons/Tool/GettextCommon.py +++ b/SCons/Tool/GettextCommon.py @@ -82,8 +82,8 @@ class _POTargetFactory: default for all produced nodes. """ - def __init__(self, env, nodefault=True, alias=None, precious=True - , noclean=True): + def __init__(self, env, nodefault: bool=True, alias=None, precious: bool=True + , noclean: bool=True) -> None: """ Object constructor. **Arguments** @@ -104,7 +104,7 @@ class _POTargetFactory: self.noclean = noclean self.nodefault = nodefault - def _create_node(self, name, factory, directory=None, create=1): + def _create_node(self, name, factory, directory=None, create: int=1): """ Create node, and set it up to factory settings. """ node = factory(name, directory, create) node.set_noclean(self.noclean) @@ -115,11 +115,11 @@ class _POTargetFactory: self.env.AlwaysBuild(self.env.Alias(self.alias, node)) return node - def Entry(self, name, directory=None, create=1): + def Entry(self, name, directory=None, create: int=1): """ Create `SCons.Node.FS.Entry` """ return self._create_node(name, self.env.fs.Entry, directory, create) - def File(self, name, directory=None, create=1): + def File(self, name, directory=None, create: int=1): """ Create `SCons.Node.FS.File` """ return self._create_node(name, self.env.fs.File, directory, create) @@ -191,7 +191,7 @@ class _POFileBuilder(BuilderBase): # and execute iterativelly (recursion) self._execute(None, source[i]). # After that it calls emitter (which is quite too late). The emitter is # also called in each iteration, what makes things yet worse. - def __init__(self, env, **kw): + def __init__(self, env, **kw) -> None: if 'suffix' not in kw: kw['suffix'] = '$POSUFFIX' if 'src_suffix' not in kw: @@ -300,7 +300,7 @@ class RPaths: # seems be enough for our purposes (don't need TARGET variable and # SCons.Defaults.Variable_Caller stuff). - def __init__(self, env): + def __init__(self, env) -> None: """ Initialize `RPaths` callable object. **Arguments**: diff --git a/SCons/Tool/JavaCommon.py b/SCons/Tool/JavaCommon.py index adec1d3a7..96000d06b 100644 --- a/SCons/Tool/JavaCommon.py +++ b/SCons/Tool/JavaCommon.py @@ -100,7 +100,7 @@ if java_parsing: """The initial state for parsing a Java file for classes, interfaces, and anonymous inner classes.""" - def __init__(self, version=default_java_version): + def __init__(self, version=default_java_version) -> None: if version not in ( '1.1', '1.2', @@ -136,7 +136,7 @@ if java_parsing: self.anonStacksStack = [[0]] self.package = None - def trace(self): + def trace(self) -> None: pass def __getClassState(self): @@ -175,10 +175,10 @@ if java_parsing: def _getAnonStack(self): return self.anonStacksStack[-1] - def openBracket(self): + def openBracket(self) -> None: self.brackets = self.brackets + 1 - def closeBracket(self): + def closeBracket(self) -> None: self.brackets = self.brackets - 1 if len(self.stackBrackets) and \ self.brackets == self.stackBrackets[-1]: @@ -223,7 +223,7 @@ if java_parsing: return self.__getSkipState() return self - def addAnonClass(self): + def addAnonClass(self) -> None: """Add an anonymous inner class""" if self.version in ('1.1', '1.2', '1.3', '1.4'): clazz = self.listClasses[0] @@ -257,7 +257,7 @@ if java_parsing: self.nextAnon = self.nextAnon + 1 self._getAnonStack().append(0) - def setPackage(self, package): + def setPackage(self, package) -> None: self.package = package @@ -267,7 +267,7 @@ if java_parsing: within the confines of a scope. """ - def __init__(self, old_state): + def __init__(self, old_state) -> None: self.outer_state = old_state.outer_state self.old_state = old_state self.brackets = 0 @@ -296,10 +296,10 @@ if java_parsing: self.skipState = ret return ret - def openBracket(self): + def openBracket(self) -> None: self.brackets = self.brackets + 1 - def closeBracket(self): + def closeBracket(self) -> None: self.brackets = self.brackets - 1 def parseToken(self, token): @@ -332,7 +332,7 @@ if java_parsing: class AnonClassState: """A state that looks for anonymous inner classes.""" - def __init__(self, old_state): + def __init__(self, old_state) -> None: # outer_state is always an instance of OuterState self.outer_state = old_state.outer_state self.old_state = old_state @@ -373,7 +373,7 @@ if java_parsing: """A state that will skip a specified number of tokens before reverting to the previous state.""" - def __init__(self, tokens_to_skip, old_state): + def __init__(self, tokens_to_skip, old_state) -> None: self.tokens_to_skip = tokens_to_skip self.old_state = old_state @@ -387,7 +387,7 @@ if java_parsing: class ClassState: """A state we go into when we hit a class or interface keyword.""" - def __init__(self, outer_state): + def __init__(self, outer_state) -> None: # outer_state is always an instance of OuterState self.outer_state = outer_state @@ -419,7 +419,7 @@ if java_parsing: """A state that will ignore all tokens until it gets to a specified token.""" - def __init__(self, ignore_until, old_state): + def __init__(self, ignore_until, old_state) -> None: self.ignore_until = ignore_until self.old_state = old_state @@ -433,7 +433,7 @@ if java_parsing: """The state we enter when we encounter the package keyword. We assume the next token will be the package name.""" - def __init__(self, outer_state): + def __init__(self, outer_state) -> None: # outer_state is always an instance of OuterState self.outer_state = outer_state diff --git a/SCons/Tool/JavaCommonTests.py b/SCons/Tool/JavaCommonTests.py index 75e75efd6..fa462b698 100644 --- a/SCons/Tool/JavaCommonTests.py +++ b/SCons/Tool/JavaCommonTests.py @@ -34,14 +34,14 @@ import TestSCons # the parser to spit out trace messages of the tokens it sees and the # attendant transitions. -def trace(token, newstate): +def trace(token, newstate) -> None: from SCons.Debug import Trace statename = newstate.__class__.__name__ Trace('token = %s, state = %s\n' % (repr(token), statename)) class parse_javaTestCase(unittest.TestCase): - def test_bare_bones(self): + def test_bare_bones(self) -> None: """Test a bare-bones class""" input = """\ @@ -65,7 +65,7 @@ public class Foo assert classes == ['Foo'], classes - def test_file_parser(self): + def test_file_parser(self) -> None: """Test the file parser""" input = """\ package com.sub.bar; @@ -90,7 +90,7 @@ public class Foo assert classes == ['Foo'], classes - def test_dollar_sign(self): + def test_dollar_sign(self) -> None: """Test class names with $ in them""" input = """\ @@ -104,7 +104,7 @@ public class BadDep { - def test_inner_classes(self): + def test_inner_classes(self) -> None: """Test parsing various forms of inner classes""" input = """\ @@ -227,7 +227,7 @@ class Private { - def test_comments(self): + def test_comments(self) -> None: """Test a class with comments""" input = """\ @@ -272,7 +272,7 @@ public class Example1 extends UnicastRemoteObject implements Hello { assert classes == ['Example1'], classes - def test_arrays(self): + def test_arrays(self) -> None: """Test arrays of class instances""" input = """\ @@ -292,7 +292,7 @@ public class Test { - def test_backslash(self): + def test_backslash(self) -> None: """Test backslash handling""" input = """\ @@ -310,7 +310,7 @@ public class MyTabs assert classes == ['MyTabs$MyInternal', 'MyTabs'], classes - def test_enum(self): + def test_enum(self) -> None: """Test the Java 1.5 enum keyword""" input = """\ @@ -323,7 +323,7 @@ public enum a {} assert classes == ['a'], classes - def test_anon_classes(self): + def test_anon_classes(self) -> None: """Test anonymous classes""" input = """\ @@ -347,7 +347,7 @@ public abstract class TestClass assert classes == ['TestClass$1', 'TestClass$2', 'TestClass'], classes - def test_closing_bracket(self): + def test_closing_bracket(self) -> None: """Test finding a closing bracket instead of an anonymous class""" input = """\ @@ -365,7 +365,7 @@ class Foo { } assert classes == ['TestSCons', 'Foo'], classes - def test_dot_class_attributes(self): + def test_dot_class_attributes(self) -> None: """Test handling ".class" attributes""" input = """\ @@ -398,7 +398,7 @@ public class A { assert pkg_dir is None, pkg_dir assert classes == ['A$B', 'A'], classes - def test_anonymous_classes_with_parentheses(self): + def test_anonymous_classes_with_parentheses(self) -> None: """Test finding anonymous classes marked by parentheses""" input = """\ @@ -432,7 +432,7 @@ public class Foo { - def test_nested_anonymous_inner_classes(self): + def test_nested_anonymous_inner_classes(self) -> None: """Test finding nested anonymous inner classes""" input = """\ @@ -481,7 +481,7 @@ public class NestedExample expect = [ 'NestedExample$1', 'NestedExample$1$1', 'NestedExample' ] assert expect == classes, (expect, classes) - def test_lambda_after_new(self): + def test_lambda_after_new(self) -> None: """Test lamdas after new""" input = """\ @@ -518,7 +518,7 @@ public class LamdaExample expect = [ 'LamdaExample' ] assert expect == classes, (expect, classes) - def test_private_inner_class_instantiation(self): + def test_private_inner_class_instantiation(self) -> None: """Test anonymous inner class generated by private instantiation""" input = """\ @@ -551,7 +551,7 @@ class test pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.5') assert expect == classes, (expect, classes) - def test_floating_point_numbers(self): + def test_floating_point_numbers(self) -> None: """Test floating-point numbers in the input stream""" input = """ // Broken.java @@ -592,7 +592,7 @@ class Broken assert expect == classes, (expect, classes) - def test_genercis(self): + def test_genercis(self) -> None: """Test that generics don't interfere with detecting anonymous classes""" input = """\ @@ -624,7 +624,7 @@ public class Foo assert expect == classes, (expect, classes) - def test_in_function_class_declaration(self): + def test_in_function_class_declaration(self) -> None: """ Test that implementing a class in a function call doesn't confuse SCons. """ @@ -667,7 +667,7 @@ public class AnonDemo { pkg_dir, classes = SCons.Tool.JavaCommon.parse_java(input, '1.8') assert expect == classes, (expect, classes) - def test_jdk_globs(self): + def test_jdk_globs(self) -> None: """ Verify that the java path globs work with specific examples. :return: diff --git a/SCons/Tool/MSCommon/MSVC/ConfigTests.py b/SCons/Tool/MSCommon/MSVC/ConfigTests.py index 89db6cda5..cbd811e45 100644 --- a/SCons/Tool/MSCommon/MSVC/ConfigTests.py +++ b/SCons/Tool/MSCommon/MSVC/ConfigTests.py @@ -44,7 +44,7 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: vc._VCVER = cls._VCVER class Config: @@ -58,13 +58,13 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Config.MSVC_VERSION_INTERNAL = cls.MSVC_VERSION_INTERNAL class ConfigTests(unittest.TestCase): - def test_vcver(self): + def test_vcver(self) -> None: # all vc._VCVER in Config.MSVC_VERSION_SUFFIX _VCVER = Patch.vc._VCVER.enable_copy() _VCVER.append('99.9') @@ -72,7 +72,7 @@ class ConfigTests(unittest.TestCase): Config.verify() Patch.vc._VCVER.restore() - def test_msvc_version_internal(self): + def test_msvc_version_internal(self) -> None: # all vc._VCVER numstr in Config.MSVC_VERSION_INTERNAL MSVC_VERSION_INTERNAL = Patch.Config.MSVC_VERSION_INTERNAL.enable_copy() del MSVC_VERSION_INTERNAL['14.3'] @@ -80,7 +80,7 @@ class ConfigTests(unittest.TestCase): Config.verify() Patch.Config.MSVC_VERSION_INTERNAL.restore() - def test_verify(self): + def test_verify(self) -> None: Config.verify() diff --git a/SCons/Tool/MSCommon/MSVC/Dispatcher.py b/SCons/Tool/MSCommon/MSVC/Dispatcher.py index 42b5287b0..31233a969 100644 --- a/SCons/Tool/MSCommon/MSVC/Dispatcher.py +++ b/SCons/Tool/MSCommon/MSVC/Dispatcher.py @@ -53,16 +53,16 @@ from ..common import ( _refs = [] -def register_modulename(modname): +def register_modulename(modname) -> None: module = sys.modules[modname] _refs.append(module) -def register_class(ref): +def register_class(ref) -> None: _refs.append(ref) -def reset(): +def reset() -> None: debug('') for ref in _refs: for method in ['reset', '_reset']: @@ -73,7 +73,7 @@ def reset(): func() -def verify(): +def verify() -> None: debug('') for ref in _refs: for method in ['verify', '_verify']: diff --git a/SCons/Tool/MSCommon/MSVC/DispatcherTests.py b/SCons/Tool/MSCommon/MSVC/DispatcherTests.py index d6af8d464..61ea3f12f 100644 --- a/SCons/Tool/MSCommon/MSVC/DispatcherTests.py +++ b/SCons/Tool/MSCommon/MSVC/DispatcherTests.py @@ -46,37 +46,37 @@ verify = None class StaticMethods: @staticmethod - def _reset(): + def _reset() -> None: Data.reset_count += 1 @staticmethod - def reset(): + def reset() -> None: Data.reset_count += 1 @staticmethod - def _verify(): + def _verify() -> None: Data.verify_count += 1 @staticmethod - def verify(): + def verify() -> None: Data.verify_count += 1 class ClassMethods: @classmethod - def _reset(cls): + def _reset(cls) -> None: Data.reset_count += 1 @classmethod - def reset(cls): + def reset(cls) -> None: Data.reset_count += 1 @classmethod - def _verify(cls): + def _verify(cls) -> None: Data.verify_count += 1 @classmethod - def verify(cls): + def verify(cls) -> None: Data.verify_count += 1 @@ -94,22 +94,22 @@ MSVC.Dispatcher.register_class(NotCallable) class DispatcherTests(unittest.TestCase): - def test_dispatcher_reset(self): + def test_dispatcher_reset(self) -> None: MSVC.Dispatcher.reset() self.assertTrue(Data.reset_count == 4, "MSVC.Dispatcher.reset() count failed") Data.reset_count = 0 - def test_dispatcher_verify(self): + def test_dispatcher_verify(self) -> None: MSVC.Dispatcher.verify() self.assertTrue(Data.verify_count == 4, "MSVC.Dispatcher.verify() count failed") Data.verify_count = 0 - def test_msvc_reset(self): + def test_msvc_reset(self) -> None: MSVC._reset() self.assertTrue(Data.reset_count == 4, "MSVC._reset() count failed") Data.reset_count = 0 - def test_msvc_verify(self): + def test_msvc_verify(self) -> None: MSVC._verify() self.assertTrue(Data.verify_count == 4, "MSVC._verify() count failed") Data.verify_count = 0 diff --git a/SCons/Tool/MSCommon/MSVC/PolicyTests.py b/SCons/Tool/MSCommon/MSVC/PolicyTests.py index 013fd477d..a312d1191 100644 --- a/SCons/Tool/MSCommon/MSVC/PolicyTests.py +++ b/SCons/Tool/MSCommon/MSVC/PolicyTests.py @@ -43,22 +43,22 @@ from SCons.Tool.MSCommon.MSVC.Warnings import ( class PolicyTests(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.warnstack = [] - def push_warning_as_exception(self, warning_class): + def push_warning_as_exception(self, warning_class) -> None: SCons.Warnings.enableWarningClass(warning_class) prev_state = SCons.Warnings.warningAsException() self.warnstack.append((warning_class, prev_state)) - def pop_warning_as_exception(self): + def pop_warning_as_exception(self) -> None: warning_class, prev_state = self.warnstack.pop() SCons.Warnings.warningAsException(prev_state) SCons.Warnings.suppressWarningClass(warning_class) # msvc_set_notfound_policy, msvc_get_notfound_policy, and MSVC_NOTFOUND_POLICY - def test_notfound_func_valid_symbols(self): + def test_notfound_func_valid_symbols(self) -> None: def_policy = Policy.msvc_get_notfound_policy() last_policy = def_policy for notfound_def in Policy.MSVC_NOTFOUND_DEFINITION_LIST: @@ -75,21 +75,21 @@ class PolicyTests(unittest.TestCase): last_policy = cur_get_policy Policy.msvc_set_notfound_policy(def_policy) - def test_notfound_func_invalid_symbol(self): + def test_notfound_func_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_set_notfound_policy('Undefined') - def test_notfound_handler_invalid_symbol(self): + def test_notfound_handler_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': 'Undefined'}, '') - def test_notfound_handler_ignore(self): + def test_notfound_handler_ignore(self) -> None: def_policy = Policy.msvc_set_notfound_policy('Ignore') Policy.msvc_notfound_handler(None, '') Policy.msvc_notfound_handler({'MSVC_NOTFOUND_POLICY': None}, '') Policy.msvc_set_notfound_policy(def_policy) - def test_notfound_handler_warning(self): + def test_notfound_handler_warning(self) -> None: # treat warning as exception for testing self.push_warning_as_exception(SCons.Warnings.VisualCMissingWarning) def_policy = Policy.msvc_set_notfound_policy('Warning') @@ -101,7 +101,7 @@ class PolicyTests(unittest.TestCase): Policy.msvc_set_notfound_policy(def_policy) self.pop_warning_as_exception() - def test_notfound_handler_error(self): + def test_notfound_handler_error(self) -> None: def_policy = Policy.msvc_set_notfound_policy('Error') with self.assertRaises(MSVCVersionNotFound): Policy.msvc_notfound_handler(None, '') @@ -112,7 +112,7 @@ class PolicyTests(unittest.TestCase): # msvc_set_scripterror_policy, msvc_get_scripterror_policy, and MSVC_SCRIPTERROR_POLICY - def test_scripterror_func_valid_symbols(self): + def test_scripterror_func_valid_symbols(self) -> None: def_policy = Policy.msvc_get_scripterror_policy() last_policy = def_policy for scripterror_def in Policy.MSVC_SCRIPTERROR_DEFINITION_LIST: @@ -129,21 +129,21 @@ class PolicyTests(unittest.TestCase): last_policy = cur_get_policy Policy.msvc_set_scripterror_policy(def_policy) - def test_scripterror_func_invalid_symbol(self): + def test_scripterror_func_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_set_scripterror_policy('Undefined') - def test_scripterror_handler_invalid_symbol(self): + def test_scripterror_handler_invalid_symbol(self) -> None: with self.assertRaises(MSVCArgumentError): Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': 'Undefined'}, '') - def test_scripterror_handler_ignore(self): + def test_scripterror_handler_ignore(self) -> None: def_policy = Policy.msvc_set_scripterror_policy('Ignore') Policy.msvc_scripterror_handler(None, '') Policy.msvc_scripterror_handler({'MSVC_SCRIPTERROR_POLICY': None}, '') Policy.msvc_set_scripterror_policy(def_policy) - def test_scripterror_handler_warning(self): + def test_scripterror_handler_warning(self) -> None: # treat warning as exception for testing self.push_warning_as_exception(MSVCScriptExecutionWarning) def_policy = Policy.msvc_set_scripterror_policy('Warning') @@ -155,7 +155,7 @@ class PolicyTests(unittest.TestCase): Policy.msvc_set_scripterror_policy(def_policy) self.pop_warning_as_exception() - def test_scripterror_handler_error(self): + def test_scripterror_handler_error(self) -> None: def_policy = Policy.msvc_set_scripterror_policy('Error') with self.assertRaises(MSVCScriptExecutionError): Policy.msvc_scripterror_handler(None, '') diff --git a/SCons/Tool/MSCommon/MSVC/Registry.py b/SCons/Tool/MSCommon/MSVC/Registry.py index 9519e1553..eee20ccbc 100644 --- a/SCons/Tool/MSCommon/MSVC/Registry.py +++ b/SCons/Tool/MSCommon/MSVC/Registry.py @@ -46,7 +46,7 @@ Dispatcher.register_modulename(__name__) # A null-terminated string that contains unexpanded references to environment variables. REG_EXPAND_SZ = 2 -def read_value(hkey, subkey_valname, expand=True): +def read_value(hkey, subkey_valname, expand: bool=True): try: rval_t = RegGetValue(hkey, subkey_valname) except OSError: @@ -58,7 +58,7 @@ def read_value(hkey, subkey_valname, expand=True): debug('hkey=%s, subkey=%s, rval=%s', repr(hkey), repr(subkey_valname), repr(rval)) return rval -def registry_query_path(key, val, suffix, expand=True): +def registry_query_path(key, val, suffix, expand: bool=True): extval = val + '\\' + suffix if suffix else val qpath = read_value(key, extval, expand=expand) if qpath and os.path.exists(qpath): @@ -74,7 +74,7 @@ REG_SOFTWARE_MICROSOFT = [ (HKEY_CURRENT_USER, r'Software\Microsoft'), ] -def microsoft_query_paths(suffix, usrval=None, expand=True): +def microsoft_query_paths(suffix, usrval=None, expand: bool=True): paths = [] records = [] for key, val in REG_SOFTWARE_MICROSOFT: @@ -87,7 +87,7 @@ def microsoft_query_paths(suffix, usrval=None, expand=True): records.append((qpath, key, val, extval, usrval)) return records -def microsoft_query_keys(suffix, usrval=None, expand=True): +def microsoft_query_keys(suffix, usrval=None, expand: bool=True): records = [] for key, val in REG_SOFTWARE_MICROSOFT: extval = val + '\\' + suffix if suffix else val diff --git a/SCons/Tool/MSCommon/MSVC/RegistryTests.py b/SCons/Tool/MSCommon/MSVC/RegistryTests.py index aff3b3f99..9c9ef89a0 100644 --- a/SCons/Tool/MSCommon/MSVC/RegistryTests.py +++ b/SCons/Tool/MSCommon/MSVC/RegistryTests.py @@ -37,7 +37,7 @@ class RegistryTests(unittest.TestCase): _sdk_versions = None @classmethod - def setUpClass(cls): + def setUpClass(cls) -> None: cls._sdk_versions = [] sdk_seen = set() for vs_def in Config.VISUALSTUDIO_DEFINITION_LIST: @@ -49,24 +49,24 @@ class RegistryTests(unittest.TestCase): sdk_seen.add(sdk_version) cls._sdk_versions.append(sdk_version) - def setUp(self): + def setUp(self) -> None: self.sdk_versions = self.__class__._sdk_versions - def test_sdk_query_paths(self): + def test_sdk_query_paths(self) -> None: for sdk_version in self.sdk_versions: _ = Registry.sdk_query_paths(sdk_version) - def test_vstudio_sxs_vc7(self): + def test_vstudio_sxs_vc7(self) -> None: suffix = Registry.vstudio_sxs_vc7('14.0') _ = Registry.microsoft_query_paths(suffix) - def test_microsoft_query_keys(self): + def test_microsoft_query_keys(self) -> None: val = r'SYSTEM\CurrentControlSet\Control\Session Manager\Environment' for suffix in ['Temp', 'Tmp']: _ = Registry.registry_query_path(Registry.HKEY_LOCAL_MACHINE, val, suffix, expand=True) _ = Registry.registry_query_path(Registry.HKEY_LOCAL_MACHINE, val, suffix, expand=False) - def test_registry_query_path(self): + def test_registry_query_path(self) -> None: # need a better test for when VS2015 is no longer installed for component_reg in ('enterprise', 'professional', 'community'): suffix = Registry.devdiv_vs_servicing_component('14.0', component_reg) @@ -74,7 +74,7 @@ class RegistryTests(unittest.TestCase): if not rval: continue - def test_windows_kit_query_paths(self): + def test_windows_kit_query_paths(self) -> None: for sdk_version in self.sdk_versions: _ = Registry.windows_kit_query_paths(sdk_version) diff --git a/SCons/Tool/MSCommon/MSVC/ScriptArguments.py b/SCons/Tool/MSCommon/MSVC/ScriptArguments.py index 57dbf9d3f..a5ceb332f 100644 --- a/SCons/Tool/MSCommon/MSVC/ScriptArguments.py +++ b/SCons/Tool/MSCommon/MSVC/ScriptArguments.py @@ -107,12 +107,12 @@ _MSVC_FORCE_DEFAULT_TOOLSET = False # Force default arguments _MSVC_FORCE_DEFAULT_ARGUMENTS = False -def _msvc_force_default_sdk(force=True): +def _msvc_force_default_sdk(force: bool=True) -> None: global _MSVC_FORCE_DEFAULT_SDK _MSVC_FORCE_DEFAULT_SDK = force debug('_MSVC_FORCE_DEFAULT_SDK=%s', repr(force)) -def _msvc_force_default_toolset(force=True): +def _msvc_force_default_toolset(force: bool=True) -> None: global _MSVC_FORCE_DEFAULT_TOOLSET _MSVC_FORCE_DEFAULT_TOOLSET = force debug('_MSVC_FORCE_DEFAULT_TOOLSET=%s', repr(force)) @@ -227,7 +227,7 @@ def _msvc_script_argument_uwp(env, msvc, arglist): return uwp_arg -def _user_script_argument_uwp(env, uwp, user_argstr): +def _user_script_argument_uwp(env, uwp, user_argstr) -> bool: matches = [m for m in re_vcvars_uwp.finditer(user_argstr)] if not matches: @@ -331,7 +331,7 @@ def _msvc_script_argument_sdk(env, msvc, toolset, platform_def, arglist): return sdk_version -def _msvc_script_default_sdk(env, msvc, platform_def, arglist, force_sdk=False): +def _msvc_script_default_sdk(env, msvc, platform_def, arglist, force_sdk: bool=False): if msvc.vs_def.vc_buildtools_def.vc_version_numeric < VS2015.vc_buildtools_def.vc_version_numeric: return None @@ -390,7 +390,7 @@ def _msvc_have140_toolset(): return _toolset_have140_cache -def _reset_have140_cache(): +def _reset_have140_cache() -> None: global _toolset_have140_cache debug('reset: cache') _toolset_have140_cache = None @@ -520,7 +520,7 @@ def _msvc_read_toolset_default(msvc, vc_dir): _toolset_version_cache = {} _toolset_default_cache = {} -def _reset_toolset_cache(): +def _reset_toolset_cache() -> None: global _toolset_version_cache global _toolset_default_cache debug('reset: toolset cache') @@ -686,7 +686,7 @@ def _msvc_script_argument_toolset(env, msvc, vc_dir, arglist): return toolset_vcvars -def _msvc_script_default_toolset(env, msvc, vc_dir, arglist, force_toolset=False): +def _msvc_script_default_toolset(env, msvc, vc_dir, arglist, force_toolset: bool=False): if msvc.vs_def.vc_buildtools_def.vc_version_numeric < VS2017.vc_buildtools_def.vc_version_numeric: return None @@ -853,7 +853,7 @@ def _msvc_script_argument_user(env, msvc, arglist): return script_args -def _msvc_process_construction_variables(env): +def _msvc_process_construction_variables(env) -> bool: for cache_variable in [ _MSVC_FORCE_DEFAULT_TOOLSET, @@ -982,7 +982,7 @@ def _msvc_toolset_internal(msvc_version, toolset_version, vc_dir): return toolset_vcvars -def _msvc_toolset_versions_internal(msvc_version, vc_dir, full=True, sxs=False): +def _msvc_toolset_versions_internal(msvc_version, vc_dir, full: bool=True, sxs: bool=False): msvc = _msvc_version(msvc_version) @@ -1020,12 +1020,12 @@ def _msvc_toolset_versions_spectre_internal(msvc_version, vc_dir): return spectre_toolset_versions -def reset(): +def reset() -> None: debug('') _reset_have140_cache() _reset_toolset_cache() -def verify(): +def verify() -> None: debug('') _verify_re_sdk_dispatch_map() diff --git a/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py b/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py index 441325653..670576b04 100644 --- a/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py +++ b/SCons/Tool/MSCommon/MSVC/ScriptArgumentsTests.py @@ -147,13 +147,13 @@ class Data: ) @classmethod - def msvc_sdk_version_list_components(cls, msvc_version, msvc_uwp_app=False): + def msvc_sdk_version_list_components(cls, msvc_version, msvc_uwp_app: bool=False): comps_dict = cls.SDK_VERSIONS_COMPS_DICT.get(msvc_version, {}) comps_list = comps_dict.get(msvc_uwp_app, []) return comps_list @classmethod - def msvc_sdk_version(cls, msvc_version, msvc_uwp_app=False): + def msvc_sdk_version(cls, msvc_version, msvc_uwp_app: bool=False): comps_dict = cls.SDK_VERSIONS_COMPS_DICT.get(msvc_version, {}) comps_list = comps_dict.get(msvc_uwp_app, []) if not comps_list: @@ -163,7 +163,7 @@ class Data: return sdk_version @classmethod - def msvc_sdk_notfound_version(cls, msvc_version, msvc_uwp_app=False): + def msvc_sdk_notfound_version(cls, msvc_version, msvc_uwp_app: bool=False): notfound_dict = cls.SDK_VERSIONS_NOTFOUND_DICT.get(msvc_version, {}) notfound_list = notfound_dict.get(msvc_uwp_app, []) if not notfound_list: @@ -201,19 +201,19 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Config.MSVC_SDK_VERSIONS = cls.MSVC_SDK_VERSIONS class ScriptArgumentsTests(unittest.TestCase): - def test_verify(self): + def test_verify(self) -> None: MSVC_SDK_VERSIONS = Patch.Config.MSVC_SDK_VERSIONS.enable_copy() MSVC_SDK_VERSIONS.add('99.0') with self.assertRaises(MSVCInternalError): ScriptArguments.verify() Patch.Config.MSVC_SDK_VERSIONS.restore() - def test_msvc_script_arguments_defaults(self): + def test_msvc_script_arguments_defaults(self) -> None: func = ScriptArguments.msvc_script_arguments env = Environment() # disable forcing sdk and toolset versions as arguments @@ -244,7 +244,7 @@ class ScriptArgumentsTests(unittest.TestCase): # restore forcing sdk and toolset versions as arguments ScriptArguments.msvc_force_default_arguments(force=force) - def test_msvc_toolset_versions_internal(self): + def test_msvc_toolset_versions_internal(self) -> None: func = ScriptArguments._msvc_toolset_versions_internal for version_def, vc_dir in Data.INSTALLED_VERSIONS_PAIRS: for full in (True, False): @@ -267,7 +267,7 @@ class ScriptArgumentsTests(unittest.TestCase): func.__name__, repr(version_def.msvc_version), repr(vc_dir), repr(full), repr(sxs) )) - def test_msvc_toolset_internal(self): + def test_msvc_toolset_internal(self) -> None: if not Data.HAVE_MSVC: return func = ScriptArguments._msvc_toolset_internal @@ -278,7 +278,7 @@ class ScriptArgumentsTests(unittest.TestCase): for toolset_version in toolset_versions: _ = func(version_def.msvc_version, toolset_version, vc_dir) - def run_msvc_script_args_none(self): + def run_msvc_script_args_none(self) -> None: func = ScriptArguments.msvc_script_arguments for version_def, vc_dir in Data.INSTALLED_VERSIONS_PAIRS: for kwargs in [ @@ -291,7 +291,7 @@ class ScriptArgumentsTests(unittest.TestCase): env = Environment(**kwargs) _ = func(env, version_def.msvc_version, vc_dir, '') - def run_msvc_script_args(self): + def run_msvc_script_args(self) -> None: func = ScriptArguments.msvc_script_arguments for version_def, vc_dir in Data.INSTALLED_VERSIONS_PAIRS: if version_def.msvc_vernum >= 14.1: @@ -565,7 +565,7 @@ class ScriptArgumentsTests(unittest.TestCase): with self.assertRaises(MSVCArgumentError): _ = func(env, version_def.msvc_version, vc_dir, '') - def test_msvc_script_args_none(self): + def test_msvc_script_args_none(self) -> None: force = ScriptArguments.msvc_force_default_arguments(force=False) self.run_msvc_script_args_none() if Data.HAVE_MSVC: @@ -573,14 +573,14 @@ class ScriptArgumentsTests(unittest.TestCase): self.run_msvc_script_args_none() ScriptArguments.msvc_force_default_arguments(force=force) - def test_msvc_script_args(self): + def test_msvc_script_args(self) -> None: force = ScriptArguments.msvc_force_default_arguments(force=False) self.run_msvc_script_args() ScriptArguments.msvc_force_default_arguments(force=True) self.run_msvc_script_args() ScriptArguments.msvc_force_default_arguments(force=force) - def test_reset(self): + def test_reset(self) -> None: ScriptArguments.reset() self.assertTrue(ScriptArguments._toolset_have140_cache is None, "ScriptArguments._toolset_have140_cache was not reset") self.assertFalse(ScriptArguments._toolset_version_cache, "ScriptArguments._toolset_version_cache was not reset") diff --git a/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py b/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py index e1c05bc1b..34e60ab19 100644 --- a/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py +++ b/SCons/Tool/MSCommon/MSVC/SetupEnvDefault.py @@ -54,7 +54,7 @@ class _Data: need_init = True @classmethod - def reset(cls): + def reset(cls) -> None: debug('msvc default:init') cls.n_setup = 0 # number of calls to msvc_setup_env_once cls.default_ismsvc = False # is msvc the default compiler @@ -65,7 +65,7 @@ class _Data: cls.msvc_nodefault = False # is there a default version of msvc cls.need_init = True # reset initialization indicator -def _initialize(env, msvc_exists_func): +def _initialize(env, msvc_exists_func) -> None: if _Data.need_init: _Data.reset() _Data.need_init = False @@ -88,7 +88,7 @@ def register_tool(env, tool, msvc_exists_func): _Data.msvc_tools.add(tool) debug('msvc default:tool=%s, msvc_tools=%s', tool, _Data.msvc_tools) -def register_setup(env, msvc_exists_func): +def register_setup(env, msvc_exists_func) -> None: if _Data.need_init: _initialize(env, msvc_exists_func) _Data.n_setup += 1 @@ -106,7 +106,7 @@ def register_setup(env, msvc_exists_func): _Data.n_setup, _Data.msvc_installed, _Data.default_ismsvc ) -def set_nodefault(): +def set_nodefault() -> None: # default msvc version, msvc not installed _Data.msvc_nodefault = True debug('msvc default:msvc_nodefault=%s', _Data.msvc_nodefault) @@ -227,7 +227,7 @@ def register_iserror(env, tool, msvc_exists_func): # return tool list in order presented return tools_found_list -def reset(): +def reset() -> None: debug('') _Data.reset() diff --git a/SCons/Tool/MSCommon/MSVC/UtilTests.py b/SCons/Tool/MSCommon/MSVC/UtilTests.py index 5e14d506d..36e08f5eb 100644 --- a/SCons/Tool/MSCommon/MSVC/UtilTests.py +++ b/SCons/Tool/MSCommon/MSVC/UtilTests.py @@ -39,7 +39,7 @@ class Data: class UtilTests(unittest.TestCase): - def test_listdir_dirs(self): + def test_listdir_dirs(self) -> None: func = Util.listdir_dirs for dirname, expect in [ (None, False), ('', False), ('doesnotexist.xyz.abc', False), @@ -50,7 +50,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(dirname), 'list is empty' if expect else 'list is not empty' )) - def test_process_path(self): + def test_process_path(self) -> None: func = Util.process_path for p, expect in [ (None, True), ('', True), @@ -61,7 +61,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(p), repr(rval) )) - def test_get_version_prefix(self): + def test_get_version_prefix(self) -> None: func = Util.get_version_prefix for version, expect in [ (None, ''), ('', ''), @@ -76,7 +76,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(version), repr(prefix), repr(expect) )) - def test_get_msvc_version_prefix(self): + def test_get_msvc_version_prefix(self) -> None: func = Util.get_msvc_version_prefix for version, expect in [ (None, ''), ('', ''), @@ -91,7 +91,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(version), repr(prefix), repr(expect) )) - def test_is_toolset_full(self): + def test_is_toolset_full(self) -> None: func = Util.is_toolset_full for toolset, expect in [ (None, False), ('', False), @@ -103,7 +103,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(toolset), repr(rval) )) - def test_is_toolset_140(self): + def test_is_toolset_140(self) -> None: func = Util.is_toolset_140 for toolset, expect in [ (None, False), ('', False), @@ -115,7 +115,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(toolset), repr(rval) )) - def test_is_toolset_sxs(self): + def test_is_toolset_sxs(self) -> None: func = Util.is_toolset_sxs for toolset, expect in [ (None, False), ('', False), @@ -127,7 +127,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(toolset), repr(rval) )) - def test_msvc_version_components(self): + def test_msvc_version_components(self) -> None: func = Util.msvc_version_components for vcver, expect in [ (None, False), ('', False), ('ABC', False), ('14', False), ('14.1.', False), ('14.16', False), @@ -145,7 +145,7 @@ class UtilTests(unittest.TestCase): func.__name__, repr(vcver) )) - def test_msvc_extended_version_components(self): + def test_msvc_extended_version_components(self) -> None: func = Util.msvc_extended_version_components # normal code paths for vcver, expect in [ @@ -184,7 +184,7 @@ class UtilTests(unittest.TestCase): )) Util.re_extended_version = save_re - def test_msvc_sdk_version_components(self): + def test_msvc_sdk_version_components(self) -> None: func = Util.msvc_sdk_version_components for vcver, expect in [ (None, False), ('', False), ('ABC', False), ('14', False), ('14.1.', False), ('14.16', False), diff --git a/SCons/Tool/MSCommon/MSVC/WinSDK.py b/SCons/Tool/MSCommon/MSVC/WinSDK.py index 6d18d0730..a5a48c465 100644 --- a/SCons/Tool/MSCommon/MSVC/WinSDK.py +++ b/SCons/Tool/MSCommon/MSVC/WinSDK.py @@ -154,7 +154,7 @@ def _sdk_81_layout(version): _sdk_map_cache = {} _sdk_cache = {} -def _reset_sdk_cache(): +def _reset_sdk_cache() -> None: global _sdk_map_cache global _sdk_cache debug('') @@ -220,7 +220,7 @@ def _sdk_map(version_list): _sdk_cache[key] = sdk_map return sdk_map -def get_msvc_platform(is_uwp=False): +def get_msvc_platform(is_uwp: bool=False): platform_def = _UWP if is_uwp else _DESKTOP return platform_def @@ -230,7 +230,7 @@ def get_sdk_version_list(vs_def, platform_def): sdk_list = sdk_map.get(platform_def.vc_platform, []) return sdk_list -def get_msvc_sdk_version_list(msvc_version, msvc_uwp_app=False): +def get_msvc_sdk_version_list(msvc_version, msvc_uwp_app: bool=False): debug('msvc_version=%s, msvc_uwp_app=%s', repr(msvc_version), repr(msvc_uwp_app)) sdk_versions = [] @@ -254,11 +254,11 @@ def get_msvc_sdk_version_list(msvc_version, msvc_uwp_app=False): return sdk_versions -def reset(): +def reset() -> None: debug('') _reset_sdk_cache() -def verify(): +def verify() -> None: debug('') _verify_sdk_dispatch_map() diff --git a/SCons/Tool/MSCommon/MSVC/WinSDKTests.py b/SCons/Tool/MSCommon/MSVC/WinSDKTests.py index 2a40e9a68..10e68f3d6 100644 --- a/SCons/Tool/MSCommon/MSVC/WinSDKTests.py +++ b/SCons/Tool/MSCommon/MSVC/WinSDKTests.py @@ -47,7 +47,7 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Config.MSVC_SDK_VERSIONS = cls.MSVC_SDK_VERSIONS class Registry: @@ -69,54 +69,54 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: Registry.sdk_query_paths = cls.sdk_query_paths class WinSDKTests(unittest.TestCase): @classmethod - def setUpClass(cls): + def setUpClass(cls) -> None: Patch.Registry.sdk_query_paths.enable_duplicate() @classmethod - def tearDownClass(cls): + def tearDownClass(cls) -> None: Patch.Registry.sdk_query_paths.restore() - def test_verify(self): + def test_verify(self) -> None: MSVC_SDK_VERSIONS = Patch.Config.MSVC_SDK_VERSIONS.enable_copy() MSVC_SDK_VERSIONS.add('99.0') with self.assertRaises(MSVCInternalError): WinSDK.verify() Patch.Config.MSVC_SDK_VERSIONS.restore() - def _run_reset(self): + def _run_reset(self) -> None: WinSDK.reset() self.assertFalse(WinSDK._sdk_map_cache, "WinSDK._sdk_map_cache was not reset") self.assertFalse(WinSDK._sdk_cache, "WinSDK._sdk_cache was not reset") - def _run_get_msvc_sdk_version_list(self): + def _run_get_msvc_sdk_version_list(self) -> None: for vcver in Config.MSVC_VERSION_SUFFIX.keys(): for msvc_uwp_app in (True, False): _ = WinSDK.get_msvc_sdk_version_list(vcver, msvc_uwp_app=msvc_uwp_app) - def _run_version_list_sdk_map(self): + def _run_version_list_sdk_map(self) -> None: for vcver in Config.MSVC_VERSION_SUFFIX.keys(): vs_def = Config.MSVC_VERSION_SUFFIX.get(vcver) if not vs_def.vc_sdk_versions: continue _ = WinSDK._version_list_sdk_map(vs_def.vc_sdk_versions) - def test_version_list_sdk_map(self): + def test_version_list_sdk_map(self) -> None: self._run_version_list_sdk_map() self._run_version_list_sdk_map() self.assertTrue(WinSDK._sdk_map_cache, "WinSDK._sdk_map_cache is empty") - def test_get_msvc_sdk_version_list(self): + def test_get_msvc_sdk_version_list(self) -> None: self._run_get_msvc_sdk_version_list() self._run_get_msvc_sdk_version_list() self.assertTrue(WinSDK._sdk_cache, "WinSDK._sdk_cache is empty") - def test_get_msvc_sdk_version_list_empty(self): + def test_get_msvc_sdk_version_list_empty(self) -> None: func = WinSDK.get_msvc_sdk_version_list for vcver in [None, '', '99', '99.9']: sdk_versions = func(vcver) @@ -124,7 +124,7 @@ class WinSDKTests(unittest.TestCase): func.__name__, repr(vcver) )) - def test_reset(self): + def test_reset(self) -> None: self._run_reset() if __name__ == "__main__": diff --git a/SCons/Tool/MSCommon/MSVC/__init__.py b/SCons/Tool/MSCommon/MSVC/__init__.py index 849c82d14..766894d9b 100644 --- a/SCons/Tool/MSCommon/MSVC/__init__.py +++ b/SCons/Tool/MSCommon/MSVC/__init__.py @@ -47,9 +47,9 @@ from . import ScriptArguments # noqa: F401 from . import Dispatcher as _Dispatcher -def _reset(): +def _reset() -> None: _Dispatcher.reset() -def _verify(): +def _verify() -> None: _Dispatcher.verify() diff --git a/SCons/Tool/MSCommon/arch.py b/SCons/Tool/MSCommon/arch.py index 6648bb6b6..e52687369 100644 --- a/SCons/Tool/MSCommon/arch.py +++ b/SCons/Tool/MSCommon/arch.py @@ -30,7 +30,7 @@ class ArchDefinition: """ A class for defining architecture-specific settings and logic. """ - def __init__(self, arch, synonyms=[]): + def __init__(self, arch, synonyms=[]) -> None: self.arch = arch self.synonyms = synonyms diff --git a/SCons/Tool/MSCommon/common.py b/SCons/Tool/MSCommon/common.py index ad4c827d3..185ccdf53 100644 --- a/SCons/Tool/MSCommon/common.py +++ b/SCons/Tool/MSCommon/common.py @@ -68,7 +68,7 @@ if LOGFILE: class _Debug_Filter(logging.Filter): # custom filter for module relative filename - def filter(self, record): + def filter(self, record) -> bool: relfilename = get_relative_filename(record.pathname, modulelist) relfilename = relfilename.replace('\\', '/') record.relfilename = relfilename @@ -138,7 +138,7 @@ def read_script_env_cache(): return envcache -def write_script_env_cache(cache): +def write_script_env_cache(cache) -> None: """ write out cache of msvc env vars if requested """ if CONFIG_CACHE: try: @@ -209,7 +209,7 @@ def has_reg(value): # Functions for fetching environment variable settings from batch files. -def normalize_env(env, keys, force=False): +def normalize_env(env, keys, force: bool=False): """Given a dictionary representing a shell environment, add the variables from os.environ needed for the processing of .bat files; the keys are controlled by the keys argument. @@ -369,7 +369,7 @@ def parse_output(output, keep=KEEPLIST): for i in keep: rdk[i] = re.compile('%s=(.*)' % i, re.I) - def add_env(rmatch, key, dkeep=dkeep): + def add_env(rmatch, key, dkeep=dkeep) -> None: path_list = rmatch.group(1).split(os.pathsep) for path in path_list: # Do not add empty paths (when a var ends with ;) diff --git a/SCons/Tool/MSCommon/sdk.py b/SCons/Tool/MSCommon/sdk.py index aa94f4d65..fd0892c8f 100644 --- a/SCons/Tool/MSCommon/sdk.py +++ b/SCons/Tool/MSCommon/sdk.py @@ -59,7 +59,7 @@ class SDKDefinition: """ An abstract base class for trying to find installed SDK directories. """ - def __init__(self, version, **kw): + def __init__(self, version, **kw) -> None: self.version = version self.__dict__.update(kw) @@ -130,7 +130,7 @@ class WindowsSDK(SDKDefinition): A subclass for trying to find installed Windows SDK directories. """ HKEY_FMT = r'Software\Microsoft\Microsoft SDKs\Windows\v%s\InstallationFolder' - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: super().__init__(*args, **kw) self.hkey_data = self.version @@ -139,7 +139,7 @@ class PlatformSDK(SDKDefinition): A subclass for trying to find installed Platform SDK directories. """ HKEY_FMT = r'Software\Microsoft\MicrosoftSDK\InstalledSDKS\%s\Install Dir' - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: super().__init__(*args, **kw) self.hkey_data = self.uuid @@ -306,7 +306,7 @@ def get_installed_sdks(): SDKEnvironmentUpdates = {} -def set_sdk_by_directory(env, sdk_dir): +def set_sdk_by_directory(env, sdk_dir) -> None: global SDKEnvironmentUpdates debug('set_sdk_by_directory: Using dir:%s', sdk_dir) try: diff --git a/SCons/Tool/MSCommon/vc.py b/SCons/Tool/MSCommon/vc.py index 787194062..1dc6b8d11 100644 --- a/SCons/Tool/MSCommon/vc.py +++ b/SCons/Tool/MSCommon/vc.py @@ -455,7 +455,7 @@ def get_native_host_platform(): return _native_host_platform -def get_host_target(env, msvc_version, all_host_targets=False): +def get_host_target(env, msvc_version, all_host_targets: bool=False): vernum = float(get_msvc_version_numeric(msvc_version)) @@ -823,7 +823,7 @@ __INSTALLED_VCS_RUN = None _VC_TOOLS_VERSION_FILE_PATH = ['Auxiliary', 'Build', 'Microsoft.VCToolsVersion.default.txt'] _VC_TOOLS_VERSION_FILE = os.sep.join(_VC_TOOLS_VERSION_FILE_PATH) -def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version): +def _check_cl_exists_in_vc_dir(env, vc_dir, msvc_version) -> bool: """Return status of finding a cl.exe to use. Locates cl in the vc_dir depending on TARGET_ARCH, HOST_ARCH and the @@ -963,7 +963,7 @@ def get_installed_vcs(env=None): __INSTALLED_VCS_RUN = installed_versions return __INSTALLED_VCS_RUN -def reset_installed_vcs(): +def reset_installed_vcs() -> None: """Make it try again to find VC. This is just for the tests.""" global __INSTALLED_VCS_RUN __INSTALLED_VCS_RUN = None @@ -1099,7 +1099,7 @@ def get_default_version(env): return msvc_version -def msvc_setup_env_once(env, tool=None): +def msvc_setup_env_once(env, tool=None) -> None: try: has_run = env["MSVC_SETUP_RUN"] except KeyError: @@ -1340,7 +1340,7 @@ def msvc_setup_env_tool(env=None, version=None, tool=None): rval = True return rval -def msvc_sdk_versions(version=None, msvc_uwp_app=False): +def msvc_sdk_versions(version=None, msvc_uwp_app: bool=False): debug('version=%s, msvc_uwp_app=%s', repr(version), repr(msvc_uwp_app)) rval = [] @@ -1360,7 +1360,7 @@ def msvc_sdk_versions(version=None, msvc_uwp_app=False): rval = MSVC.WinSDK.get_msvc_sdk_version_list(version, msvc_uwp_app) return rval -def msvc_toolset_versions(msvc_version=None, full=True, sxs=False): +def msvc_toolset_versions(msvc_version=None, full: bool=True, sxs: bool=False): debug('msvc_version=%s, full=%s, sxs=%s', repr(msvc_version), repr(full), repr(sxs)) env = None @@ -1410,7 +1410,7 @@ def msvc_toolset_versions_spectre(msvc_version=None): rval = MSVC.ScriptArguments._msvc_toolset_versions_spectre_internal(msvc_version, vc_dir) return rval -def msvc_query_version_toolset(version=None, prefer_newest=True): +def msvc_query_version_toolset(version=None, prefer_newest: bool=True): """ Returns an msvc version and a toolset version given a version specification. diff --git a/SCons/Tool/MSCommon/vcTests.py b/SCons/Tool/MSCommon/vcTests.py index 3e37def2e..c4cf2af69 100644 --- a/SCons/Tool/MSCommon/vcTests.py +++ b/SCons/Tool/MSCommon/vcTests.py @@ -47,12 +47,12 @@ MS_TOOLS_VERSION = '1.1.1' class VswhereTestCase(unittest.TestCase): @staticmethod - def _createVSWhere(path): + def _createVSWhere(path) -> None: os.makedirs(os.path.dirname(path), exist_ok=True) with open(path, 'w') as f: f.write("Created:%s" % f) - def testDefaults(self): + def testDefaults(self) -> None: """ Verify that msvc_find_vswhere() find's files in the specified paths """ @@ -75,7 +75,7 @@ class VswhereTestCase(unittest.TestCase): class MSVcTestCase(unittest.TestCase): @staticmethod - def _createDummyCl(path, add_bin=True): + def _createDummyCl(path, add_bin: bool=True) -> None: """ Creates a dummy cl.exe in the correct directory. It will create all missing parent directories as well @@ -101,7 +101,7 @@ class MSVcTestCase(unittest.TestCase): ct.write('created') - def runTest(self): + def runTest(self) -> None: """ Check that all proper HOST_PLATFORM and TARGET_PLATFORM are handled. Verify that improper HOST_PLATFORM and/or TARGET_PLATFORM are properly handled. @@ -307,13 +307,13 @@ class Patch: return hook @classmethod - def restore(cls): + def restore(cls) -> None: MSCommon.vc.msvc_default_version = cls.msvc_default_version class MsvcSdkVersionsTests(unittest.TestCase): """Test msvc_sdk_versions""" - def run_valid_default_msvc(self): + def run_valid_default_msvc(self) -> None: symbol = MSCommon.vc.msvc_default_version() version_def = MSCommon.msvc_version_components(symbol) for msvc_uwp_app in (True, False): @@ -323,14 +323,14 @@ class MsvcSdkVersionsTests(unittest.TestCase): else: self.assertFalse(sdk_list, "SDK list is not empty for msvc version {}".format(repr(None))) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc() Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc() - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) for msvc_uwp_app in (True, False): @@ -340,7 +340,7 @@ class MsvcSdkVersionsTests(unittest.TestCase): else: self.assertFalse(sdk_list, "SDK list is not empty for msvc version {}".format(repr(symbol))) - def test_valid_vcver_toolsets(self): + def test_valid_vcver_toolsets(self) -> None: for symbol in MSCommon.vc._VCVER: toolset_list = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol, full=True, sxs=True) if toolset_list is None: @@ -354,13 +354,13 @@ class MsvcSdkVersionsTests(unittest.TestCase): ) self.assertTrue(sdk_list, "SDK list is empty for msvc toolset version {}".format(repr(toolset))) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['6.0Exp', '14.3Exp', '99', '14.1Bug']: for msvc_uwp_app in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_sdk_versions(version=symbol, msvc_uwp_app=msvc_uwp_app) - def test_invalid_vcver_toolsets(self): + def test_invalid_vcver_toolsets(self) -> None: for symbol in ['14.31.123456', '14.31.1.1']: for msvc_uwp_app in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): @@ -369,7 +369,7 @@ class MsvcSdkVersionsTests(unittest.TestCase): class MsvcToolsetVersionsTests(unittest.TestCase): """Test msvc_toolset_versions""" - def run_valid_default_msvc(self): + def run_valid_default_msvc(self) -> None: symbol = MSCommon.vc.msvc_default_version() version_def = MSCommon.msvc_version_components(symbol) toolset_none_list = MSCommon.vc.msvc_toolset_versions(msvc_version=None, full=False, sxs=False) @@ -386,14 +386,14 @@ class MsvcToolsetVersionsTests(unittest.TestCase): self.assertFalse(toolset_all_list, "Toolset all list is not empty for msvc version {}".format(repr(None))) self.assertFalse(toolset_none_list, "Toolset none list is not empty for msvc version {}".format(repr(None))) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc() Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc() - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) toolset_none_list = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol, full=False, sxs=False) @@ -410,14 +410,14 @@ class MsvcToolsetVersionsTests(unittest.TestCase): self.assertFalse(toolset_all_list, "Toolset all list is not empty for msvc version {}".format(repr(symbol))) self.assertFalse(toolset_none_list, "Toolset none list is not empty for msvc version {}".format(repr(symbol))) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['12.9', '6.0Exp', '14.3Exp', '99', '14.1Bug']: with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol) class MsvcToolsetVersionsSpectreTests(unittest.TestCase): - def run_valid_default_msvc(self): + def run_valid_default_msvc(self) -> None: symbol = MSCommon.vc.msvc_default_version() version_def = MSCommon.msvc_version_components(symbol) spectre_toolset_list = MSCommon.vc.msvc_toolset_versions_spectre(msvc_version=None) @@ -427,14 +427,14 @@ class MsvcToolsetVersionsSpectreTests(unittest.TestCase): else: self.assertFalse(spectre_toolset_list, "Toolset spectre list is not empty for msvc version {}".format(repr(None))) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc() Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc() - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) spectre_toolset_list = MSCommon.vc.msvc_toolset_versions_spectre(msvc_version=symbol) @@ -444,7 +444,7 @@ class MsvcToolsetVersionsSpectreTests(unittest.TestCase): else: self.assertFalse(spectre_toolset_list, "Toolset spectre list is not empty for msvc version {}".format(repr(symbol))) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['12.9', '6.0Exp', '14.3Exp', '99', '14.1Bug']: with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_toolset_versions_spectre(msvc_version=symbol) @@ -452,7 +452,7 @@ class MsvcToolsetVersionsSpectreTests(unittest.TestCase): class MsvcQueryVersionToolsetTests(unittest.TestCase): """Test msvc_query_toolset_version""" - def run_valid_default_msvc(self, have_msvc): + def run_valid_default_msvc(self, have_msvc) -> None: for prefer_newest in (True, False): msvc_version, msvc_toolset_version = MSCommon.vc.msvc_query_version_toolset( version=None, prefer_newest=prefer_newest @@ -468,14 +468,14 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): repr(None) )) - def test_valid_default_msvc(self): + def test_valid_default_msvc(self) -> None: if Data.HAVE_MSVC: Patch.MSCommon.vc.msvc_default_version.enable_none() self.run_valid_default_msvc(have_msvc=False) Patch.MSCommon.vc.msvc_default_version.restore() self.run_valid_default_msvc(have_msvc=Data.HAVE_MSVC) - def test_valid_vcver(self): + def test_valid_vcver(self) -> None: for symbol in MSCommon.vc._VCVER: version_def = MSCommon.msvc_version_components(symbol) for prefer_newest in (True, False): @@ -489,7 +489,7 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): repr(symbol) )) - def test_valid_vcver_toolsets(self): + def test_valid_vcver_toolsets(self) -> None: for symbol in MSCommon.vc._VCVER: toolset_list = MSCommon.vc.msvc_toolset_versions(msvc_version=symbol, full=True, sxs=True) if toolset_list is None: @@ -508,7 +508,7 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): repr(toolset) )) - def test_msvc_query_version_toolset_notfound(self): + def test_msvc_query_version_toolset_notfound(self) -> None: toolset_notfound_dict = Data.msvc_toolset_notfound_dict() for toolset_notfound_list in toolset_notfound_dict.values(): for toolset in toolset_notfound_list[:1]: @@ -516,13 +516,13 @@ class MsvcQueryVersionToolsetTests(unittest.TestCase): with self.assertRaises(MSCommon.vc.MSVCToolsetVersionNotFound): _ = MSCommon.vc.msvc_query_version_toolset(version=toolset, prefer_newest=prefer_newest) - def test_invalid_vcver(self): + def test_invalid_vcver(self) -> None: for symbol in ['12.9', '6.0Exp', '14.3Exp', '99', '14.1Bug']: for prefer_newest in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): _ = MSCommon.vc.msvc_query_version_toolset(version=symbol, prefer_newest=prefer_newest) - def test_invalid_vcver_toolsets(self): + def test_invalid_vcver_toolsets(self) -> None: for symbol in ['14.16.00000Exp', '14.00.00001', '14.31.123456', '14.31.1.1']: for prefer_newest in (True, False): with self.assertRaises(MSCommon.vc.MSVCArgumentError): diff --git a/SCons/Tool/MSCommon/vs.py b/SCons/Tool/MSCommon/vs.py index 08c3cf5af..00ccaef94 100644 --- a/SCons/Tool/MSCommon/vs.py +++ b/SCons/Tool/MSCommon/vs.py @@ -46,7 +46,7 @@ class VisualStudio: An abstract base class for trying to find installed versions of Visual Studio. """ - def __init__(self, version, **kw): + def __init__(self, version, **kw) -> None: self.version = version kw['vc_version'] = kw.get('vc_version', version) kw['sdk_version'] = kw.get('sdk_version', version) @@ -148,7 +148,7 @@ class VisualStudio: self._cache['supported_arch'] = self.supported_arch return self.supported_arch - def reset(self): + def reset(self) -> None: self._cache = {} # The list of supported Visual Studio versions we know how to detect. @@ -439,7 +439,7 @@ def get_installed_visual_studios(env=None): InstalledVSMap[vs.version] = vs return InstalledVSList -def reset_installed_visual_studios(): +def reset_installed_visual_studios() -> None: global InstalledVSList global InstalledVSMap InstalledVSList = None @@ -564,12 +564,12 @@ def get_default_arch(env): return arch -def merge_default_version(env): +def merge_default_version(env) -> None: version = get_default_version(env) arch = get_default_arch(env) # TODO: refers to versions and arch which aren't defined; called nowhere. Drop? -def msvs_setup_env(env): +def msvs_setup_env(env) -> None: msvs = get_vs_by_version(version) if msvs is None: return diff --git a/SCons/Tool/PharLapCommon.py b/SCons/Tool/PharLapCommon.py index 9ffafa9e5..e1907ab07 100644 --- a/SCons/Tool/PharLapCommon.py +++ b/SCons/Tool/PharLapCommon.py @@ -86,7 +86,7 @@ def getPharLapVersion(): # Default return for Phar Lap 9.1 return 910 -def addPharLapPaths(env): +def addPharLapPaths(env) -> None: """This function adds the path to the Phar Lap binaries, includes, and libraries, if they are not already there.""" ph_path = getPharLapPath() diff --git a/SCons/Tool/ToolTests.py b/SCons/Tool/ToolTests.py index 59d093b0e..e87a9725f 100644 --- a/SCons/Tool/ToolTests.py +++ b/SCons/Tool/ToolTests.py @@ -31,19 +31,19 @@ import SCons.Tool class DummyEnvironment: - def __init__(self): + def __init__(self) -> None: self.dict = {} def Detect(self, progs): if not SCons.Util.is_List(progs): progs = [ progs ] return progs[0] - def Append(self, **kw): + def Append(self, **kw) -> None: self.dict.update(kw) def __getitem__(self, key): return self.dict[key] - def __setitem__(self, key, val): + def __setitem__(self, key, val) -> None: self.dict[key] = val - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dict def subst(self, string, *args, **kwargs): return string @@ -60,13 +60,13 @@ class DummyEnvironment: if self.PHONY_PATH in paths: return os.path.join(self.PHONY_PATH, key_program) return None - def AppendENVPath(self, pathvar, path): + def AppendENVPath(self, pathvar, path) -> None: # signature matches how called from find_program_path() self['ENV'][pathvar] = self['ENV'][pathvar] + os.pathsep + path class ToolTestCase(unittest.TestCase): - def test_Tool(self): + def test_Tool(self) -> None: """Test the Tool() function""" env = DummyEnvironment() @@ -96,7 +96,7 @@ class ToolTestCase(unittest.TestCase): assert exc_caught, "did not catch expected UserError" - def test_pathfind(self): + def test_pathfind(self) -> None: """Test that find_program_path() alters PATH only if add_path is true""" env = DummyEnvironment() diff --git a/SCons/Tool/__init__.py b/SCons/Tool/__init__.py index 33c1d33ab..3681235f6 100644 --- a/SCons/Tool/__init__.py +++ b/SCons/Tool/__init__.py @@ -105,7 +105,7 @@ TOOL_ALIASES = { class Tool: - def __init__(self, name, toolpath=None, **kwargs): + def __init__(self, name, toolpath=None, **kwargs) -> None: if toolpath is None: toolpath = [] @@ -241,7 +241,7 @@ class Tool: msg = "No tool named '{self.name}': {e}" raise SCons.Errors.SConsEnvironmentError(msg) - def __call__(self, env, *args, **kw): + def __call__(self, env, *args, **kw) -> None: if self.init_kw is not None: # Merge call kws into init kws; # but don't bash self.init_kw. @@ -264,7 +264,7 @@ class Tool: self.generate(env, *args, **kw) - def __str__(self): + def __str__(self) -> str: return self.name @@ -324,7 +324,7 @@ def createStaticLibBuilder(env): return static_lib -def createSharedLibBuilder(env, shlib_suffix='$_SHLIBSUFFIX'): +def createSharedLibBuilder(env, shlib_suffix: str='$_SHLIBSUFFIX'): """This is a utility function that creates the SharedLibrary Builder in an Environment if it is not there already. @@ -354,7 +354,7 @@ def createSharedLibBuilder(env, shlib_suffix='$_SHLIBSUFFIX'): return shared_lib -def createLoadableModuleBuilder(env, loadable_module_suffix='$_LDMODULESUFFIX'): +def createLoadableModuleBuilder(env, loadable_module_suffix: str='$_LDMODULESUFFIX'): """This is a utility function that creates the LoadableModule Builder in an Environment if it is not there already. @@ -557,7 +557,7 @@ class ToolInitializerMethod: environment in place of this particular instance. """ - def __init__(self, name, initializer): + def __init__(self, name, initializer) -> None: """ Note: we store the tool name as __name__ so it can be used by the class that attaches this to a construction environment. @@ -608,7 +608,7 @@ class ToolInitializer: that we want to use to delay Tool searches until necessary. """ - def __init__(self, env, tools, names): + def __init__(self, env, tools, names) -> None: if not SCons.Util.is_List(tools): tools = [tools] if not SCons.Util.is_List(names): @@ -622,7 +622,7 @@ class ToolInitializer: self.methods[name] = method env.AddMethod(method) - def remove_methods(self, env): + def remove_methods(self, env) -> None: """ Removes the methods that were added by the tool initialization so we no longer copy and re-bind them when the construction @@ -631,7 +631,7 @@ class ToolInitializer: for method in self.methods.values(): env.RemoveMethod(method) - def apply_tools(self, env): + def apply_tools(self, env) -> None: """ Searches the list of associated Tool modules for one that exists, and applies that to the construction environment. @@ -649,7 +649,7 @@ class ToolInitializer: # the ToolInitializer class. -def Initializers(env): +def Initializers(env) -> None: ToolInitializer(env, ['install'], ['_InternalInstall', '_InternalInstallAs', '_InternalInstallVersionedLib']) def Install(self, *args, **kw): @@ -824,7 +824,7 @@ def tool_list(platform, env): return [x for x in tools if x] -def find_program_path(env, key_program, default_paths=None, add_path=False) -> Optional[str]: +def find_program_path(env, key_program, default_paths=None, add_path: bool=False) -> Optional[str]: """ Find the location of a tool using various means. diff --git a/SCons/Tool/aixcc.py b/SCons/Tool/aixcc.py index 09365b1df..ccde0a8fc 100644 --- a/SCons/Tool/aixcc.py +++ b/SCons/Tool/aixcc.py @@ -44,7 +44,7 @@ def get_xlc(env): xlc = env.get('CC', 'xlc') return SCons.Platform.aix.get_xlc(env, xlc, packages) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for xlc / Visual Age suite to an Environment.""" path, _cc, version = get_xlc(env) diff --git a/SCons/Tool/aixcxx.py b/SCons/Tool/aixcxx.py index 58d9ecca9..7b478997b 100644 --- a/SCons/Tool/aixcxx.py +++ b/SCons/Tool/aixcxx.py @@ -47,7 +47,7 @@ def get_xlc(env): xlc = env.get('CXX', 'xlC') return SCons.Platform.aix.get_xlc(env, xlc, packages) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for xlC / Visual Age suite to an Environment.""" path, _cxx, version = get_xlc(env) diff --git a/SCons/Tool/aixf77.py b/SCons/Tool/aixf77.py index 4cef908fa..33511ee9c 100644 --- a/SCons/Tool/aixf77.py +++ b/SCons/Tool/aixf77.py @@ -50,7 +50,7 @@ def get_xlf77(env): #return SCons.Platform.aix.get_xlc(env, xlf77, xlf77_r, packages) return (None, xlf77, xlf77_r, None) -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for the Visual Age FORTRAN compiler to an Environment. diff --git a/SCons/Tool/aixlink.py b/SCons/Tool/aixlink.py index dc0de2a3d..03fc3b011 100644 --- a/SCons/Tool/aixlink.py +++ b/SCons/Tool/aixlink.py @@ -48,7 +48,7 @@ def smart_linkflags(source, target, env, for_signature): return '' -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Visual Age linker to an Environment. diff --git a/SCons/Tool/applelink.py b/SCons/Tool/applelink.py index b81d2b3cd..3dc744d46 100644 --- a/SCons/Tool/applelink.py +++ b/SCons/Tool/applelink.py @@ -79,7 +79,7 @@ def _applelib_check_valid_version(version_string): return True, "" -def _applelib_currentVersionFromSoVersion(source, target, env, for_signature): +def _applelib_currentVersionFromSoVersion(source, target, env, for_signature) -> str: """ A generator function to create the -Wl,-current_version flag if needed. If env['APPLELINK_NO_CURRENT_VERSION'] contains a true value no flag will be generated @@ -110,7 +110,7 @@ def _applelib_currentVersionFromSoVersion(source, target, env, for_signature): return "-Wl,-current_version,%s" % version_string -def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): +def _applelib_compatVersionFromSoVersion(source, target, env, for_signature) -> str: """ A generator function to create the -Wl,-compatibility_version flag if needed. If env['APPLELINK_NO_COMPATIBILITY_VERSION'] contains a true value no flag will be generated @@ -141,7 +141,7 @@ def _applelib_compatVersionFromSoVersion(source, target, env, for_signature): return "-Wl,-compatibility_version,%s" % version_string -def _applelib_soname(target, source, env, for_signature): +def _applelib_soname(target, source, env, for_signature) -> str: """ Override default _soname() function from SCons.Tools.linkCommon.SharedLibrary. Apple's file naming for versioned shared libraries puts the version string before @@ -160,7 +160,7 @@ def _applelib_soname(target, source, env, for_signature): return "$SHLIBPREFIX$_get_shlib_stem$_SHLIBSOVERSION${SHLIBSUFFIX}" -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for applelink to an Environment.""" link.generate(env) diff --git a/SCons/Tool/ar.py b/SCons/Tool/ar.py index 2cd15c844..e3709273b 100644 --- a/SCons/Tool/ar.py +++ b/SCons/Tool/ar.py @@ -38,7 +38,7 @@ import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/asm.py b/SCons/Tool/asm.py index c7482513b..2c9a915c9 100644 --- a/SCons/Tool/asm.py +++ b/SCons/Tool/asm.py @@ -46,7 +46,7 @@ if SCons.Util.case_sensitive_suffixes('.s', '.S'): else: ASSuffixes.extend(['.S']) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for as to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/bcc32.py b/SCons/Tool/bcc32.py index 55f871b75..5bd14f65f 100644 --- a/SCons/Tool/bcc32.py +++ b/SCons/Tool/bcc32.py @@ -44,7 +44,7 @@ def findIt(program, env): env.PrependENVPath('PATH', dir) return borwin -def generate(env): +def generate(env) -> None: findIt('bcc32', env) """Add Builders and construction variables for bcc to an Environment.""" diff --git a/SCons/Tool/cc.py b/SCons/Tool/cc.py index 590ec5fd3..e9cbe530b 100644 --- a/SCons/Tool/cc.py +++ b/SCons/Tool/cc.py @@ -40,7 +40,7 @@ CSuffixes = ['.c', '.m'] if not SCons.Util.case_sensitive_suffixes('.c', '.C'): CSuffixes.append('.C') -def add_common_cc_variables(env): +def add_common_cc_variables(env) -> None: """ Add underlying common "C compiler" variables that are used by multiple tools (specifically, c++). @@ -64,7 +64,7 @@ def add_common_cc_variables(env): compilers = ['cc'] -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for C compilers to an Environment. """ diff --git a/SCons/Tool/clang.py b/SCons/Tool/clang.py index 518b09ed0..1cef0ad19 100644 --- a/SCons/Tool/clang.py +++ b/SCons/Tool/clang.py @@ -44,7 +44,7 @@ from SCons.Tool.MSCommon import msvc_setup_env_once compilers = ['clang'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for clang to an Environment.""" SCons.Tool.cc.generate(env) diff --git a/SCons/Tool/clangxx.py b/SCons/Tool/clangxx.py index 07d8378e3..5f8202c84 100644 --- a/SCons/Tool/clangxx.py +++ b/SCons/Tool/clangxx.py @@ -44,7 +44,7 @@ from SCons.Tool.MSCommon import msvc_setup_env_once compilers = ['clang++'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for clang++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/compilation_db.py b/SCons/Tool/compilation_db.py index a4954c1de..14c6ef59c 100644 --- a/SCons/Tool/compilation_db.py +++ b/SCons/Tool/compilation_db.py @@ -51,12 +51,12 @@ __COMPILATION_DB_ENTRIES = [] # We make no effort to avoid rebuilding the entries. Someday, perhaps we could and even # integrate with the cache, but there doesn't seem to be much call for it. class __CompilationDbNode(SCons.Node.Python.Value): - def __init__(self, value): + def __init__(self, value) -> None: SCons.Node.Python.Value.__init__(self, value) self.Decider(changed_since_last_build_node) -def changed_since_last_build_node(child, target, prev_ni, node): +def changed_since_last_build_node(child, target, prev_ni, node) -> bool: """ Dummy decider to force always building""" return True @@ -111,7 +111,7 @@ class CompDBTEMPFILE(TempFileMunge): return self.cmd -def compilation_db_entry_action(target, source, env, **kw): +def compilation_db_entry_action(target, source, env, **kw) -> None: """ Create a dictionary with evaluated command line, target, source and store that info as an attribute on the target @@ -140,7 +140,7 @@ def compilation_db_entry_action(target, source, env, **kw): target[0].write(entry) -def write_compilation_db(target, source, env): +def write_compilation_db(target, source, env) -> None: entries = [] use_abspath = env['COMPILATIONDB_USE_ABSPATH'] in [True, 1, 'True', 'true'] @@ -197,7 +197,7 @@ def compilation_db_emitter(target, source, env): return target, source -def generate(env, **kwargs): +def generate(env, **kwargs) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) env["COMPILATIONDB_COMSTR"] = kwargs.get( @@ -261,5 +261,5 @@ def generate(env, **kwargs): env['COMPILATIONDB_PATH_FILTER'] = '' -def exists(env): +def exists(env) -> bool: return True diff --git a/SCons/Tool/cvf.py b/SCons/Tool/cvf.py index 47e733ebd..0dc74ade3 100644 --- a/SCons/Tool/cvf.py +++ b/SCons/Tool/cvf.py @@ -33,7 +33,7 @@ from . import fortran compilers = ['f90'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for compaq visual fortran to an Environment.""" fortran.generate(env) diff --git a/SCons/Tool/cxx.py b/SCons/Tool/cxx.py index 128cdc4f6..bf4bcceff 100644 --- a/SCons/Tool/cxx.py +++ b/SCons/Tool/cxx.py @@ -39,7 +39,7 @@ CXXSuffixes = ['.cpp', '.cc', '.cxx', '.c++', '.C++', '.mm'] if SCons.Util.case_sensitive_suffixes('.c', '.C'): CXXSuffixes.append('.C') -def iscplusplus(source): +def iscplusplus(source) -> int: if not source: # Source might be None for unusual cases like SConf. return 0 @@ -50,7 +50,7 @@ def iscplusplus(source): return 1 return 0 -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Visual Age C++ compilers to an Environment. diff --git a/SCons/Tool/cyglink.py b/SCons/Tool/cyglink.py index bb5cd1035..0d1eb51a4 100644 --- a/SCons/Tool/cyglink.py +++ b/SCons/Tool/cyglink.py @@ -134,7 +134,7 @@ def cyglink_ldmodule_version(target, source, env, for_signature): return "." + version -def _implib_pre_flags(target, source, env, for_signature): +def _implib_pre_flags(target, source, env, for_signature) -> str: no_import_lib = env.get('no_import_lib', False) if no_import_lib in ['1', 'True', 'true', True]: return '' @@ -142,7 +142,7 @@ def _implib_pre_flags(target, source, env, for_signature): return '-Wl,--out-implib=${TARGETS[1]} -Wl,--export-all-symbols -Wl,--enable-auto-import -Wl,--whole-archive' -def _implib_post_flags(target, source, env, for_signature): +def _implib_post_flags(target, source, env, for_signature) -> str: no_import_lib = env.get('no_import_lib', False) if no_import_lib in ['1', 'True', 'true', True]: return '' @@ -150,7 +150,7 @@ def _implib_post_flags(target, source, env, for_signature): return '-Wl,--no-whole-archive' -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for cyglink to an Environment.""" gnulink.generate(env) diff --git a/SCons/Tool/default.py b/SCons/Tool/default.py index a36e9ec1c..4b386e2e1 100644 --- a/SCons/Tool/default.py +++ b/SCons/Tool/default.py @@ -35,12 +35,12 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Tool -def generate(env): +def generate(env) -> None: """Add default tools.""" for t in SCons.Tool.tool_list(env['PLATFORM'], env): SCons.Tool.Tool(t)(env) -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/dmd.py b/SCons/Tool/dmd.py index 67ed43eda..7b2a24962 100644 --- a/SCons/Tool/dmd.py +++ b/SCons/Tool/dmd.py @@ -82,7 +82,7 @@ import SCons.Tool import SCons.Tool.DCommon as DCommon -def generate(env): +def generate(env) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.add_action('.d', SCons.Defaults.DAction) diff --git a/SCons/Tool/docbook/__init__.py b/SCons/Tool/docbook/__init__.py index 52e291144..53505eb7c 100644 --- a/SCons/Tool/docbook/__init__.py +++ b/SCons/Tool/docbook/__init__.py @@ -72,7 +72,7 @@ re_refname = re.compile(r"([^<]*)") lmxl_xslt_global_max_depth = 3600 if has_lxml and lmxl_xslt_global_max_depth: - def __lxml_xslt_set_global_max_depth(max_depth): + def __lxml_xslt_set_global_max_depth(max_depth) -> None: from lxml import etree etree.XSLT.set_global_max_depth(max_depth) __lxml_xslt_set_global_max_depth(lmxl_xslt_global_max_depth) @@ -93,7 +93,7 @@ def __extend_targets_sources(target, source): return target, source -def __init_xsl_stylesheet(kw, env, user_xsl_var, default_path): +def __init_xsl_stylesheet(kw, env, user_xsl_var, default_path) -> None: if kw.get('DOCBOOK_XSL','') == '': xsl_style = kw.get('xsl', env.subst(user_xsl_var)) if xsl_style == '': @@ -137,7 +137,7 @@ def __get_xml_text(root): txt += e.data return txt -def __create_output_dir(base_dir): +def __create_output_dir(base_dir) -> None: """ Ensure that the output directory base_dir exists. """ root, tail = os.path.split(base_dir) dir = None @@ -173,7 +173,7 @@ fop_com = {'fop' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -fo $SOURCE -pdf $TARGET', 'xep' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -valid -fo $SOURCE -pdf $TARGET', 'jw' : '$DOCBOOK_FOP $DOCBOOK_FOPFLAGS -f docbook -b pdf $SOURCE -o $TARGET'} -def __detect_cl_tool(env, chainkey, cdict, cpriority=None): +def __detect_cl_tool(env, chainkey, cdict, cpriority=None) -> None: """ Helper function, picks a command line tool from the list and initializes its environment variables. @@ -195,7 +195,7 @@ def __detect_cl_tool(env, chainkey, cdict, cpriority=None): env[chainkey + 'COM'] = cdict[cltool] break -def _detect(env): +def _detect(env) -> None: """ Detect all the command line tools that we might need for creating the requested output formats. @@ -420,7 +420,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): import zipfile import shutil - def build_open_container(target, source, env): + def build_open_container(target, source, env) -> None: """Generate the *.epub file from intermediate outputs Constructs the epub file according to the Open Container Format. This @@ -444,7 +444,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): zf.write(path, os.path.relpath(path, str(env.get('ZIPROOT', ''))), zipfile.ZIP_DEFLATED) - def add_resources(target, source, env): + def add_resources(target, source, env) -> None: """Add missing resources to the OEBPS directory Ensure all the resources in the manifest are present in the OEBPS directory. @@ -789,7 +789,7 @@ def DocbookXslt(env, target, source=None, *args, **kw): return result -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for docbook to an Environment.""" env.SetDefault( @@ -839,5 +839,5 @@ def generate(env): env.AddMethod(DocbookXslt, "DocbookXslt") -def exists(env): +def exists(env) -> int: return 1 diff --git a/SCons/Tool/dvi.py b/SCons/Tool/dvi.py index 4067b2a1e..a395d2b39 100644 --- a/SCons/Tool/dvi.py +++ b/SCons/Tool/dvi.py @@ -34,7 +34,7 @@ import SCons.Tool DVIBuilder = None -def generate(env): +def generate(env) -> None: try: env['BUILDERS']['DVI'] except KeyError: @@ -52,7 +52,7 @@ def generate(env): env['BUILDERS']['DVI'] = DVIBuilder -def exists(env): +def exists(env) -> int: # This only puts a skeleton Builder in place, so if someone # references this Tool directly, it's always "available." return 1 diff --git a/SCons/Tool/dvipdf.py b/SCons/Tool/dvipdf.py index e0622072d..c08bf07f6 100644 --- a/SCons/Tool/dvipdf.py +++ b/SCons/Tool/dvipdf.py @@ -85,12 +85,12 @@ def PDFEmitter(target, source, env): used to generate the .dvi file we're using as input, and we only care about the .dvi file. """ - def strip_suffixes(n): + def strip_suffixes(n) -> bool: return not SCons.Util.splitext(str(n))[1] in ['.aux', '.log'] source = [src for src in source if strip_suffixes(src)] return (target, source) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for dvipdf to an Environment.""" global PDFAction if PDFAction is None: diff --git a/SCons/Tool/dvips.py b/SCons/Tool/dvips.py index 198bda038..7cf717b8d 100644 --- a/SCons/Tool/dvips.py +++ b/SCons/Tool/dvips.py @@ -55,7 +55,7 @@ PSAction = None DVIPSAction = None PSBuilder = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for dvips to an Environment.""" global PSAction if PSAction is None: diff --git a/SCons/Tool/f03.py b/SCons/Tool/f03.py index 142c1278b..7c2f029a5 100644 --- a/SCons/Tool/f03.py +++ b/SCons/Tool/f03.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f03_to_env compilers = ['f03'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f03_to_env(env) diff --git a/SCons/Tool/f08.py b/SCons/Tool/f08.py index eb367c53e..30c2d72bd 100644 --- a/SCons/Tool/f08.py +++ b/SCons/Tool/f08.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f08_to_env compilers = ['f08'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f08_to_env(env) diff --git a/SCons/Tool/f77.py b/SCons/Tool/f77.py index 5ff15ae45..c065f6cd2 100644 --- a/SCons/Tool/f77.py +++ b/SCons/Tool/f77.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env compilers = ['f77'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f77_to_env(env) diff --git a/SCons/Tool/f90.py b/SCons/Tool/f90.py index cbf3947c1..b3dde59b8 100644 --- a/SCons/Tool/f90.py +++ b/SCons/Tool/f90.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f90_to_env compilers = ['f90'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f90_to_env(env) diff --git a/SCons/Tool/f95.py b/SCons/Tool/f95.py index 4830ee03f..b707a115f 100644 --- a/SCons/Tool/f95.py +++ b/SCons/Tool/f95.py @@ -32,7 +32,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f95_to_env compilers = ['f95'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_f95_to_env(env) diff --git a/SCons/Tool/filesystem.py b/SCons/Tool/filesystem.py index 3b8ee4c8f..9a977b5d7 100644 --- a/SCons/Tool/filesystem.py +++ b/SCons/Tool/filesystem.py @@ -48,7 +48,7 @@ def copyto_emitter(target, source, env): return (n_target, source) -def copy_action_func(target, source, env): +def copy_action_func(target, source, env) -> int: assert( len(target) == len(source) ), "\ntarget: %s\nsource: %s" %(list(map(str, target)),list(map(str, source))) for t, s in zip(target, source): @@ -62,7 +62,7 @@ def copy_action_str(target, source, env): copy_action = SCons.Action.Action( copy_action_func, copy_action_str ) -def generate(env): +def generate(env) -> None: try: env['BUILDERS']['CopyTo'] env['BUILDERS']['CopyAs'] @@ -88,7 +88,7 @@ def generate(env): env['COPYSTR'] = 'Copy file(s): "$SOURCES" to "$TARGETS"' -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/fortran.py b/SCons/Tool/fortran.py index d21b93087..4463085f7 100644 --- a/SCons/Tool/fortran.py +++ b/SCons/Tool/fortran.py @@ -33,7 +33,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_fortran_to_env compilers = ['f95', 'f90', 'f77'] -def generate(env): +def generate(env) -> None: add_all_to_env(env) add_fortran_to_env(env) diff --git a/SCons/Tool/g77.py b/SCons/Tool/g77.py index aea419a2f..8c69d8532 100644 --- a/SCons/Tool/g77.py +++ b/SCons/Tool/g77.py @@ -35,7 +35,7 @@ from SCons.Tool.FortranCommon import add_all_to_env, add_f77_to_env compilers = ['g77', 'f77'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for g77 to an Environment.""" add_all_to_env(env) add_f77_to_env(env) diff --git a/SCons/Tool/gas.py b/SCons/Tool/gas.py index d01bd60cc..04c9a2ed8 100644 --- a/SCons/Tool/gas.py +++ b/SCons/Tool/gas.py @@ -40,7 +40,7 @@ except: assemblers = ['as', 'gas'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for as to an Environment.""" as_module.generate(env) diff --git a/SCons/Tool/gcc.py b/SCons/Tool/gcc.py index 1a25cb44d..d564f9cb2 100644 --- a/SCons/Tool/gcc.py +++ b/SCons/Tool/gcc.py @@ -40,7 +40,7 @@ import SCons.Util compilers = ['gcc', 'cc'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gcc to an Environment.""" if 'CC' not in env: diff --git a/SCons/Tool/gdc.py b/SCons/Tool/gdc.py index 0728c6fec..c77e27a05 100644 --- a/SCons/Tool/gdc.py +++ b/SCons/Tool/gdc.py @@ -54,7 +54,7 @@ import SCons.Tool.DCommon as DCommon import SCons.Tool.linkCommon -def generate(env): +def generate(env) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.add_action('.d', SCons.Defaults.DAction) diff --git a/SCons/Tool/gettext_tool.py b/SCons/Tool/gettext_tool.py index a1407b362..18c7c0eef 100644 --- a/SCons/Tool/gettext_tool.py +++ b/SCons/Tool/gettext_tool.py @@ -40,7 +40,7 @@ from SCons.Tool.GettextCommon import ( _xgettext_exists, ) -def generate(env, **kw): +def generate(env, **kw) -> None: for t in tool_list(env['PLATFORM'], env): if sys.platform == 'win32': tool = SCons.Tool.find_program_path( diff --git a/SCons/Tool/gfortran.py b/SCons/Tool/gfortran.py index f9c0a4535..cb55ad602 100644 --- a/SCons/Tool/gfortran.py +++ b/SCons/Tool/gfortran.py @@ -34,7 +34,7 @@ from SCons.Util import CLVar from . import fortran -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gfortran.""" fortran.generate(env) diff --git a/SCons/Tool/gnulink.py b/SCons/Tool/gnulink.py index e8b668fa3..159aa972c 100644 --- a/SCons/Tool/gnulink.py +++ b/SCons/Tool/gnulink.py @@ -39,7 +39,7 @@ import SCons.Tool from . import link -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gnulink to an Environment.""" link.generate(env) diff --git a/SCons/Tool/gs.py b/SCons/Tool/gs.py index 25359a858..8955bfd58 100644 --- a/SCons/Tool/gs.py +++ b/SCons/Tool/gs.py @@ -50,7 +50,7 @@ else: GhostscriptAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Ghostscript to an Environment.""" global GhostscriptAction diff --git a/SCons/Tool/gxx.py b/SCons/Tool/gxx.py index 1272997be..e788381b7 100644 --- a/SCons/Tool/gxx.py +++ b/SCons/Tool/gxx.py @@ -41,7 +41,7 @@ from . import cxx compilers = ['g++'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for g++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/hpcc.py b/SCons/Tool/hpcc.py index 51d2e3802..f893686a8 100644 --- a/SCons/Tool/hpcc.py +++ b/SCons/Tool/hpcc.py @@ -36,7 +36,7 @@ import SCons.Util from . import cc -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for aCC & cc to an Environment.""" cc.generate(env) diff --git a/SCons/Tool/hpcxx.py b/SCons/Tool/hpcxx.py index 7113fa222..c02a06f72 100644 --- a/SCons/Tool/hpcxx.py +++ b/SCons/Tool/hpcxx.py @@ -60,7 +60,7 @@ for dir in dirs: break -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for g++ to an Environment.""" cplusplus.generate(env) diff --git a/SCons/Tool/hplink.py b/SCons/Tool/hplink.py index ba182f1d3..0d26fa4a2 100644 --- a/SCons/Tool/hplink.py +++ b/SCons/Tool/hplink.py @@ -51,7 +51,7 @@ for dir in dirs: ccLinker = linker break -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Visual Age linker to an Environment. diff --git a/SCons/Tool/icc.py b/SCons/Tool/icc.py index adf24e9ab..63c7fd0ff 100644 --- a/SCons/Tool/icc.py +++ b/SCons/Tool/icc.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" from . import cc -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for the OS/2 to an Environment.""" cc.generate(env) diff --git a/SCons/Tool/ifl.py b/SCons/Tool/ifl.py index 574695072..dac8179fa 100644 --- a/SCons/Tool/ifl.py +++ b/SCons/Tool/ifl.py @@ -32,7 +32,7 @@ import SCons.Defaults from SCons.Scanner.Fortran import FortranScan from .FortranCommon import add_all_to_env -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ifl to an Environment.""" fscan = FortranScan("FORTRANPATH") SCons.Tool.SourceFileScanner.add_scanner('.i', fscan) diff --git a/SCons/Tool/ifort.py b/SCons/Tool/ifort.py index bf39b7f49..92109234d 100644 --- a/SCons/Tool/ifort.py +++ b/SCons/Tool/ifort.py @@ -35,7 +35,7 @@ from SCons.Scanner.Fortran import FortranScan from .FortranCommon import add_all_to_env -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ifort to an Environment.""" # ifort supports Fortran 90 and Fortran 95 # Additionally, ifort recognizes more file extensions. diff --git a/SCons/Tool/ilink.py b/SCons/Tool/ilink.py index 4112825b8..6be62d3c7 100644 --- a/SCons/Tool/ilink.py +++ b/SCons/Tool/ilink.py @@ -33,7 +33,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ilink to an Environment.""" SCons.Tool.createProgBuilder(env) diff --git a/SCons/Tool/ilink32.py b/SCons/Tool/ilink32.py index 1452fd555..1bdc6d0a6 100644 --- a/SCons/Tool/ilink32.py +++ b/SCons/Tool/ilink32.py @@ -33,7 +33,7 @@ import SCons.Tool import SCons.Tool.bcc32 import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Borland ilink to an Environment.""" SCons.Tool.createSharedLibBuilder(env) diff --git a/SCons/Tool/install.py b/SCons/Tool/install.py index d6870c398..54fc09036 100644 --- a/SCons/Tool/install.py +++ b/SCons/Tool/install.py @@ -50,8 +50,8 @@ class CopytreeError(OSError): pass -def scons_copytree(src, dst, symlinks=False, ignore=None, copy_function=copy2, - ignore_dangling_symlinks=False, dirs_exist_ok=False): +def scons_copytree(src, dst, symlinks: bool=False, ignore=None, copy_function=copy2, + ignore_dangling_symlinks: bool=False, dirs_exist_ok: bool=False): """Recursively copy a directory tree, SCons version. This is a modified copy of the Python 3.7 shutil.copytree function. @@ -225,7 +225,7 @@ def listShlibLinksToInstall(dest, source, env): install_links.append((install_link, install_linktgt)) return install_links -def installShlibLinks(dest, source, env): +def installShlibLinks(dest, source, env) -> None: """If we are installing a versioned shared library create the required links.""" Verbose = False symlinks = listShlibLinksToInstall(dest, source, env) @@ -337,7 +337,7 @@ class DESTDIR_factory: """ A node factory, where all files will be relative to the dir supplied in the constructor. """ - def __init__(self, env, dir): + def __init__(self, env, dir) -> None: self.env = env self.dir = env.arg2nodes( dir, env.fs.Dir )[0] @@ -429,7 +429,7 @@ def InstallVersionedBuilderWrapper(env, target=None, source=None, dir=None, **kw added = None -def generate(env): +def generate(env) -> None: from SCons.Script import AddOption, GetOption global added @@ -500,7 +500,7 @@ def generate(env): except KeyError: env['INSTALLVERSIONEDLIB'] = copyFuncVersionedLib -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/intelc.py b/SCons/Tool/intelc.py index ac6fa6077..a7b480242 100644 --- a/SCons/Tool/intelc.py +++ b/SCons/Tool/intelc.py @@ -384,7 +384,7 @@ def get_intel_compiler_top(version, abi): return top -def generate(env, version=None, abi=None, topdir=None, verbose=0): +def generate(env, version=None, abi=None, topdir=None, verbose: int=0): r"""Add Builders and construction variables for Intel C/C++ compiler to an Environment. diff --git a/SCons/Tool/ipkg.py b/SCons/Tool/ipkg.py index 8e01dd26d..b295c121e 100644 --- a/SCons/Tool/ipkg.py +++ b/SCons/Tool/ipkg.py @@ -39,7 +39,7 @@ import os import SCons.Builder -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ipkg to an Environment.""" try: bld = env['BUILDERS']['Ipkg'] diff --git a/SCons/Tool/jar.py b/SCons/Tool/jar.py index ae44ff3bd..1967294f0 100644 --- a/SCons/Tool/jar.py +++ b/SCons/Tool/jar.py @@ -240,7 +240,7 @@ def generate(env) -> None: env['JARCOM'] = "${TEMPFILE('$_JARCOM','$JARCOMSTR')}" env['JARSUFFIX'] = '.jar' -def exists(env): +def exists(env) -> bool: # As reported by Jan Nijtmans in issue #2730, the simple # return env.Detect('jar') # doesn't always work during initialization. For now, we diff --git a/SCons/Tool/javac.py b/SCons/Tool/javac.py index 1b331253b..635392459 100644 --- a/SCons/Tool/javac.py +++ b/SCons/Tool/javac.py @@ -73,7 +73,7 @@ def emit_java_classes(target, source, env): elif isinstance(entry, SCons.Node.FS.Dir): result = OrderedDict() dirnode = entry.rdir() - def find_java_files(arg, dirpath, filenames): + def find_java_files(arg, dirpath, filenames) -> None: java_files = sorted([n for n in filenames if _my_normcase(n).endswith(js)]) mydir = dirnode.Dir(dirpath) @@ -141,7 +141,7 @@ class pathopt: Callable object for generating javac-style path options from a construction variable (e.g. -classpath, -sourcepath). """ - def __init__(self, opt, var, default=None): + def __init__(self, opt, var, default=None) -> None: self.opt = opt self.var = var self.default = default @@ -198,7 +198,7 @@ def Java(env, target, source, *args, **kw): return result -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for javac to an Environment.""" java_file = SCons.Tool.CreateJavaFileBuilder(env) java_class = SCons.Tool.CreateJavaClassFileBuilder(env) @@ -242,7 +242,7 @@ def generate(env): env['_JAVACCOM'] = '$JAVAC $JAVACFLAGS $_JAVABOOTCLASSPATH $_JAVAPROCESSORPATH $_JAVACLASSPATH -d ${TARGET.attributes.java_classdir} $_JAVASOURCEPATH $SOURCES' env['JAVACCOM'] = "${TEMPFILE('$_JAVACCOM','$JAVACCOMSTR')}" -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/javacTests.py b/SCons/Tool/javacTests.py index 08633d5e4..46f1af120 100644 --- a/SCons/Tool/javacTests.py +++ b/SCons/Tool/javacTests.py @@ -27,39 +27,39 @@ import unittest import SCons.Tool.javac class DummyNode: - def __init__(self, val): + def __init__(self, val) -> None: self.val = val - def __str__(self): + def __str__(self) -> str: return str(self.val) class pathoptTestCase(unittest.TestCase): - def assert_pathopt(self, expect, path): + def assert_pathopt(self, expect, path) -> None: popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH') env = {'FOOPATH': path} actual = popt(None, None, env, None) self.assertEqual(expect, actual) - def assert_pathopt_default(self, expect, path, default): + def assert_pathopt_default(self, expect, path, default) -> None: popt = SCons.Tool.javac.pathopt('-foopath', 'FOOPATH', default='DPATH') env = {'FOOPATH': path, 'DPATH': default} actual = popt(None, None, env, None) self.assertEqual(expect, actual) - def test_unset(self): + def test_unset(self) -> None: self.assert_pathopt([], None) self.assert_pathopt([], '') - def test_str(self): + def test_str(self) -> None: self.assert_pathopt(['-foopath', '/foo/bar'], '/foo/bar') - def test_list_str(self): + def test_list_str(self) -> None: self.assert_pathopt(['-foopath', '/foo%s/bar' % os.pathsep], ['/foo', '/bar']) - def test_uses_pathsep(self): + def test_uses_pathsep(self) -> None: save = os.pathsep try: os.pathsep = '!' @@ -68,27 +68,27 @@ class pathoptTestCase(unittest.TestCase): finally: os.pathsep = save - def test_node(self): + def test_node(self) -> None: self.assert_pathopt(['-foopath', '/foo'], DummyNode('/foo')) - def test_list_node(self): + def test_list_node(self) -> None: self.assert_pathopt(['-foopath', os.pathsep.join(['/foo','/bar'])], ['/foo', DummyNode('/bar')]) - def test_default_str(self): + def test_default_str(self) -> None: self.assert_pathopt_default( ['-foopath', os.pathsep.join(['/foo','/bar','/baz'])], ['/foo', '/bar'], '/baz') - def test_default_list(self): + def test_default_list(self) -> None: self.assert_pathopt_default( ['-foopath', os.pathsep.join(['/foo','/bar','/baz'])], ['/foo', '/bar'], ['/baz']) - def test_default_unset(self): + def test_default_unset(self) -> None: self.assert_pathopt_default( ['-foopath', '/foo'], '/foo', @@ -98,7 +98,7 @@ class pathoptTestCase(unittest.TestCase): '/foo', '') - def test_list_within_list(self): + def test_list_within_list(self) -> None: self.assert_pathopt(['-foopath', os.pathsep.join(['/foo','/bar'])], ['/foo', ['/bar']]) diff --git a/SCons/Tool/javah.py b/SCons/Tool/javah.py index c5a75646e..4b688152e 100644 --- a/SCons/Tool/javah.py +++ b/SCons/Tool/javah.py @@ -109,13 +109,13 @@ def JavaHOutFlagGenerator(target, source, env, for_signature): except AttributeError: return '-o ' + str(t) -def getJavaHClassPath(env,target, source, for_signature): +def getJavaHClassPath(env,target, source, for_signature) -> str: path = "${SOURCE.attributes.java_classdir}" if 'JAVACLASSPATH' in env and env['JAVACLASSPATH']: path = SCons.Util.AppendPath(path, env['JAVACLASSPATH']) return "-classpath %s" % path -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for javah to an Environment.""" java_javah = SCons.Tool.CreateJavaHBuilder(env) java_javah.emitter = emit_java_headers diff --git a/SCons/Tool/latex.py b/SCons/Tool/latex.py index f30356b23..ddbcdf998 100644 --- a/SCons/Tool/latex.py +++ b/SCons/Tool/latex.py @@ -50,7 +50,7 @@ def LaTeXAuxFunction(target = None, source= None, env=None): LaTeXAuxAction = SCons.Action.Action(LaTeXAuxFunction, strfunction=SCons.Tool.tex.TeXLaTeXStrFunction) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for LaTeX to an Environment.""" env.AppendUnique(LATEXSUFFIXES=SCons.Tool.LaTeXSuffixes) diff --git a/SCons/Tool/ldc.py b/SCons/Tool/ldc.py index fa02bf873..758385368 100644 --- a/SCons/Tool/ldc.py +++ b/SCons/Tool/ldc.py @@ -58,7 +58,7 @@ import SCons.Tool import SCons.Tool.DCommon as DCommon -def generate(env): +def generate(env) -> None: static_obj, shared_obj = SCons.Tool.createObjBuilders(env) static_obj.add_action('.d', SCons.Defaults.DAction) diff --git a/SCons/Tool/lex.py b/SCons/Tool/lex.py index 3f1a3ade1..527f91c29 100644 --- a/SCons/Tool/lex.py +++ b/SCons/Tool/lex.py @@ -95,7 +95,7 @@ def lexEmitter(target, source, env) -> tuple: return target, source -def get_lex_path(env, append_paths=False) -> Optional[str]: +def get_lex_path(env, append_paths: bool=False) -> Optional[str]: """ Returns the path to the lex tool, searching several possible names. diff --git a/SCons/Tool/link.py b/SCons/Tool/link.py index 24d17a31f..e879ae862 100644 --- a/SCons/Tool/link.py +++ b/SCons/Tool/link.py @@ -40,7 +40,7 @@ from SCons.Tool.linkCommon.LoadableModule import setup_loadable_module_logic from SCons.Tool.linkCommon.SharedLibrary import setup_shared_lib_logic -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gnulink to an Environment.""" createProgBuilder(env) diff --git a/SCons/Tool/linkCommon/LoadableModule.py b/SCons/Tool/linkCommon/LoadableModule.py index c8124a088..77a06eddd 100644 --- a/SCons/Tool/linkCommon/LoadableModule.py +++ b/SCons/Tool/linkCommon/LoadableModule.py @@ -65,7 +65,7 @@ def _ldmodule_soversion(target, source, env, for_signature): return '' -def _ldmodule_soname(target, source, env, for_signature): +def _ldmodule_soname(target, source, env, for_signature) -> str: if 'SONAME' in env: return '$SONAME' else: @@ -82,7 +82,7 @@ def _LDMODULEVERSION(target, source, env, for_signature): else: return "" -def setup_loadable_module_logic(env): +def setup_loadable_module_logic(env) -> None: """ Just the logic for loadable modules diff --git a/SCons/Tool/linkCommon/SharedLibrary.py b/SCons/Tool/linkCommon/SharedLibrary.py index d18aa6b4b..30170f8bb 100644 --- a/SCons/Tool/linkCommon/SharedLibrary.py +++ b/SCons/Tool/linkCommon/SharedLibrary.py @@ -100,7 +100,7 @@ def _soversion(target, source, env, for_signature): return "" -def _soname(target, source, env, for_signature): +def _soname(target, source, env, for_signature) -> str: if "SONAME" in env: # Now verify that SOVERSION is not also set as that is not allowed if "SOVERSION" in env: @@ -177,7 +177,7 @@ def _get_shlib_dir(target, source, env, for_signature: bool) -> str: return "" -def setup_shared_lib_logic(env): +def setup_shared_lib_logic(env) -> None: """Initialize an environment for shared library building. Args: diff --git a/SCons/Tool/linkCommon/__init__.py b/SCons/Tool/linkCommon/__init__.py index 5461ad3db..b8d7610c4 100644 --- a/SCons/Tool/linkCommon/__init__.py +++ b/SCons/Tool/linkCommon/__init__.py @@ -45,7 +45,7 @@ def StringizeLibSymlinks(symlinks): return symlinks -def EmitLibSymlinks(env, symlinks, libnode, **kw): +def EmitLibSymlinks(env, symlinks, libnode, **kw) -> None: """Used by emitters to handle (shared/versioned) library symlinks""" Verbose = False @@ -66,7 +66,7 @@ def EmitLibSymlinks(env, symlinks, libnode, **kw): print("EmitLibSymlinks: Clean(%r,%r)" % (linktgt.get_path(), [x.get_path() for x in clean_list])) -def CreateLibSymlinks(env, symlinks): +def CreateLibSymlinks(env, symlinks) -> int: """Physically creates symlinks. The symlinks argument must be a list in form [ (link, linktarget), ... ], where link and linktarget are SCons nodes. @@ -92,7 +92,7 @@ def CreateLibSymlinks(env, symlinks): return 0 -def LibSymlinksActionFunction(target, source, env): +def LibSymlinksActionFunction(target, source, env) -> int: for tgt in target: symlinks = getattr(getattr(tgt, 'attributes', None), 'shliblinks', None) if symlinks: @@ -127,7 +127,7 @@ def _call_env_subst(env, string, *args, **kw): return env.subst(string, *args, **kw2) -def smart_link(source, target, env, for_signature): +def smart_link(source, target, env, for_signature) -> str: import SCons.Tool.cxx import SCons.Tool.FortranCommon diff --git a/SCons/Tool/linkCommon/linkCommmonTests.py b/SCons/Tool/linkCommon/linkCommmonTests.py index e55660d77..5326da214 100644 --- a/SCons/Tool/linkCommon/linkCommmonTests.py +++ b/SCons/Tool/linkCommon/linkCommmonTests.py @@ -31,10 +31,10 @@ from SCons.Environment import Environment class SharedLibraryTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: pass - def test_shlib_symlink_emitter(self): + def test_shlib_symlink_emitter(self) -> None: """Test shlib_symlink_emitter() """ env = Environment(tools=['gnulink']) diff --git a/SCons/Tool/linkloc.py b/SCons/Tool/linkloc.py index 6ee5d6192..6122d9be0 100644 --- a/SCons/Tool/linkloc.py +++ b/SCons/Tool/linkloc.py @@ -61,7 +61,7 @@ def repl_linker_command(m): return m.group(1) + '#' + m.group(2) class LinklocGenerator: - def __init__(self, cmdline): + def __init__(self, cmdline) -> None: self.cmdline = cmdline def __call__(self, env, target, source, for_signature): @@ -75,7 +75,7 @@ class LinklocGenerator: else: return "${TEMPFILE('" + self.cmdline + "')}" -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createSharedLibBuilder(env) SCons.Tool.createProgBuilder(env) diff --git a/SCons/Tool/m4.py b/SCons/Tool/m4.py index 8506784de..341d93dfa 100644 --- a/SCons/Tool/m4.py +++ b/SCons/Tool/m4.py @@ -37,7 +37,7 @@ import SCons.Action import SCons.Builder import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for m4 to an Environment.""" M4Action = SCons.Action.Action('$M4COM', '$M4COMSTR') bld = SCons.Builder.Builder(action = M4Action, src_suffix = '.m4') diff --git a/SCons/Tool/masm.py b/SCons/Tool/masm.py index b9d88cd19..f8fae2019 100644 --- a/SCons/Tool/masm.py +++ b/SCons/Tool/masm.py @@ -44,7 +44,7 @@ if SCons.Util.case_sensitive_suffixes('.s', '.S'): else: ASSuffixes.extend(['.S']) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for masm to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/midl.py b/SCons/Tool/midl.py index c25ce69ad..0c640f509 100644 --- a/SCons/Tool/midl.py +++ b/SCons/Tool/midl.py @@ -73,7 +73,7 @@ midl_builder = SCons.Builder.Builder(action=midl_action, source_scanner=idl_scanner) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for midl to an Environment.""" env['MIDL'] = 'MIDL.EXE' diff --git a/SCons/Tool/mingw.py b/SCons/Tool/mingw.py index 8e7ac2df9..07f15b74c 100644 --- a/SCons/Tool/mingw.py +++ b/SCons/Tool/mingw.py @@ -142,7 +142,7 @@ def get_mingw_paths(): _mingw_all_paths = mingw_base_paths + find_version_specific_mingw_paths() return _mingw_all_paths -def generate(env): +def generate(env) -> None: # Check for reasoanble mingw default paths mingw_paths = get_mingw_paths() diff --git a/SCons/Tool/msgfmt.py b/SCons/Tool/msgfmt.py index a15c1dcc0..334e0580e 100644 --- a/SCons/Tool/msgfmt.py +++ b/SCons/Tool/msgfmt.py @@ -86,7 +86,7 @@ def _create_mo_file_builder(env, **kw): return _MOFileBuilder(**kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate `msgfmt` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/msginit.py b/SCons/Tool/msginit.py index 9635f5710..19aaccb4e 100644 --- a/SCons/Tool/msginit.py +++ b/SCons/Tool/msginit.py @@ -79,7 +79,7 @@ def _POInitBuilderWrapper(env, target=None, source=_null, **kw): source = [domain] # NOTE: Suffix shall be appended automatically return env._POInitBuilder(target, source, **kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate the `msginit` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/msgmerge.py b/SCons/Tool/msgmerge.py index 69508ebbf..292e75d6d 100644 --- a/SCons/Tool/msgmerge.py +++ b/SCons/Tool/msgmerge.py @@ -77,7 +77,7 @@ def _POUpdateBuilderWrapper(env, target=None, source=_null, **kw): return env._POUpdateBuilder(target, source, **kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate the `msgmerge` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/mslib.py b/SCons/Tool/mslib.py index be4088b15..6e15a808f 100644 --- a/SCons/Tool/mslib.py +++ b/SCons/Tool/mslib.py @@ -45,7 +45,7 @@ from .MSCommon import msvc_setup_env_tool, msvc_setup_env_once tool_name = 'mslib' -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for lib to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/mslink.py b/SCons/Tool/mslink.py index 2a90e174e..1e5b71ae1 100644 --- a/SCons/Tool/mslink.py +++ b/SCons/Tool/mslink.py @@ -256,7 +256,7 @@ compositeLdmodAction = ldmodLinkAction + regServerCheck + embedManifestDllCheckA exeLinkAction = SCons.Action.Action('${TEMPFILE("$LINK $LINKFLAGS /OUT:$TARGET.windows $_LIBDIRFLAGS $_LIBFLAGS $_PDB $SOURCES.windows", "$LINKCOMSTR")}', '$LINKCOMSTR') compositeLinkAction = exeLinkAction + embedManifestExeCheckAction -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createSharedLibBuilder(env, shlib_suffix='$SHLIBSUFFIX') SCons.Tool.createProgBuilder(env) diff --git a/SCons/Tool/mssdk.py b/SCons/Tool/mssdk.py index b94f105f0..0151eff2b 100644 --- a/SCons/Tool/mssdk.py +++ b/SCons/Tool/mssdk.py @@ -36,7 +36,7 @@ selection method. from .MSCommon import mssdk_exists, \ mssdk_setup_env -def generate(env): +def generate(env) -> None: """Add construction variables for an MS SDK to an Environment.""" mssdk_setup_env(env) diff --git a/SCons/Tool/msvc.py b/SCons/Tool/msvc.py index 191d2cc7c..33a67d0f4 100644 --- a/SCons/Tool/msvc.py +++ b/SCons/Tool/msvc.py @@ -60,7 +60,7 @@ def validate_vars(env): if not SCons.Util.is_String(env['PCHSTOP']): raise SCons.Errors.UserError("The PCHSTOP construction variable must be a string: %r"%env['PCHSTOP']) -def msvc_set_PCHPDBFLAGS(env): +def msvc_set_PCHPDBFLAGS(env) -> None: """ Set appropriate PCHPDBFLAGS for the MSVC version being used. """ @@ -229,7 +229,7 @@ ShCXXAction = SCons.Action.Action("$SHCXXCOM", "$SHCXXCOMSTR", -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for MSVC++ to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index 86df1ef66..51e2970e4 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -207,7 +207,7 @@ class _UserGenerator: usrdebg = None usrconf = None createfile = False - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: # DebugSettings should be a list of debug dictionary sorted in the same order # as the target list and variants if 'variant' not in env: @@ -249,12 +249,12 @@ class _UserGenerator: trg[key] = str(src[key]) self.configs[var].debug = trg - def UserHeader(self): + def UserHeader(self) -> None: encoding = self.env.subst('$MSVSENCODING') versionstr = self.versionstr self.usrfile.write(self.usrhead % locals()) - def UserProject(self): + def UserProject(self) -> None: pass def Build(self): @@ -317,14 +317,14 @@ V9DebugSettings = { class _GenerateV7User(_UserGenerator): """Generates a Project file for MSVS .NET""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: if self.version_num >= 9.0: self.usrhead = V9UserHeader self.usrconf = V9UserConfiguration self.usrdebg = V9DebugSettings super().__init__(dspfile, source, env) - def UserProject(self): + def UserProject(self) -> None: confkeys = sorted(self.configs.keys()) for kind in confkeys: variant = self.configs[kind].variant @@ -379,7 +379,7 @@ V10DebugSettings = { class _GenerateV10User(_UserGenerator): """Generates a Project'user file for MSVS 2010 or later""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: version_num, suite = msvs_parse_version(env['MSVS_VERSION']) if version_num >= 14.3: # Visual Studio 2022 is considered to be version 17. @@ -399,7 +399,7 @@ class _GenerateV10User(_UserGenerator): self.usrdebg = V10DebugSettings super().__init__(dspfile, source, env) - def UserProject(self): + def UserProject(self) -> None: confkeys = sorted(self.configs.keys()) for kind in confkeys: variant = self.configs[kind].variant @@ -422,7 +422,7 @@ class _DSPGenerator: 'resources', 'misc'] - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: self.dspfile = str(dspfile) try: get_abspath = dspfile.get_abspath @@ -585,7 +585,7 @@ class _DSPGenerator: for n in sourcenames: self.sources[n].sort(key=lambda a: a.lower()) - def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, cppdefines, cpppaths, cppflags, dspfile=dspfile, env=env): + def AddConfig(self, variant, buildtarget, outdir, runfile, cmdargs, cppdefines, cpppaths, cppflags, dspfile=dspfile, env=env) -> None: config = Config() config.buildtarget = buildtarget config.outdir = outdir @@ -617,7 +617,7 @@ class _DSPGenerator: if not (p.platform in seen or seen.add(p.platform))] - def Build(self): + def Build(self) -> None: pass V6DSPHeader = """\ @@ -645,7 +645,7 @@ CFG=%(name)s - Win32 %(confkey)s class _GenerateV6DSP(_DSPGenerator): """Generates a Project file for MSVS 6.0""" - def PrintHeader(self): + def PrintHeader(self) -> None: # pick a default config confkeys = sorted(self.configs.keys()) @@ -659,7 +659,7 @@ class _GenerateV6DSP(_DSPGenerator): self.file.write('!MESSAGE\n\n') - def PrintProject(self): + def PrintProject(self) -> None: name = self.name self.file.write('# Begin Project\n' '# PROP AllowPerConfigDependencies 0\n' @@ -728,7 +728,7 @@ class _GenerateV6DSP(_DSPGenerator): pdata = base64.b64encode(pdata).decode() self.file.write(pdata + '\n') - def PrintSourceFiles(self): + def PrintSourceFiles(self) -> None: categories = {'Source Files': 'cpp|c|cxx|l|y|def|odl|idl|hpj|bat', 'Header Files': 'h|hpp|hxx|hm|inl', 'Local Headers': 'h|hpp|hxx|hm|inl', @@ -882,7 +882,7 @@ V8DSPConfiguration = """\ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): """Generates a Project file for MSVS .NET""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: _DSPGenerator.__init__(self, dspfile, source, env) self.version = env['MSVS_VERSION'] self.version_num, self.suite = msvs_parse_version(self.version) @@ -905,7 +905,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): _GenerateV7User.__init__(self, dspfile, source, env) - def PrintHeader(self): + def PrintHeader(self) -> None: env = self.env versionstr = self.versionstr name = self.name @@ -948,7 +948,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): self.file.write('\t\n' '\t\n') - def PrintProject(self): + def PrintProject(self) -> None: self.file.write('\t\n') confkeys = sorted(self.configs.keys()) @@ -1005,7 +1005,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): pdata = base64.b64encode(pdata).decode() self.file.write(pdata + '-->\n') - def printSources(self, hierarchy, commonprefix): + def printSources(self, hierarchy, commonprefix) -> None: sorteditems = sorted(hierarchy.items(), key=lambda a: a[0].lower()) # First folders, then files @@ -1027,7 +1027,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): '\t\t\t\tRelativePath="%s">\n' '\t\t\t\n' % file) - def PrintSourceFiles(self): + def PrintSourceFiles(self) -> None: categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', 'Header Files': 'h;hpp;hxx;hm;inl', 'Local Headers': 'h;hpp;hxx;hm;inl', @@ -1192,7 +1192,7 @@ V15DSPHeader = """\ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): """Generates a Project file for MSVS 2010""" - def __init__(self, dspfile, source, env): + def __init__(self, dspfile, source, env) -> None: _DSPGenerator.__init__(self, dspfile, source, env) self.dspheader = V10DSPHeader self.dspconfiguration = V10DSPProjectConfiguration @@ -1200,7 +1200,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): _GenerateV10User.__init__(self, dspfile, source, env) - def PrintHeader(self): + def PrintHeader(self) -> None: env = self.env name = self.name versionstr = self.versionstr @@ -1340,7 +1340,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): pdata = base64.b64encode(pdata).decode() self.file.write(pdata + '-->\n') - def printFilters(self, hierarchy, name): + def printFilters(self, hierarchy, name) -> None: sorteditems = sorted(hierarchy.items(), key = lambda a: a[0].lower()) for key, value in sorteditems: @@ -1351,7 +1351,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t\n' % (filter_name, _generateGUID(self.dspabs, filter_name))) self.printFilters(value, filter_name) - def printSources(self, hierarchy, kind, commonprefix, filter_name): + def printSources(self, hierarchy, kind, commonprefix, filter_name) -> None: keywords = {'Source Files': 'ClCompile', 'Header Files': 'ClInclude', 'Local Headers': 'ClInclude', @@ -1377,7 +1377,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): '\t\t\t%s\n' '\t\t\n' % (keywords[kind], file, filter_name, keywords[kind])) - def PrintSourceFiles(self): + def PrintSourceFiles(self) -> None: categories = {'Source Files': 'cpp;c;cxx;l;y;def;odl;idl;hpj;bat', 'Header Files': 'h;hpp;hxx;hm;inl', 'Local Headers': 'h;hpp;hxx;hm;inl', @@ -1443,7 +1443,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): #'\t\t\n' '\t\n' % str(self.sconscript)) - def Parse(self): + def Parse(self) -> None: # DEBUG # print("_GenerateV10DSP.Parse()") pass @@ -1462,7 +1462,7 @@ class _GenerateV10DSP(_DSPGenerator, _GenerateV10User): class _DSWGenerator: """ Base class for DSW generators """ - def __init__(self, dswfile, source, env): + def __init__(self, dswfile, source, env) -> None: self.dswfile = os.path.normpath(str(dswfile)) self.dsw_folder_path = os.path.dirname(os.path.abspath(self.dswfile)) self.env = env @@ -1483,12 +1483,12 @@ class _DSWGenerator: self.name = os.path.basename(SCons.Util.splitext(self.dswfile)[0]) self.name = self.env.subst(self.name) - def Build(self): + def Build(self) -> None: pass class _GenerateV7DSW(_DSWGenerator): """Generates a Solution file for MSVS .NET""" - def __init__(self, dswfile, source, env): + def __init__(self, dswfile, source, env) -> None: super().__init__(dswfile, source, env) self.file = None @@ -1520,7 +1520,7 @@ class _GenerateV7DSW(_DSWGenerator): if self.nokeep == 0 and os.path.exists(self.dswfile): self.Parse() - def AddConfig(self, variant, dswfile=dswfile): + def AddConfig(self, variant, dswfile=dswfile) -> None: config = Config() match = re.match(r'(.*)\|(.*)', variant) @@ -1548,7 +1548,7 @@ class _GenerateV7DSW(_DSWGenerator): self.platforms = [p.platform for p in self.configs.values() if not (p.platform in seen or seen.add(p.platform))] - def GenerateProjectFilesInfo(self): + def GenerateProjectFilesInfo(self) -> None: for dspfile in self.dspfiles: dsp_folder_path, name = os.path.split(dspfile) dsp_folder_path = os.path.abspath(dsp_folder_path) @@ -1601,7 +1601,7 @@ class _GenerateV7DSW(_DSWGenerator): self.configs.update(data) - def PrintSolution(self): + def PrintSolution(self) -> None: """Writes a solution file""" self.file.write('Microsoft Visual Studio Solution File, Format Version %s\n' % self.versionstr) if self.version_num >= 14.3: @@ -1769,7 +1769,7 @@ Package=<3> class _GenerateV6DSW(_DSWGenerator): """Generates a Workspace file for MSVS 6.0""" - def PrintWorkspace(self): + def PrintWorkspace(self) -> None: """ writes a DSW file """ name = self.name dspfile = os.path.relpath(self.dspfiles[0], self.dsw_folder_path) @@ -1785,7 +1785,7 @@ class _GenerateV6DSW(_DSWGenerator): self.file.close() -def GenerateDSP(dspfile, source, env): +def GenerateDSP(dspfile, source, env) -> None: """Generates a Project file based on the version of MSVS that is being used""" version_num = 6.0 @@ -1801,7 +1801,7 @@ def GenerateDSP(dspfile, source, env): g = _GenerateV6DSP(dspfile, source, env) g.Build() -def GenerateDSW(dswfile, source, env): +def GenerateDSW(dswfile, source, env) -> None: """Generates a Solution/Workspace file based on the version of MSVS that is being used""" version_num = 6.0 @@ -1861,7 +1861,7 @@ def GenerateProject(target, source, env): GenerateDSW(dswfile, source, env) -def GenerateSolution(target, source, env): +def GenerateSolution(target, source, env) -> None: GenerateDSW(target[0], source, env) def projectEmitter(target, source, env): @@ -2039,7 +2039,7 @@ solutionBuilder = SCons.Builder.Builder(action = '$MSVSSOLUTIONCOM', default_MSVS_SConscript = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Microsoft Visual Studio project files to an Environment.""" try: diff --git a/SCons/Tool/msvsTests.py b/SCons/Tool/msvsTests.py index c4d2e9835..9c369d130 100644 --- a/SCons/Tool/msvsTests.py +++ b/SCons/Tool/msvsTests.py @@ -391,7 +391,7 @@ regdata_cv = r'''[HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\CurrentVersion] regdata_none = [] class DummyEnv: - def __init__(self, dict=None): + def __init__(self, dict=None) -> None: self.fs = SCons.Node.FS.FS() if dict: self.dict = dict @@ -403,13 +403,13 @@ class DummyEnv: return self.dict return self.dict[key] - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.dict[key] = value def __getitem__(self, key): return self.dict[key] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dict def get(self, name, value=None): @@ -424,14 +424,14 @@ class DummyEnv: class RegKey: """key class for storing an 'open' registry key""" - def __init__(self,key): + def __init__(self,key) -> None: self.key = key # Warning: this is NOT case-insensitive, unlike the Windows registry. # So e.g. HKLM\Software is NOT the same key as HKLM\SOFTWARE. class RegNode: """node in the dummy registry""" - def __init__(self,name): + def __init__(self,name) -> None: self.valdict = {} self.keydict = {} self.keyarray = [] @@ -444,7 +444,7 @@ class RegNode: else: raise SCons.Util.RegError - def addValue(self,name,val): + def addValue(self,name,val) -> None: self.valdict[name] = val self.valarray.append(name) @@ -456,7 +456,7 @@ class RegNode: raise SCons.Util.RegError return rv - def key(self,key,sep = '\\'): + def key(self,key,sep: str = '\\'): if key.find(sep) != -1: keyname, subkeys = key.split(sep,1) else: @@ -471,7 +471,7 @@ class RegNode: except KeyError: raise SCons.Util.RegError - def addKey(self,name,sep = '\\'): + def addKey(self,name,sep: str = '\\'): if name.find(sep) != -1: keyname, subkeys = name.split(sep, 1) else: @@ -491,10 +491,10 @@ class RegNode: def keyindex(self,index): return self.keydict[self.keyarray[index]] - def __str__(self): + def __str__(self) -> str: return self._doStr() - def _doStr(self, indent = ''): + def _doStr(self, indent: str = ''): rv = "" for value in self.valarray: rv = rv + '%s"%s" = "%s"\n' % (indent, value, self.valdict[value]) @@ -506,7 +506,7 @@ class RegNode: class DummyRegistry: """registry class for storing fake registry attributes""" - def __init__(self,data): + def __init__(self,data) -> None: """parse input data into the fake registry""" self.root = RegNode('REGISTRY') self.root.addKey('HKEY_LOCAL_MACHINE') @@ -516,7 +516,7 @@ class DummyRegistry: self.parse(data) - def parse(self, data): + def parse(self, data) -> None: parents = [None, None] parents[0] = self.root keymatch = re.compile(r'^\[(.*)\]$') @@ -577,7 +577,7 @@ def DummyQueryValue(key, value): # print "Query Value",key.name+"\\"+value,"=>",rv return rv -def DummyExists(path): +def DummyExists(path) -> int: return 1 def DummyVsWhere(msvc_version, env): @@ -587,7 +587,7 @@ def DummyVsWhere(msvc_version, env): class msvsTestCase(unittest.TestCase): """This test case is run several times with different defaults. See its subclasses below.""" - def setUp(self): + def setUp(self) -> None: debug("THIS TYPE :%s"%self) global registry registry = self.registry @@ -599,7 +599,7 @@ class msvsTestCase(unittest.TestCase): os.chdir(self.test.workpath("")) self.fs = SCons.Node.FS.FS() - def test_get_default_version(self): + def test_get_default_version(self) -> None: """Test retrieval of the default visual studio version""" debug("Testing for default version %s"%self.default_version) @@ -632,18 +632,18 @@ class msvsTestCase(unittest.TestCase): assert env['MSVS']['VERSION'] == override, env['MSVS']['VERSION'] assert v3 == override, v3 - def _TODO_test_merge_default_version(self): + def _TODO_test_merge_default_version(self) -> None: """Test the merge_default_version() function""" pass - def test_query_versions(self): + def test_query_versions(self) -> None: """Test retrieval of the list of visual studio versions""" v1 = query_versions() assert not v1 or str(v1[0]) == self.highest_version, \ (v1, self.highest_version) assert len(v1) == self.number_of_versions, v1 - def test_config_generation(self): + def test_config_generation(self) -> None: """Test _DSPGenerator.__init__(...)""" if not self.highest_version : return diff --git a/SCons/Tool/mwcc.py b/SCons/Tool/mwcc.py index 8f1201a02..22b610a9f 100644 --- a/SCons/Tool/mwcc.py +++ b/SCons/Tool/mwcc.py @@ -37,7 +37,7 @@ import os.path import SCons.Util -def set_vars(env): +def set_vars(env) -> int: """Set MWCW_VERSION, MWCW_VERSIONS, and some codewarrior environment vars MWCW_VERSIONS is set to a list of objects representing installed versions @@ -120,7 +120,7 @@ def find_versions(): class MWVersion: - def __init__(self, version, path, platform): + def __init__(self, version, path, platform) -> None: self.version = version self.path = path self.platform = platform @@ -144,7 +144,7 @@ class MWVersion: self.includes = [msl, support] self.libs = [msl, support] - def __str__(self): + def __str__(self) -> str: return self.version @@ -152,7 +152,7 @@ CSuffixes = ['.c', '.C'] CXXSuffixes = ['.cc', '.cpp', '.cxx', '.c++', '.C++'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for the mwcc to an Environment.""" import SCons.Defaults import SCons.Tool diff --git a/SCons/Tool/mwld.py b/SCons/Tool/mwld.py index 20676606e..9824c01b5 100644 --- a/SCons/Tool/mwld.py +++ b/SCons/Tool/mwld.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" import SCons.Tool -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for lib to an Environment.""" SCons.Tool.createStaticLibBuilder(env) SCons.Tool.createSharedLibBuilder(env) diff --git a/SCons/Tool/nasm.py b/SCons/Tool/nasm.py index ff0bc612f..253ad1cf6 100644 --- a/SCons/Tool/nasm.py +++ b/SCons/Tool/nasm.py @@ -44,7 +44,7 @@ if SCons.Util.case_sensitive_suffixes('.s', '.S'): else: ASSuffixes.extend(['.S']) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for nasm to an Environment.""" static_obj, shared_obj = SCons.Tool.createObjBuilders(env) diff --git a/SCons/Tool/ninja/Methods.py b/SCons/Tool/ninja/Methods.py index c0afab80b..7259475b0 100644 --- a/SCons/Tool/ninja/Methods.py +++ b/SCons/Tool/ninja/Methods.py @@ -33,17 +33,17 @@ from SCons.Tool.ninja.Utils import get_targets_sources, get_dependencies, get_or get_rule, get_path, generate_command, get_command_env, get_comstr -def register_custom_handler(env, name, handler): +def register_custom_handler(env, name, handler) -> None: """Register a custom handler for SCons function actions.""" env[NINJA_CUSTOM_HANDLERS][name] = handler -def register_custom_rule_mapping(env, pre_subst_string, rule): +def register_custom_rule_mapping(env, pre_subst_string, rule) -> None: """Register a function to call for a given rule.""" SCons.Tool.ninja.Globals.__NINJA_RULE_MAPPING[pre_subst_string] = rule -def register_custom_rule(env, rule, command, description="", deps=None, pool=None, use_depfile=False, use_response_file=False, response_file_content="$rspc"): +def register_custom_rule(env, rule, command, description: str="", deps=None, pool=None, use_depfile: bool=False, use_response_file: bool=False, response_file_content: str="$rspc") -> None: """Allows specification of Ninja rules from inside SCons files.""" rule_obj = { "command": command, @@ -66,12 +66,12 @@ def register_custom_rule(env, rule, command, description="", deps=None, pool=Non env[NINJA_RULES][rule] = rule_obj -def register_custom_pool(env, pool, size): +def register_custom_pool(env, pool, size) -> None: """Allows the creation of custom Ninja pools""" env[NINJA_POOLS][pool] = size -def set_build_node_callback(env, node, callback): +def set_build_node_callback(env, node, callback) -> None: if not node.is_conftest(): node.attributes.ninja_build_callback = callback @@ -215,7 +215,7 @@ def get_command(env, node, action): # pylint: disable=too-many-branches return ninja_build -def gen_get_response_file_command(env, rule, tool, tool_is_dynamic=False, custom_env={}): +def gen_get_response_file_command(env, rule, tool, tool_is_dynamic: bool=False, custom_env={}): """Generate a response file command provider for rule name.""" # If win32 using the environment with a response file command will cause diff --git a/SCons/Tool/ninja/NinjaState.py b/SCons/Tool/ninja/NinjaState.py index 5e7c28919..707a9e20d 100644 --- a/SCons/Tool/ninja/NinjaState.py +++ b/SCons/Tool/ninja/NinjaState.py @@ -52,7 +52,7 @@ from .Methods import get_command class NinjaState: """Maintains state of Ninja build system as it's translated from SCons.""" - def __init__(self, env, ninja_file, ninja_syntax): + def __init__(self, env, ninja_file, ninja_syntax) -> None: self.env = env self.ninja_file = ninja_file @@ -303,7 +303,7 @@ class NinjaState: } self.pools = {"scons_pool": 1} - def add_build(self, node): + def add_build(self, node) -> bool: if not node.has_builder(): return False @@ -348,12 +348,12 @@ class NinjaState: # TODO: rely on SCons to tell us what is generated source # or some form of user scanner maybe (Github Issue #3624) - def is_generated_source(self, output): + def is_generated_source(self, output) -> bool: """Check if output ends with a known generated suffix.""" _, suffix = splitext(output) return suffix in self.generated_suffixes - def has_generated_sources(self, output): + def has_generated_sources(self, output) -> bool: """ Determine if output indicates this is a generated header file. """ @@ -710,7 +710,7 @@ class NinjaState: class SConsToNinjaTranslator: """Translates SCons Actions into Ninja build objects.""" - def __init__(self, env): + def __init__(self, env) -> None: self.env = env self.func_handlers = { # Skip conftest builders diff --git a/SCons/Tool/ninja/Overrides.py b/SCons/Tool/ninja/Overrides.py index e98ec4036..83d2efb11 100644 --- a/SCons/Tool/ninja/Overrides.py +++ b/SCons/Tool/ninja/Overrides.py @@ -27,7 +27,7 @@ ninja file generation import SCons -def ninja_hack_linkcom(env): +def ninja_hack_linkcom(env) -> None: # TODO: change LINKCOM and SHLINKCOM to handle embedding manifest exe checks # without relying on the SCons hacks that SCons uses by default. if env["PLATFORM"] == "win32": @@ -42,7 +42,7 @@ def ninja_hack_linkcom(env): ] = '${TEMPFILE("$SHLINK $SHLINKFLAGS $_SHLINK_TARGETS $_LIBDIRFLAGS $_LIBFLAGS $_PDB $_SHLINK_SOURCES", "$SHLINKCOMSTR")}' -def ninja_hack_arcom(env): +def ninja_hack_arcom(env) -> None: """ Force ARCOM so use 's' flag on ar instead of separately running ranlib """ @@ -68,12 +68,12 @@ class NinjaNoResponseFiles(SCons.Platform.TempFileMunge): def __call__(self, target, source, env, for_signature): return self.cmd - def _print_cmd_str(*_args, **_kwargs): + def _print_cmd_str(*_args, **_kwargs) -> None: """Disable this method""" pass -def ninja_always_serial(self, num, taskmaster): +def ninja_always_serial(self, num, taskmaster) -> None: """Replacement for SCons.Job.Jobs constructor which always uses the Serial Job class.""" # We still set self.num_jobs to num even though it's a lie. The # only consumer of this attribute is the Parallel Job class AND diff --git a/SCons/Tool/ninja/Utils.py b/SCons/Tool/ninja/Utils.py index 7269fb2e5..eb09daf4e 100644 --- a/SCons/Tool/ninja/Utils.py +++ b/SCons/Tool/ninja/Utils.py @@ -34,7 +34,7 @@ class NinjaExperimentalWarning(SCons.Warnings.WarningOnByDefault): pass -def ninja_add_command_line_options(): +def ninja_add_command_line_options() -> None: """ Add additional command line arguments to SCons specific to the ninja tool """ @@ -92,7 +92,7 @@ def alias_to_ninja_build(node): } -def check_invalid_ninja_node(node): +def check_invalid_ninja_node(node) -> bool: return not isinstance(node, (SCons.Node.FS.Base, SCons.Node.Alias.Alias)) @@ -129,7 +129,7 @@ def get_order_only(node): return [get_path(src_file(prereq)) for prereq in filter_ninja_nodes(node.prerequisites)] -def get_dependencies(node, skip_sources=False): +def get_dependencies(node, skip_sources: bool=False): """Return a list of dependencies for node.""" if skip_sources: return [ @@ -236,7 +236,7 @@ def to_escaped_list(env, lst): return sorted([dep.escape(env.get("ESCAPE", lambda x: x)) for dep in deps_list]) -def generate_depfile(env, node, dependencies): +def generate_depfile(env, node, dependencies) -> None: """ Ninja tool function for writing a depfile. The depfile should include the node path followed by all the dependent files in a makefile format. @@ -281,7 +281,7 @@ def ninja_recursive_sorted_dict(build): return sorted_dict -def ninja_sorted_build(ninja, **build): +def ninja_sorted_build(ninja, **build) -> None: sorted_dict = ninja_recursive_sorted_dict(build) ninja.build(**sorted_dict) @@ -437,7 +437,7 @@ def ninja_whereis(thing, *_args, **_kwargs): return path -def ninja_print_conf_log(s, target, source, env): +def ninja_print_conf_log(s, target, source, env) -> None: """Command line print only for conftest to generate a correct conf log.""" if target and target[0].is_conftest(): action = SCons.Action._ActionAction() diff --git a/SCons/Tool/ninja/__init__.py b/SCons/Tool/ninja/__init__.py index 2622641d9..0ee72d2cf 100644 --- a/SCons/Tool/ninja/__init__.py +++ b/SCons/Tool/ninja/__init__.py @@ -136,7 +136,7 @@ def ninja_builder(env, target, source): sys.stdout.write("\n") -def options(opts): +def options(opts) -> None: """ Add command line Variables for Ninja builder. """ @@ -302,7 +302,7 @@ def generate(env): # instead return something that looks more expanded. So to # continue working even if a user has done this we map both the # "bracketted" and semi-expanded versions. - def robust_rule_mapping(var, rule, tool): + def robust_rule_mapping(var, rule, tool) -> None: provider = gen_get_response_file_command(env, rule, tool) env.NinjaRuleMapping("${" + var + "}", provider) @@ -459,7 +459,7 @@ def generate(env): # In the future we may be able to use this to actually cache the build.ninja # file once we have the upstream support for referencing SConscripts as File # nodes. - def ninja_execute(self): + def ninja_execute(self) -> None: target = self.targets[0] if target.get_env().get('NINJA_SKIP'): @@ -475,7 +475,7 @@ def generate(env): # date-ness. SCons.Script.Main.BuildTask.needs_execute = lambda x: True - def ninja_Set_Default_Targets(env, tlist): + def ninja_Set_Default_Targets(env, tlist) -> None: """ Record the default targets if they were ever set by the user. Ninja will need to write the default targets and make sure not to include diff --git a/SCons/Tool/ninja/ninja_daemon_build.py b/SCons/Tool/ninja/ninja_daemon_build.py index 32c375dfd..f198d773c 100644 --- a/SCons/Tool/ninja/ninja_daemon_build.py +++ b/SCons/Tool/ninja/ninja_daemon_build.py @@ -55,7 +55,7 @@ logging.basicConfig( ) -def log_error(msg): +def log_error(msg) -> None: logging.debug(msg) sys.stderr.write(msg) diff --git a/SCons/Tool/ninja/ninja_run_daemon.py b/SCons/Tool/ninja/ninja_run_daemon.py index 08029a29f..666be0f71 100644 --- a/SCons/Tool/ninja/ninja_run_daemon.py +++ b/SCons/Tool/ninja/ninja_run_daemon.py @@ -61,7 +61,7 @@ logging.basicConfig( level=logging.DEBUG, ) -def log_error(msg): +def log_error(msg) -> None: logging.debug(msg) sys.stderr.write(msg) diff --git a/SCons/Tool/ninja/ninja_scons_daemon.py b/SCons/Tool/ninja/ninja_scons_daemon.py index 6802af293..2084097fc 100644 --- a/SCons/Tool/ninja/ninja_scons_daemon.py +++ b/SCons/Tool/ninja/ninja_scons_daemon.py @@ -77,11 +77,11 @@ logging.basicConfig( ) -def daemon_log(message): +def daemon_log(message) -> None: logging.debug(message) -def custom_readlines(handle, line_separator="\n", chunk_size=1): +def custom_readlines(handle, line_separator: str="\n", chunk_size: int=1): buf = "" while not handle.closed: data = handle.read(chunk_size) @@ -98,7 +98,7 @@ def custom_readlines(handle, line_separator="\n", chunk_size=1): buf = "" -def custom_readerr(handle, line_separator="\n", chunk_size=1): +def custom_readerr(handle, line_separator: str="\n", chunk_size: int=1): buf = "" while not handle.closed: data = handle.read(chunk_size) @@ -112,13 +112,13 @@ def custom_readerr(handle, line_separator="\n", chunk_size=1): yield chunk + line_separator -def enqueue_output(out, queue): +def enqueue_output(out, queue) -> None: for line in iter(custom_readlines(out)): queue.put(line) out.close() -def enqueue_error(err, queue): +def enqueue_error(err, queue) -> None: for line in iter(custom_readerr(err)): queue.put(line) err.close() @@ -143,7 +143,7 @@ class StateInfo: shared_state = StateInfo() -def sigint_func(signum, frame): +def sigint_func(signum, frame) -> None: global shared_state shared_state.daemon_needs_to_shutdown = True @@ -264,7 +264,7 @@ logging.debug( keep_alive_timer = timer() -def server_thread_func(): +def server_thread_func() -> None: global shared_state class S(http.server.BaseHTTPRequestHandler): def do_GET(self): @@ -284,7 +284,7 @@ def server_thread_func(): daemon_log(f"Got request: {build[0]}") input_q.put(build[0]) - def pred(): + def pred() -> bool: return build[0] in shared_state.finished_building with building_cv: @@ -329,7 +329,7 @@ def server_thread_func(): daemon_log("SERVER ERROR: " + traceback.format_exc()) raise - def log_message(self, format, *args): + def log_message(self, format, *args) -> None: return socketserver.TCPServer.allow_reuse_address = True diff --git a/SCons/Tool/packaging/__init__.py b/SCons/Tool/packaging/__init__.py index 6fe01c190..c8e530de7 100644 --- a/SCons/Tool/packaging/__init__.py +++ b/SCons/Tool/packaging/__init__.py @@ -199,7 +199,7 @@ def Package(env, target=None, source=None, **kw): # added = False -def generate(env): +def generate(env) -> None: global added if not added: added = True @@ -218,11 +218,11 @@ def generate(env): env['BUILDERS']['Tag'] = Tag -def exists(env): +def exists(env) -> int: return 1 -def options(opts): +def options(opts) -> None: opts.AddVariables( EnumVariable('PACKAGETYPE', 'the type of package to create.', @@ -235,7 +235,7 @@ def options(opts): # Internal utility functions # -def copy_attr(f1, f2): +def copy_attr(f1, f2) -> None: """ Copies the special packaging file attributes from f1 to f2. """ if f1._tags: @@ -247,7 +247,7 @@ def copy_attr(f1, f2): for attr in pattrs: f2.Tag(attr, f1.GetTag(attr)) -def putintopackageroot(target, source, env, pkgroot, honor_install_location=1): +def putintopackageroot(target, source, env, pkgroot, honor_install_location: int=1): """ Copies all source files to the directory given in pkgroot. If honor_install_location is set and the copied source file has an @@ -298,7 +298,7 @@ def stripinstallbuilder(target, source, env): It also warns about files which have no install builder attached. """ - def has_no_install_location(file): + def has_no_install_location(file) -> bool: return not (file.has_builder() and hasattr(file.builder, 'name') and file.builder.name in ["InstallBuilder", "InstallAsBuilder"]) diff --git a/SCons/Tool/packaging/ipk.py b/SCons/Tool/packaging/ipk.py index ac8b992bb..930eacbec 100644 --- a/SCons/Tool/packaging/ipk.py +++ b/SCons/Tool/packaging/ipk.py @@ -105,7 +105,7 @@ def gen_ipk_dir(proot, source, env, kw): # the packageroot directory does now contain the specfiles. return proot -def build_specfiles(source, target, env): +def build_specfiles(source, target, env) -> int: """ Filter the targets for the needed files and use the variables in env to create the specfile. """ diff --git a/SCons/Tool/packaging/msi.py b/SCons/Tool/packaging/msi.py index 458e81f83..a0bed8f2a 100644 --- a/SCons/Tool/packaging/msi.py +++ b/SCons/Tool/packaging/msi.py @@ -130,7 +130,7 @@ def create_feature_dict(files): """ dict = {} - def add_to_dict( feature, file ): + def add_to_dict( feature, file ) -> None: if not SCons.Util.is_List( feature ): feature = [ feature ] @@ -150,7 +150,7 @@ def create_feature_dict(files): return dict -def generate_guids(root): +def generate_guids(root) -> None: """ generates globally unique identifiers for parts of the xml which need them. @@ -179,7 +179,7 @@ def generate_guids(root): node.attributes[attribute] = str(hash) -def string_wxsfile(target, source, env): +def string_wxsfile(target, source, env) -> str: return "building WiX file %s" % target[0].path def build_wxsfile(target, source, env): @@ -266,7 +266,7 @@ def create_default_directory_layout(root, NAME, VERSION, VENDOR, filename_set): # # mandatory and optional file tags # -def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set): +def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, id_set) -> None: """ Builds the Component sections of the wxs file with their included files. Files need to be specified in 8.3 format and in the long name format, long @@ -358,7 +358,7 @@ def build_wxsfile_file_section(root, files, NAME, VERSION, VENDOR, filename_set, # # additional functions # -def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): +def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set) -> None: """ This function creates the tag based on the supplied xml tree. This is achieved by finding all s and adding them to a default target. @@ -413,7 +413,7 @@ def build_wxsfile_features_section(root, files, NAME, VERSION, SUMMARY, id_set): root.getElementsByTagName('Product')[0].childNodes.append(Feature) -def build_wxsfile_default_gui(root): +def build_wxsfile_default_gui(root) -> None: """ This function adds a default GUI to the wxs file """ factory = Document() @@ -427,7 +427,7 @@ def build_wxsfile_default_gui(root): UIRef.attributes['Id'] = 'WixUI_ErrorProgressText' Product.childNodes.append(UIRef) -def build_license_file(directory, spec): +def build_license_file(directory, spec) -> None: """ Creates a License.rtf file with the content of "X_MSI_LICENSE_TEXT" in the given directory """ @@ -451,7 +451,7 @@ def build_license_file(directory, spec): # # mandatory and optional package tags # -def build_wxsfile_header_section(root, spec): +def build_wxsfile_header_section(root, spec) -> None: """ Adds the xml file node which define the package meta-data. """ # Create the needed DOM nodes and add them at the correct position in the tree. diff --git a/SCons/Tool/packaging/rpm.py b/SCons/Tool/packaging/rpm.py index cdeabcf62..a0c317229 100644 --- a/SCons/Tool/packaging/rpm.py +++ b/SCons/Tool/packaging/rpm.py @@ -317,7 +317,7 @@ class SimpleTagCompiler: "cdef ghij cdef gh ij" """ - def __init__(self, tagset, mandatory=1): + def __init__(self, tagset, mandatory: int=1) -> None: self.tagset = tagset self.mandatory = mandatory diff --git a/SCons/Tool/pdf.py b/SCons/Tool/pdf.py index 050f1a572..ddaaa8aab 100644 --- a/SCons/Tool/pdf.py +++ b/SCons/Tool/pdf.py @@ -37,7 +37,7 @@ PDFBuilder = None EpsPdfAction = SCons.Action.Action('$EPSTOPDFCOM', '$EPSTOPDFCOMSTR') -def generate(env): +def generate(env) -> None: try: env['BUILDERS']['PDF'] except KeyError: @@ -57,7 +57,7 @@ def generate(env): # put the epstopdf builder in this routine so we can add it after # the pdftex builder so that one is the default for no source suffix -def generate2(env): +def generate2(env) -> None: bld = env['BUILDERS']['PDF'] #bld.add_action('.ps', EpsPdfAction) # this is covered by direct Ghostcript action in gs.py bld.add_action('.eps', EpsPdfAction) @@ -66,7 +66,7 @@ def generate2(env): env['EPSTOPDFFLAGS'] = SCons.Util.CLVar('') env['EPSTOPDFCOM'] = '$EPSTOPDF $EPSTOPDFFLAGS ${SOURCE} --outfile=${TARGET}' -def exists(env): +def exists(env) -> int: # This only puts a skeleton Builder in place, so if someone # references this Tool directly, it's always "available." return 1 diff --git a/SCons/Tool/pdflatex.py b/SCons/Tool/pdflatex.py index fbffb2395..e3c733b97 100644 --- a/SCons/Tool/pdflatex.py +++ b/SCons/Tool/pdflatex.py @@ -49,7 +49,7 @@ def PDFLaTeXAuxFunction(target = None, source= None, env=None): PDFLaTeXAuxAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for pdflatex to an Environment.""" global PDFLaTeXAction if PDFLaTeXAction is None: diff --git a/SCons/Tool/pdftex.py b/SCons/Tool/pdftex.py index e9a0bda03..4b7707fbe 100644 --- a/SCons/Tool/pdftex.py +++ b/SCons/Tool/pdftex.py @@ -68,7 +68,7 @@ def PDFTeXLaTeXFunction(target = None, source= None, env=None): PDFTeXLaTeXAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for pdftex to an Environment.""" global PDFTeXAction if PDFTeXAction is None: diff --git a/SCons/Tool/python.py b/SCons/Tool/python.py index c61fc8d72..2820afb47 100644 --- a/SCons/Tool/python.py +++ b/SCons/Tool/python.py @@ -33,13 +33,13 @@ import SCons.Tool from SCons.Scanner.Python import PythonScanner, PythonSuffixes -def generate(env): +def generate(env) -> None: """Hook the python builder and scanner into the environment.""" for suffix in PythonSuffixes: SCons.Tool.SourceFileScanner.add_scanner(suffix, PythonScanner) -def exists(env): +def exists(env) -> bool: return True # Local Variables: diff --git a/SCons/Tool/qt.py b/SCons/Tool/qt.py index 607b58d83..376e2ba19 100644 --- a/SCons/Tool/qt.py +++ b/SCons/Tool/qt.py @@ -34,5 +34,5 @@ def generate(env): "'qt3' will be removed entirely in a future release." ) -def exists(env): +def exists(env) -> bool: return False diff --git a/SCons/Tool/qt3.py b/SCons/Tool/qt3.py index 4e6975648..d35b661a4 100644 --- a/SCons/Tool/qt3.py +++ b/SCons/Tool/qt3.py @@ -90,7 +90,7 @@ def find_platform_specific_qt3_paths(): QT3_BIN_DIR = find_platform_specific_qt3_paths() -def checkMocIncluded(target, source, env): +def checkMocIncluded(target, source, env) -> None: moc = target[0] cpp = source[0] # looks like cpp.includes is cleared before the build stage :-( @@ -116,7 +116,7 @@ class _Automoc: StaticLibraries. """ - def __init__(self, objBuilderName): + def __init__(self, objBuilderName) -> None: self.objBuilderName = objBuilderName def __call__(self, target, source, env): diff --git a/SCons/Tool/rmic.py b/SCons/Tool/rmic.py index 5c7a04066..852339703 100644 --- a/SCons/Tool/rmic.py +++ b/SCons/Tool/rmic.py @@ -104,7 +104,7 @@ RMICBuilder = SCons.Builder.Builder(action = RMICAction, target_factory = SCons.Node.FS.Dir, source_factory = SCons.Node.FS.File) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for rmic to an Environment.""" env['BUILDERS']['RMIC'] = RMICBuilder @@ -123,7 +123,7 @@ def generate(env): env['RMICCOM'] = '$RMIC $RMICFLAGS -d ${TARGET.attributes.java_lookupdir} -classpath ${SOURCE.attributes.java_classdir} ${SOURCES.attributes.java_classname}' env['JAVACLASSSUFFIX'] = '.class' -def exists(env): +def exists(env) -> int: # As reported by Jan Nijtmans in issue #2730, the simple # return env.Detect('rmic') # doesn't always work during initialization. For now, we diff --git a/SCons/Tool/rpcgen.py b/SCons/Tool/rpcgen.py index 5ed565862..d5f514a44 100644 --- a/SCons/Tool/rpcgen.py +++ b/SCons/Tool/rpcgen.py @@ -42,7 +42,7 @@ rpcgen_header = cmd % ('h', '$RPCGENHEADERFLAGS') rpcgen_service = cmd % ('m', '$RPCGENSERVICEFLAGS') rpcgen_xdr = cmd % ('c', '$RPCGENXDRFLAGS') -def generate(env): +def generate(env) -> None: """Add RPCGEN Builders and construction variables for an Environment.""" client = Builder(action=rpcgen_client, suffix='_clnt.c', src_suffix='.x') diff --git a/SCons/Tool/rpm.py b/SCons/Tool/rpm.py index 2fd802a67..94f5e574a 100644 --- a/SCons/Tool/rpm.py +++ b/SCons/Tool/rpm.py @@ -46,7 +46,7 @@ import SCons.Util import SCons.Action import SCons.Defaults -def get_cmd(source, env): +def get_cmd(source, env) -> str: tar_file_with_included_specfile = source if SCons.Util.is_List(source): tar_file_with_included_specfile = source[0] @@ -110,7 +110,7 @@ RpmBuilder = SCons.Builder.Builder(action = SCons.Action.Action('$RPMCOM', '$RPM -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for rpm to an Environment.""" try: bld = env['BUILDERS']['Rpm'] diff --git a/SCons/Tool/rpmutils.py b/SCons/Tool/rpmutils.py index 2c4fb3220..209fcea3e 100644 --- a/SCons/Tool/rpmutils.py +++ b/SCons/Tool/rpmutils.py @@ -437,7 +437,7 @@ arch_canon = { # End of rpmrc dictionaries (Marker, don't change or remove!) -def defaultMachine(use_rpm_default=True): +def defaultMachine(use_rpm_default: bool=True): """ Return the canonicalized machine name. """ if use_rpm_default: @@ -471,7 +471,7 @@ def defaultNames(): """ Return the canonicalized machine and system name. """ return defaultMachine(), defaultSystem() -def updateRpmDicts(rpmrc, pyfile): +def updateRpmDicts(rpmrc, pyfile) -> None: """ Read the given rpmrc file with RPM definitions and update the info dictionaries in the file pyfile with it. The arguments will usually be 'rpmrc.in' from a recent RPM source @@ -531,10 +531,10 @@ def updateRpmDicts(rpmrc, pyfile): except: pass -def usage(): +def usage() -> None: print("rpmutils.py rpmrc.in rpmutils.py") -def main(): +def main() -> None: import sys if len(sys.argv) < 3: diff --git a/SCons/Tool/sgiar.py b/SCons/Tool/sgiar.py index 54f8b7b67..72ce3766b 100644 --- a/SCons/Tool/sgiar.py +++ b/SCons/Tool/sgiar.py @@ -39,7 +39,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/sgicc.py b/SCons/Tool/sgicc.py index 94a049769..7950d1074 100644 --- a/SCons/Tool/sgicc.py +++ b/SCons/Tool/sgicc.py @@ -35,7 +35,7 @@ __revision__ = "__FILE__ __REVISION__ __DATE__ __DEVELOPER__" from . import cc -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for gcc to an Environment.""" cc.generate(env) diff --git a/SCons/Tool/sgicxx.py b/SCons/Tool/sgicxx.py index 48b04ea92..796f7ab1d 100644 --- a/SCons/Tool/sgicxx.py +++ b/SCons/Tool/sgicxx.py @@ -40,7 +40,7 @@ cplusplus = SCons.Tool.cxx #cplusplus = __import__('cxx', globals(), locals(), []) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for SGI MIPS C++ to an Environment.""" cplusplus.generate(env) diff --git a/SCons/Tool/sgilink.py b/SCons/Tool/sgilink.py index e92c7b991..f66ad5ab1 100644 --- a/SCons/Tool/sgilink.py +++ b/SCons/Tool/sgilink.py @@ -36,7 +36,7 @@ from . import link linkers = ['CC', 'cc'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for MIPSPro to an Environment.""" link.generate(env) diff --git a/SCons/Tool/sunar.py b/SCons/Tool/sunar.py index 266e91493..03223b636 100644 --- a/SCons/Tool/sunar.py +++ b/SCons/Tool/sunar.py @@ -38,7 +38,7 @@ import SCons.Defaults import SCons.Tool import SCons.Util -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/suncc.py b/SCons/Tool/suncc.py index 4651219bd..4ef023158 100644 --- a/SCons/Tool/suncc.py +++ b/SCons/Tool/suncc.py @@ -36,7 +36,7 @@ import SCons.Util from . import cc -def generate(env): +def generate(env) -> None: """ Add Builders and construction variables for Forte C and C++ compilers to an Environment. diff --git a/SCons/Tool/suncxx.py b/SCons/Tool/suncxx.py index 7c4b0941d..51dc3731e 100644 --- a/SCons/Tool/suncxx.py +++ b/SCons/Tool/suncxx.py @@ -121,7 +121,7 @@ def get_cppc(env): return (cppcPath, 'CC', 'CC', cppcVersion) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for SunPRO C++.""" path, cxx, shcxx, version = get_cppc(env) if path: diff --git a/SCons/Tool/sunf77.py b/SCons/Tool/sunf77.py index 20d18938f..efeb488a2 100644 --- a/SCons/Tool/sunf77.py +++ b/SCons/Tool/sunf77.py @@ -39,7 +39,7 @@ from .FortranCommon import add_all_to_env compilers = ['sunf77', 'f77'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for sunf77 to an Environment.""" add_all_to_env(env) diff --git a/SCons/Tool/sunf90.py b/SCons/Tool/sunf90.py index ce1697c34..4ce03c19a 100644 --- a/SCons/Tool/sunf90.py +++ b/SCons/Tool/sunf90.py @@ -39,7 +39,7 @@ from .FortranCommon import add_all_to_env compilers = ['sunf90', 'f90'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for sun f90 compiler to an Environment.""" add_all_to_env(env) diff --git a/SCons/Tool/sunf95.py b/SCons/Tool/sunf95.py index 218569c0b..273987b77 100644 --- a/SCons/Tool/sunf95.py +++ b/SCons/Tool/sunf95.py @@ -39,7 +39,7 @@ from .FortranCommon import add_all_to_env compilers = ['sunf95', 'f95'] -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for sunf95 to an Environment.""" add_all_to_env(env) diff --git a/SCons/Tool/sunlink.py b/SCons/Tool/sunlink.py index b0c9816e6..c86d7c209 100644 --- a/SCons/Tool/sunlink.py +++ b/SCons/Tool/sunlink.py @@ -55,7 +55,7 @@ for d in dirs: break -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for Forte to an Environment.""" link.generate(env) diff --git a/SCons/Tool/swig.py b/SCons/Tool/swig.py index ff0c80d44..aefd7cbaa 100644 --- a/SCons/Tool/swig.py +++ b/SCons/Tool/swig.py @@ -46,7 +46,7 @@ swigs = [ 'swig', 'swig3.0', 'swig2.0' ] SwigAction = SCons.Action.Action('$SWIGCOM', '$SWIGCOMSTR') -def swigSuffixEmitter(env, source): +def swigSuffixEmitter(env, source) -> str: if '-c++' in SCons.Util.CLVar(env.subst("$SWIGFLAGS", source=source)): return '$SWIGCXXFILESUFFIX' else: @@ -78,7 +78,7 @@ def _find_modules(src): directors = directors or 'directors' in m[0] return mnames, directors -def _add_director_header_targets(target, env): +def _add_director_header_targets(target, env) -> None: # Directors only work with C++ code, not C suffix = env.subst(env['SWIGCXXFILESUFFIX']) # For each file ending in SWIGCXXFILESUFFIX, add a new target director @@ -158,7 +158,7 @@ def _get_swig_version(env, swig): return version -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for swig to an Environment.""" c_file, cxx_file = SCons.Tool.createCFileBuilders(env) diff --git a/SCons/Tool/tar.py b/SCons/Tool/tar.py index 25937811c..ba7f45cb4 100644 --- a/SCons/Tool/tar.py +++ b/SCons/Tool/tar.py @@ -50,7 +50,7 @@ TarBuilder = SCons.Builder.Builder(action = TarAction, multi = 1) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for tar to an Environment.""" try: bld = env['BUILDERS']['Tar'] diff --git a/SCons/Tool/tex.py b/SCons/Tool/tex.py index 0a688f58a..72526c32e 100644 --- a/SCons/Tool/tex.py +++ b/SCons/Tool/tex.py @@ -149,11 +149,11 @@ _null = SCons.Scanner.LaTeX._null modify_env_var = SCons.Scanner.LaTeX.modify_env_var -def check_file_error_message(utility, filename='log'): +def check_file_error_message(utility, filename: str='log') -> None: msg = '%s returned an error, check the %s file\n' % (utility, filename) sys.stdout.write(msg) -def FindFile(name,suffixes,paths,env,requireExt=False): +def FindFile(name,suffixes,paths,env,requireExt: bool=False): if requireExt: name,ext = SCons.Util.splitext(name) # if the user gave an extension use it. @@ -253,7 +253,7 @@ def InternalLaTeXAuxAction(XXXLaTeXAction, target = None, source= None, env=None # .aux files already processed by BibTex already_bibtexed = [] - def check_content_hash(filenode, suffix): + def check_content_hash(filenode, suffix) -> bool: """ Routine to update content hash and compare """ @@ -840,7 +840,7 @@ def tex_emitter_core(target, source, env, graphics_extensions): TeXLaTeXAction = None -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for TeX to an Environment.""" global TeXLaTeXAction @@ -859,7 +859,7 @@ def generate(env): bld.add_action('.tex', TeXLaTeXAction) bld.add_emitter('.tex', tex_eps_emitter) -def generate_darwin(env): +def generate_darwin(env) -> None: try: environ = env['ENV'] except KeyError: @@ -874,7 +874,7 @@ def generate_darwin(env): if ospath: env.AppendENVPath('PATH', ospath) -def generate_common(env): +def generate_common(env) -> None: """Add internal Builders and construction variables for LaTeX to an Environment.""" # Add OSX system paths so TeX tools can be found diff --git a/SCons/Tool/textfile.py b/SCons/Tool/textfile.py index 0ec31d8f7..9d98644c4 100644 --- a/SCons/Tool/textfile.py +++ b/SCons/Tool/textfile.py @@ -137,11 +137,11 @@ def _action(target, source, env): target_file.close() -def _strfunc(target, source, env): +def _strfunc(target, source, env) -> str: return "Creating '%s'" % target[0] -def _convert_list_R(newlist, sources): +def _convert_list_R(newlist, sources) -> None: for elem in sources: if is_Sequence(elem): _convert_list_R(newlist, elem) @@ -181,7 +181,7 @@ _subst_builder = SCons.Builder.Builder( ) -def generate(env): +def generate(env) -> None: env['LINESEPARATOR'] = LINESEP # os.linesep env['BUILDERS']['Textfile'] = _text_builder env['TEXTFILEPREFIX'] = '' @@ -192,7 +192,7 @@ def generate(env): env['FILE_ENCODING'] = env.get('FILE_ENCODING', 'utf-8') -def exists(env): +def exists(env) -> int: return 1 # Local Variables: diff --git a/SCons/Tool/tlib.py b/SCons/Tool/tlib.py index 33adb576b..8b0e6ddad 100644 --- a/SCons/Tool/tlib.py +++ b/SCons/Tool/tlib.py @@ -33,7 +33,7 @@ import SCons.Tool import SCons.Tool.bcc32 import SCons.Util -def generate(env): +def generate(env) -> None: SCons.Tool.bcc32.findIt('tlib', env) """Add Builders and construction variables for ar to an Environment.""" SCons.Tool.createStaticLibBuilder(env) diff --git a/SCons/Tool/wix.py b/SCons/Tool/wix.py index 04136ce8e..617abf273 100644 --- a/SCons/Tool/wix.py +++ b/SCons/Tool/wix.py @@ -36,7 +36,7 @@ import SCons.Builder import SCons.Action import os -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for WiX to an Environment.""" if not exists(env): return diff --git a/SCons/Tool/wixTests.py b/SCons/Tool/wixTests.py index 5b255d932..26b2295b8 100644 --- a/SCons/Tool/wixTests.py +++ b/SCons/Tool/wixTests.py @@ -41,7 +41,7 @@ test.write('light.exe', 'rem this is light') os.environ['PATH'] += os.pathsep + test.workdir class WixTestCase(unittest.TestCase): - def test_vars(self): + def test_vars(self) -> None: """Test that WiX tool adds vars""" env = Environment(tools=['wix']) assert env['WIXCANDLE'] is not None diff --git a/SCons/Tool/xgettext.py b/SCons/Tool/xgettext.py index ed76e2552..f04c6a6a1 100644 --- a/SCons/Tool/xgettext.py +++ b/SCons/Tool/xgettext.py @@ -51,7 +51,7 @@ class _CmdRunner: variables. It also provides `strfunction()` method, which shall be used by scons Action objects to print command string. """ - def __init__(self, command, commandstr=None): + def __init__(self, command, commandstr=None) -> None: self.out = None self.err = None self.status = None @@ -169,7 +169,7 @@ class _POTBuilder(BuilderBase): return BuilderBase._execute(self, env, target, source, *args) -def _scan_xgettext_from_files(target, source, env, files=None, path=None): +def _scan_xgettext_from_files(target, source, env, files=None, path=None) -> int: """ Parses `POTFILES.in`-like file and returns list of extracted file names. """ if files is None: @@ -257,7 +257,7 @@ def _POTUpdateBuilder(env, **kw): return _POTBuilder(**kw) -def generate(env, **kw): +def generate(env, **kw) -> None: """ Generate `xgettext` tool """ if sys.platform == 'win32': diff --git a/SCons/Tool/yacc.py b/SCons/Tool/yacc.py index 42ef1db03..67ecd8678 100644 --- a/SCons/Tool/yacc.py +++ b/SCons/Tool/yacc.py @@ -125,7 +125,7 @@ def yyEmitter(target, source, env) -> tuple: return _yaccEmitter(target, source, env, ['.yy'], '$YACCHXXFILESUFFIX') -def get_yacc_path(env, append_paths=False) -> Optional[str]: +def get_yacc_path(env, append_paths: bool=False) -> Optional[str]: """ Returns the path to the yacc tool, searching several possible names. diff --git a/SCons/Tool/zip.py b/SCons/Tool/zip.py index f3d38fe7a..4c04afceb 100644 --- a/SCons/Tool/zip.py +++ b/SCons/Tool/zip.py @@ -57,7 +57,7 @@ def _create_zipinfo_for_file(fname, arcname, date_time, compression): return zinfo -def zip_builder(target, source, env): +def zip_builder(target, source, env) -> None: compression = env.get('ZIPCOMPRESSION', zipfile.ZIP_STORED) zip_root = str(env.get('ZIPROOT', '')) date_time = env.get('ZIP_OVERRIDE_TIMESTAMP') @@ -94,7 +94,7 @@ ZipBuilder = SCons.Builder.Builder(action=SCons.Action.Action('$ZIPCOM', '$ZIPCO multi=1) -def generate(env): +def generate(env) -> None: """Add Builders and construction variables for zip to an Environment.""" try: bld = env['BUILDERS']['Zip'] @@ -110,7 +110,7 @@ def generate(env): env['ZIPROOT'] = SCons.Util.CLVar('') -def exists(env): +def exists(env) -> bool: return True # Local Variables: diff --git a/SCons/Util/__init__.py b/SCons/Util/__init__.py index 2760298b5..655c5adc8 100644 --- a/SCons/Util/__init__.py +++ b/SCons/Util/__init__.py @@ -183,10 +183,10 @@ class NodeList(UserList): ['foo', 'bar'] """ - def __bool__(self): + def __bool__(self) -> bool: return bool(self.data) - def __str__(self): + def __str__(self) -> str: return ' '.join(map(str, self.data)) def __iter__(self): @@ -214,7 +214,7 @@ class DisplayEngine: print_it = True - def __call__(self, text, append_newline=1): + def __call__(self, text, append_newline: int=1) -> None: if not self.print_it: return @@ -231,14 +231,14 @@ class DisplayEngine: with suppress(IOError): sys.stdout.write(str(text)) - def set_mode(self, mode): + def set_mode(self, mode) -> None: self.print_it = mode display = DisplayEngine() # TODO: W0102: Dangerous default value [] as argument (dangerous-default-value) -def render_tree(root, child_func, prune=0, margin=[0], visited=None) -> str: +def render_tree(root, child_func, prune: int=0, margin=[0], visited=None) -> str: """Render a tree of nodes into an ASCII tree view. Args: @@ -302,8 +302,8 @@ BOX_HORIZ_DOWN = chr(0x252c) # '┬' def print_tree( root, child_func, - prune=0, - showtags=False, + prune: int=0, + showtags: bool=False, margin=[0], visited=None, lastChild: bool = False, @@ -432,7 +432,7 @@ def do_flatten( isinstance=isinstance, StringTypes=StringTypes, SequenceTypes=SequenceTypes, -): # pylint: disable=redefined-outer-name,redefined-builtin +) -> None: # pylint: disable=redefined-outer-name,redefined-builtin for item in sequence: if isinstance(item, StringTypes) or not isinstance(item, SequenceTypes): result.append(item) @@ -564,7 +564,7 @@ class Proxy: __str__ = Delegate('__str__') """ - def __init__(self, subject): + def __init__(self, subject) -> None: """Wrap an object as a Proxy object""" self._subject = subject @@ -593,7 +593,7 @@ class Delegate: class Foo(Proxy): __str__ = Delegate('__str__') """ - def __init__(self, attribute): + def __init__(self, attribute) -> None: self.attribute = attribute def __get__(self, obj, cls): @@ -858,7 +858,7 @@ class CLVar(UserList): 6 ['--some', '--opts', 'and', 'args', 'strips', 'spaces'] """ - def __init__(self, initlist=None): + def __init__(self, initlist=None) -> None: super().__init__(Split(initlist if initlist is not None else [])) def __add__(self, other): @@ -870,7 +870,7 @@ class CLVar(UserList): def __iadd__(self, other): return super().__iadd__(CLVar(other)) - def __str__(self): + def __str__(self) -> str: # Some cases the data can contain Nodes, so make sure they # processed to string before handing them over to join. return ' '.join([str(d) for d in self.data]) @@ -923,7 +923,7 @@ else: return os.path.normcase(s1) != os.path.normcase(s2) -def adjustixes(fname, pre, suf, ensure_suffix=False) -> str: +def adjustixes(fname, pre, suf, ensure_suffix: bool=False) -> str: """Adjust filename prefixes and suffixes as needed. Add `prefix` to `fname` if specified. @@ -1050,7 +1050,7 @@ class LogicalLines: Allows us to read all "logical" lines at once from a given file object. """ - def __init__(self, fileobj): + def __init__(self, fileobj) -> None: self.fileobj = fileobj def readlines(self): @@ -1064,16 +1064,16 @@ class UniqueList(UserList): up on access by those methods which need to act on a unique list to be correct. That means things like "in" don't have to eat the uniquing time. """ - def __init__(self, initlist=None): + def __init__(self, initlist=None) -> None: super().__init__(initlist) self.unique = True - def __make_unique(self): + def __make_unique(self) -> None: if not self.unique: self.data = uniquer_hashables(self.data) self.unique = True - def __repr__(self): + def __repr__(self) -> str: self.__make_unique() return super().__repr__() @@ -1103,7 +1103,7 @@ class UniqueList(UserList): # __contains__ doesn't need to worry about uniquing, inherit - def __len__(self): + def __len__(self) -> int: self.__make_unique() return super().__len__() @@ -1111,7 +1111,7 @@ class UniqueList(UserList): self.__make_unique() return super().__getitem__(i) - def __setitem__(self, i, item): + def __setitem__(self, i, item) -> None: super().__setitem__(i, item) self.unique = False @@ -1147,11 +1147,11 @@ class UniqueList(UserList): result.unique = False return result - def append(self, item): + def append(self, item) -> None: super().append(item) self.unique = False - def insert(self, i, item): + def insert(self, i, item) -> None: super().insert(i, item) self.unique = False @@ -1163,7 +1163,7 @@ class UniqueList(UserList): self.__make_unique() return super().index(item, *args) - def reverse(self): + def reverse(self) -> None: self.__make_unique() super().reverse() @@ -1172,7 +1172,7 @@ class UniqueList(UserList): self.__make_unique() return super().sort(*args, **kwds) - def extend(self, other): + def extend(self, other) -> None: super().extend(other) self.unique = False @@ -1182,10 +1182,10 @@ class Unbuffered: Delegates everything else to the wrapped object. """ - def __init__(self, file): + def __init__(self, file) -> None: self.file = file - def write(self, arg): + def write(self, arg) -> None: # Stdout might be connected to a pipe that has been closed # by now. The most likely reason for the pipe being closed # is that the user has press ctrl-c. It this is the case, @@ -1197,7 +1197,7 @@ class Unbuffered: self.file.write(arg) self.file.flush() - def writelines(self, arg): + def writelines(self, arg) -> None: with suppress(IOError): self.file.writelines(arg) self.file.flush() @@ -1244,7 +1244,7 @@ def print_time(): return print_time -def wait_for_process_to_die(pid): +def wait_for_process_to_die(pid) -> None: """ Wait for specified process to die, or alternatively kill it NOTE: This function operates best with psutil pypi package @@ -1278,7 +1278,7 @@ def wait_for_process_to_die(pid): # From: https://stackoverflow.com/questions/1741972/how-to-use-different-formatters-with-the-same-logging-handler-in-python class DispatchingFormatter(Formatter): - def __init__(self, formatters, default_formatter): + def __init__(self, formatters, default_formatter) -> None: self._formatters = formatters self._default_formatter = default_formatter diff --git a/SCons/Util/envs.py b/SCons/Util/envs.py index 963c963a8..64e728a8c 100644 --- a/SCons/Util/envs.py +++ b/SCons/Util/envs.py @@ -16,7 +16,7 @@ from .types import is_List, is_Tuple, is_String def PrependPath( - oldpath, newpath, sep=os.pathsep, delete_existing=True, canonicalize=None + oldpath, newpath, sep=os.pathsep, delete_existing: bool=True, canonicalize=None ) -> Union[list, str]: """Prepend *newpath* path elements to *oldpath*. @@ -102,7 +102,7 @@ def PrependPath( def AppendPath( - oldpath, newpath, sep=os.pathsep, delete_existing=True, canonicalize=None + oldpath, newpath, sep=os.pathsep, delete_existing: bool=True, canonicalize=None ) -> Union[list, str]: """Append *newpath* path elements to *oldpath*. @@ -187,7 +187,7 @@ def AppendPath( return sep.join(paths) -def AddPathIfNotExists(env_dict, key, path, sep=os.pathsep): +def AddPathIfNotExists(env_dict, key, path, sep=os.pathsep) -> None: """Add a path element to a construction variable. `key` is looked up in `env_dict`, and `path` is added to it if it @@ -229,7 +229,7 @@ class MethodWrapper: a new underlying object being copied (without which we wouldn't need to save that info). """ - def __init__(self, obj, method, name=None): + def __init__(self, obj, method, name=None) -> None: if name is None: name = method.__name__ self.object = obj @@ -265,7 +265,7 @@ class MethodWrapper: # is not needed, the remaining bit is now used inline in AddMethod. -def AddMethod(obj, function, name=None): +def AddMethod(obj, function, name=None) -> None: """Add a method to an object. Adds *function* to *obj* if *obj* is a class object. diff --git a/SCons/Util/hashes.py b/SCons/Util/hashes.py index b97cd4d07..e14da012a 100644 --- a/SCons/Util/hashes.py +++ b/SCons/Util/hashes.py @@ -314,7 +314,7 @@ def hash_signature(s, hash_format=None): return m.hexdigest() -def hash_file_signature(fname, chunksize=65536, hash_format=None): +def hash_file_signature(fname, chunksize: int=65536, hash_format=None): """ Generate the md5 signature of a file @@ -358,7 +358,7 @@ def hash_collect(signatures, hash_format=None): _MD5_WARNING_SHOWN = False -def _show_md5_warning(function_name): +def _show_md5_warning(function_name) -> None: """Shows a deprecation warning for various MD5 functions.""" global _MD5_WARNING_SHOWN @@ -380,7 +380,7 @@ def MD5signature(s): return hash_signature(s) -def MD5filesignature(fname, chunksize=65536): +def MD5filesignature(fname, chunksize: int=65536): """Deprecated. Use :func:`hash_file_signature` instead.""" _show_md5_warning("MD5filesignature") diff --git a/SCons/Util/types.py b/SCons/Util/types.py index 2071217e9..44aae5f33 100644 --- a/SCons/Util/types.py +++ b/SCons/Util/types.py @@ -115,16 +115,16 @@ class Null: cls._instance = super(Null, cls).__new__(cls, *args, **kwargs) return cls._instance - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: pass def __call__(self, *args, **kwargs): return self - def __repr__(self): + def __repr__(self) -> str: return f"Null(0x{id(self):08X})" - def __bool__(self): + def __bool__(self) -> bool: return False def __getattr__(self, name): @@ -140,7 +140,7 @@ class Null: class NullSeq(Null): """A Null object that can also be iterated over.""" - def __len__(self): + def __len__(self) -> int: return 0 def __iter__(self): @@ -245,7 +245,7 @@ def to_String_for_signature( # pylint: disable=redefined-outer-name,redefined-b return f() -def get_env_bool(env, name, default=False) -> bool: +def get_env_bool(env, name, default: bool=False) -> bool: """Convert a construction variable to bool. If the value of *name* in *env* is 'true', 'yes', 'y', 'on' (case @@ -279,7 +279,7 @@ def get_env_bool(env, name, default=False) -> bool: return default -def get_os_env_bool(name, default=False) -> bool: +def get_os_env_bool(name, default: bool=False) -> bool: """Convert an environment variable to bool. Conversion is the same as for :func:`get_env_bool`. diff --git a/SCons/UtilTests.py b/SCons/UtilTests.py index 785caf72c..860724e40 100644 --- a/SCons/UtilTests.py +++ b/SCons/UtilTests.py @@ -84,15 +84,15 @@ from SCons.Util.hashes import ( class OutBuffer: - def __init__(self): + def __init__(self) -> None: self.buffer = "" - def write(self, str): + def write(self, str) -> None: self.buffer = self.buffer + str class dictifyTestCase(unittest.TestCase): - def test_dictify(self): + def test_dictify(self) -> None: """Test the dictify() function""" r = dictify(['a', 'b', 'c'], [1, 2, 3]) assert r == {'a': 1, 'b': 2, 'c': 3}, r @@ -105,45 +105,45 @@ class dictifyTestCase(unittest.TestCase): class UtilTestCase(unittest.TestCase): - def test_splitext(self): + def test_splitext(self) -> None: assert splitext('foo') == ('foo', '') assert splitext('foo.bar') == ('foo', '.bar') assert splitext(os.path.join('foo.bar', 'blat')) == (os.path.join('foo.bar', 'blat'), '') class Node: - def __init__(self, name, children=[]): + def __init__(self, name, children=[]) -> None: self.children = children self.name = name self.nocache = None - def __str__(self): + def __str__(self) -> str: return self.name - def exists(self): + def exists(self) -> int: return 1 - def rexists(self): + def rexists(self) -> int: return 1 - def has_builder(self): + def has_builder(self) -> int: return 1 - def has_explicit_builder(self): + def has_explicit_builder(self) -> int: return 1 - def side_effect(self): + def side_effect(self) -> int: return 1 - def precious(self): + def precious(self) -> int: return 1 - def always_build(self): + def always_build(self) -> int: return 1 - def is_up_to_date(self): + def is_up_to_date(self) -> int: return 1 - def noclean(self): + def noclean(self) -> int: return 1 def tree_case_1(self): @@ -174,7 +174,7 @@ class UtilTestCase(unittest.TestCase): return foo, expect, withtags - def tree_case_2(self, prune=1): + def tree_case_2(self, prune: int=1): """Fixture for the render_tree() and print_tree() tests.""" types_h = self.Node('types.h') @@ -209,7 +209,7 @@ class UtilTestCase(unittest.TestCase): return blat_o, expect, withtags - def test_render_tree(self): + def test_render_tree(self) -> None: """Test the render_tree() function""" def get_children(node): @@ -230,7 +230,7 @@ class UtilTestCase(unittest.TestCase): actual = render_tree(node, get_children, 1) assert expect == actual, (expect, actual) - def test_print_tree(self): + def test_print_tree(self) -> None: """Test the print_tree() function""" def get_children(node): @@ -290,7 +290,7 @@ class UtilTestCase(unittest.TestCase): finally: sys.stdout = save_stdout - def test_is_Dict(self): + def test_is_Dict(self) -> None: assert is_Dict({}) assert is_Dict(UserDict()) try: @@ -305,7 +305,7 @@ class UtilTestCase(unittest.TestCase): assert not is_Dict("") - def test_is_List(self): + def test_is_List(self) -> None: assert is_List([]) assert is_List(UserList()) try: @@ -319,7 +319,7 @@ class UtilTestCase(unittest.TestCase): assert not is_List({}) assert not is_List("") - def test_is_String(self): + def test_is_String(self) -> None: assert is_String("") assert is_String(UserString('')) try: @@ -333,7 +333,7 @@ class UtilTestCase(unittest.TestCase): assert not is_String([]) assert not is_String(()) - def test_is_Tuple(self): + def test_is_Tuple(self) -> None: assert is_Tuple(()) try: class mytuple(tuple): @@ -346,13 +346,13 @@ class UtilTestCase(unittest.TestCase): assert not is_Tuple({}) assert not is_Tuple("") - def test_to_Bytes(self): + def test_to_Bytes(self) -> None: """ Test the to_Bytes method""" self.assertEqual(to_bytes('Hello'), bytearray('Hello', 'utf-8'), "Check that to_bytes creates byte array when presented with non byte string.") - def test_to_String(self): + def test_to_String(self) -> None: """Test the to_String() method.""" assert to_String(1) == "1", to_String(1) assert to_String([1, 2, 3]) == str([1, 2, 3]), to_String([1, 2, 3]) @@ -374,7 +374,7 @@ class UtilTestCase(unittest.TestCase): assert to_String(s2) == 'foo', s2 - def test_WhereIs(self): + def test_WhereIs(self) -> None: test = TestCmd.TestCmd(workdir='') sub1_xxx_exe = test.workpath('sub1', 'xxx.exe') @@ -454,7 +454,7 @@ class UtilTestCase(unittest.TestCase): finally: os.environ['PATH'] = env_path - def test_get_env_var(self): + def test_get_env_var(self) -> None: """Testing get_environment_var().""" assert get_environment_var("$FOO") == "FOO", get_environment_var("$FOO") assert get_environment_var("${BAR}") == "BAR", get_environment_var("${BAR}") @@ -467,21 +467,21 @@ class UtilTestCase(unittest.TestCase): assert get_environment_var("${some('complex expression')}") is None, get_environment_var( "${some('complex expression')}") - def test_Proxy(self): + def test_Proxy(self) -> None: """Test generic Proxy class.""" class Subject: - def foo(self): + def foo(self) -> int: return 1 - def bar(self): + def bar(self) -> int: return 2 s = Subject() s.baz = 3 class ProxyTest(Proxy): - def bar(self): + def bar(self) -> int: return 4 p = ProxyTest(s) @@ -496,7 +496,7 @@ class UtilTestCase(unittest.TestCase): assert p.baz == 5, p.baz assert p.get() == s, p.get() - def test_display(self): + def test_display(self) -> None: old_stdout = sys.stdout sys.stdout = OutBuffer() display("line1") @@ -512,7 +512,7 @@ class UtilTestCase(unittest.TestCase): assert sys.stdout.buffer == "line1\nline3\nline4\n" sys.stdout = old_stdout - def test_get_native_path(self): + def test_get_native_path(self) -> None: """Test the get_native_path() function.""" import tempfile f, filename = tempfile.mkstemp(text=True) @@ -529,7 +529,7 @@ class UtilTestCase(unittest.TestCase): except OSError: pass - def test_PrependPath(self): + def test_PrependPath(self) -> None: """Test prepending to a path""" p1 = r'C:\dir\num\one;C:\dir\num\two' p2 = r'C:\mydir\num\one;C:\mydir\num\two' @@ -547,7 +547,7 @@ class UtilTestCase(unittest.TestCase): p3 = PrependPath(p3, r'C:\dir\num\two;C:\dir\num\three;C:\dir\num\two', sep=';') assert p3 == r'C:\dir\num\two;C:\dir\num\three;C:\dir\num\one', p3 - def test_AppendPath(self): + def test_AppendPath(self) -> None: """Test appending to a path.""" p1 = r'C:\dir\num\one;C:\dir\num\two' p2 = r'C:\mydir\num\one;C:\mydir\num\two' @@ -565,7 +565,7 @@ class UtilTestCase(unittest.TestCase): p3 = AppendPath(p3, r'C:\dir\num\two;C:\dir\num\three;C:\dir\num\two', sep=';') assert p3 == r'C:\dir\num\one;C:\dir\num\three;C:\dir\num\two', p3 - def test_PrependPathPreserveOld(self): + def test_PrependPathPreserveOld(self) -> None: """Test prepending to a path while preserving old paths""" p1 = r'C:\dir\num\one;C:\dir\num\two' # have to include the pathsep here so that the test will work on UNIX too. @@ -573,7 +573,7 @@ class UtilTestCase(unittest.TestCase): p1 = PrependPath(p1, r'C:\dir\num\three', sep=';') assert p1 == r'C:\dir\num\three;C:\dir\num\one;C:\dir\num\two', p1 - def test_AppendPathPreserveOld(self): + def test_AppendPathPreserveOld(self) -> None: """Test appending to a path while preserving old paths""" p1 = r'C:\dir\num\one;C:\dir\num\two' # have to include the pathsep here so that the test will work on UNIX too. @@ -581,7 +581,7 @@ class UtilTestCase(unittest.TestCase): p1 = AppendPath(p1, r'C:\dir\num\three', sep=';') assert p1 == r'C:\dir\num\one;C:\dir\num\two;C:\dir\num\three', p1 - def test_addPathIfNotExists(self): + def test_addPathIfNotExists(self) -> None: """Test the AddPathIfNotExists() function""" env_dict = {'FOO': os.path.normpath('/foo/bar') + os.pathsep + \ os.path.normpath('/baz/blat'), @@ -605,7 +605,7 @@ class UtilTestCase(unittest.TestCase): os.path.normpath('/foo/bar'), os.path.normpath('/baz/blat')], env_dict['BLAT'] - def test_CLVar(self): + def test_CLVar(self) -> None: """Test the command-line construction variable class""" # the default value should be an empty list @@ -728,14 +728,14 @@ class UtilTestCase(unittest.TestCase): assert str(f) == 'aa bb cc dd', str(f) - def test_Selector(self): + def test_Selector(self) -> None: """Test the Selector class""" class MyNode: - def __init__(self, name): + def __init__(self, name) -> None: self.name = name - def __str__(self): + def __str__(self) -> str: return self.name def get_suffix(self): @@ -782,7 +782,7 @@ class UtilTestCase(unittest.TestCase): ret = s(env, [MyNode('bar.g')]) assert ret == 'GGG', ret - def test_adjustixes(self): + def test_adjustixes(self) -> None: """Test the adjustixes() function""" r = adjustixes('file', 'pre-', '-suf') assert r == 'pre-file-suf', r @@ -802,22 +802,22 @@ class UtilTestCase(unittest.TestCase): r = adjustixes('PREFIX', 'PREFIX', 'SUFFIX') assert r == 'PREFIXPREFIXSUFFIX', "Failed handling when filename = PREFIX [r='%s']" % r - def test_containsAny(self): + def test_containsAny(self) -> None: """Test the containsAny() function""" assert containsAny('*.py', '*?[]') assert not containsAny('file.txt', '*?[]') - def test_containsAll(self): + def test_containsAll(self) -> None: """Test the containsAll() function""" assert containsAll('43221', '123') assert not containsAll('134', '123') - def test_containsOnly(self): + def test_containsOnly(self) -> None: """Test the containsOnly() function""" assert containsOnly('.83', '0123456789.') assert not containsOnly('43221', '123') - def test_LogicalLines(self): + def test_LogicalLines(self) -> None: """Test the LogicalLines class""" content = """ foo \\ @@ -838,7 +838,7 @@ bling 'bling\n', ], lines - def test_intern(self): + def test_intern(self) -> None: s1 = silent_intern("spam") s3 = silent_intern(42) s4 = silent_intern("spam") @@ -847,7 +847,7 @@ bling class HashTestCase(unittest.TestCase): - def test_collect(self): + def test_collect(self) -> None: """Test collecting a list of signatures into a new signature value """ for algorithm, expected in { @@ -873,7 +873,7 @@ class HashTestCase(unittest.TestCase): assert expected[1] == hash_collect(s[0:2], hash_format=algorithm) assert expected[2] == hash_collect(s, hash_format=algorithm) - def test_MD5signature(self): + def test_MD5signature(self) -> None: """Test generating a signature""" for algorithm, expected in { 'md5': ('698d51a19d8a121ce581499d7b701668', @@ -900,7 +900,7 @@ class HashTestCase(unittest.TestCase): # with using OpenSSL. class FIPSHashTestCase(unittest.TestCase): - def __init__(self, *args, **kwargs): + def __init__(self, *args, **kwargs) -> None: super().__init__(*args, **kwargs) ############################### @@ -958,17 +958,17 @@ class FIPSHashTestCase(unittest.TestCase): self.sys_v4_8 = unittest.mock.Mock(version_info=v4_8) ############################### - def test_basic_failover_bad_hashlib_hash_init(self): + def test_basic_failover_bad_hashlib_hash_init(self) -> None: """Tests that if the hashing function is entirely missing from hashlib (hashlib returns None), the hash init function returns None""" assert _attempt_init_of_python_3_9_hash_object(None) is None - def test_basic_failover_bad_hashlib_hash_get(self): + def test_basic_failover_bad_hashlib_hash_get(self) -> None: """Tests that if the hashing function is entirely missing from hashlib (hashlib returns None), the hash get function returns None""" assert _attempt_get_hash_function("nonexist", self.no_algorithms) is None - def test_usedforsecurity_flag_behavior(self): + def test_usedforsecurity_flag_behavior(self) -> None: """Test usedforsecurity flag -> should be set to 'True' on older versions of python, and 'False' on Python >= 3.9""" for version, expected in { self.sys_v3_8: (True, 'md5'), @@ -977,7 +977,7 @@ class FIPSHashTestCase(unittest.TestCase): }.items(): assert _attempt_init_of_python_3_9_hash_object(self.fake_md5, version) == expected - def test_automatic_default_to_md5(self): + def test_automatic_default_to_md5(self) -> None: """Test automatic default to md5 even if sha1 available""" for version, expected in { self.sys_v3_8: (True, 'md5'), @@ -988,7 +988,7 @@ class FIPSHashTestCase(unittest.TestCase): set_hash_format(None, self.md5Default, version) assert _get_hash_object(None, self.md5Default, version) == expected - def test_automatic_default_to_sha256(self): + def test_automatic_default_to_sha256(self) -> None: """Test automatic default to sha256 if other algorithms available but throw""" for version, expected in { self.sys_v3_8: (True, 'sha256'), @@ -999,7 +999,7 @@ class FIPSHashTestCase(unittest.TestCase): set_hash_format(None, self.sha256Default, version) assert _get_hash_object(None, self.sha256Default, version) == expected - def test_automatic_default_to_sha1(self): + def test_automatic_default_to_sha1(self) -> None: """Test automatic default to sha1 if md5 is missing from hashlib entirely""" for version, expected in { self.sys_v3_8: (True, 'sha1'), @@ -1010,13 +1010,13 @@ class FIPSHashTestCase(unittest.TestCase): set_hash_format(None, self.sha1Default, version) assert _get_hash_object(None, self.sha1Default, version) == expected - def test_no_available_algorithms(self): + def test_no_available_algorithms(self) -> None: """expect exceptions on no available algorithms or when all algorithms throw""" self.assertRaises(SCons.Errors.SConsEnvironmentError, _set_allowed_viable_default_hashes, self.no_algorithms) self.assertRaises(SCons.Errors.SConsEnvironmentError, _set_allowed_viable_default_hashes, self.all_throw) self.assertRaises(SCons.Errors.SConsEnvironmentError, _set_allowed_viable_default_hashes, self.unsupported_algorithm) - def test_bad_algorithm_set_attempt(self): + def test_bad_algorithm_set_attempt(self) -> None: """expect exceptions on user setting an unsupported algorithm selections, either by host or by SCons""" # nonexistant hash algorithm, not supported by SCons @@ -1035,18 +1035,18 @@ class FIPSHashTestCase(unittest.TestCase): _set_allowed_viable_default_hashes(self.sha1Default) self.assertRaises(SCons.Errors.UserError, set_hash_format, 'unsupported', hashlib_used=self.unsupported_algorithm) - def tearDown(self): + def tearDown(self) -> None: """Return SCons back to the normal global state for the hashing functions.""" _set_allowed_viable_default_hashes(hashlib, sys) set_hash_format(None) class NodeListTestCase(unittest.TestCase): - def test_simple_attributes(self): + def test_simple_attributes(self) -> None: """Test simple attributes of a NodeList class""" class TestClass: - def __init__(self, name, child=None): + def __init__(self, name, child=None) -> None: self.child = child self.bar = name @@ -1059,11 +1059,11 @@ class NodeListTestCase(unittest.TestCase): assert nl[0:2].child.bar == ['t1child', 't2child'], \ nl[0:2].child.bar - def test_callable_attributes(self): + def test_callable_attributes(self) -> None: """Test callable attributes of a NodeList class""" class TestClass: - def __init__(self, name, child=None): + def __init__(self, name, child=None) -> None: self.child = child self.bar = name @@ -1097,12 +1097,12 @@ class NodeListTestCase(unittest.TestCase): class flattenTestCase(unittest.TestCase): - def test_scalar(self): + def test_scalar(self) -> None: """Test flattening a scalar""" result = flatten('xyz') self.assertEqual(result, ['xyz'], result) - def test_dictionary_values(self): + def test_dictionary_values(self) -> None: """Test flattening the dictionary values""" items = {"a": 1, "b": 2, "c": 3} result = flatten(items.values()) @@ -1112,14 +1112,14 @@ class flattenTestCase(unittest.TestCase): class OsEnviron: """Used to temporarily mock os.environ""" - def __init__(self, environ): + def __init__(self, environ) -> None: self._environ = environ - def start(self): + def start(self) -> None: self._stored = os.environ os.environ = self._environ - def stop(self): + def stop(self) -> None: os.environ = self._stored del self._stored @@ -1127,12 +1127,12 @@ class OsEnviron: self.start() return os.environ - def __exit__(self, *args): + def __exit__(self, *args) -> None: self.stop() class get_env_boolTestCase(unittest.TestCase): - def test_missing(self): + def test_missing(self) -> None: env = dict() var = get_env_bool(env, 'FOO') assert var is False, "var should be False, not %s" % repr(var) @@ -1140,7 +1140,7 @@ class get_env_boolTestCase(unittest.TestCase): var = get_env_bool(env, 'BAR') assert var is False, "var should be False, not %s" % repr(var) - def test_true(self): + def test_true(self) -> None: for foo in ['TRUE', 'True', 'true', 'YES', 'Yes', 'yes', 'Y', 'y', @@ -1150,7 +1150,7 @@ class get_env_boolTestCase(unittest.TestCase): var = get_env_bool(env, 'FOO') assert var is True, 'var should be True, not %s' % repr(var) - def test_false(self): + def test_false(self) -> None: for foo in ['FALSE', 'False', 'false', 'NO', 'No', 'no', 'N', 'n', @@ -1160,7 +1160,7 @@ class get_env_boolTestCase(unittest.TestCase): var = get_env_bool(env, 'FOO', True) assert var is False, 'var should be True, not %s' % repr(var) - def test_default(self): + def test_default(self) -> None: env = {'FOO': 'other'} var = get_env_bool(env, 'FOO', True) assert var is True, 'var should be True, not %s' % repr(var) @@ -1169,7 +1169,7 @@ class get_env_boolTestCase(unittest.TestCase): class get_os_env_boolTestCase(unittest.TestCase): - def test_missing(self): + def test_missing(self) -> None: with OsEnviron(dict()): var = get_os_env_bool('FOO') assert var is False, "var should be False, not %s" % repr(var) @@ -1177,7 +1177,7 @@ class get_os_env_boolTestCase(unittest.TestCase): var = get_os_env_bool('BAR') assert var is False, "var should be False, not %s" % repr(var) - def test_true(self): + def test_true(self) -> None: for foo in ['TRUE', 'True', 'true', 'YES', 'Yes', 'yes', 'Y', 'y', @@ -1187,7 +1187,7 @@ class get_os_env_boolTestCase(unittest.TestCase): var = get_os_env_bool('FOO') assert var is True, 'var should be True, not %s' % repr(var) - def test_false(self): + def test_false(self) -> None: for foo in ['FALSE', 'False', 'false', 'NO', 'No', 'no', 'N', 'n', @@ -1197,7 +1197,7 @@ class get_os_env_boolTestCase(unittest.TestCase): var = get_os_env_bool('FOO', True) assert var is False, 'var should be True, not %s' % repr(var) - def test_default(self): + def test_default(self) -> None: with OsEnviron({'FOO': 'other'}): var = get_os_env_bool('FOO', True) assert var is True, 'var should be True, not %s' % repr(var) diff --git a/SCons/Utilities/ConfigureCache.py b/SCons/Utilities/ConfigureCache.py index 67aac3c5b..f0de77b5d 100644 --- a/SCons/Utilities/ConfigureCache.py +++ b/SCons/Utilities/ConfigureCache.py @@ -38,7 +38,7 @@ import glob import json import os -def rearrange_cache_entries(current_prefix_len, new_prefix_len): +def rearrange_cache_entries(current_prefix_len, new_prefix_len) -> None: """Move cache files if prefix length changed. Move the existing cache files to new directories of the diff --git a/SCons/Utilities/sconsign.py b/SCons/Utilities/sconsign.py index ae6919693..c12782dd2 100644 --- a/SCons/Utilities/sconsign.py +++ b/SCons/Utilities/sconsign.py @@ -72,7 +72,7 @@ def my_import(mname): class Flagger: default_value = 1 - def __setitem__(self, item, value): + def __setitem__(self, item, value) -> None: self.__dict__[item] = value self.default_value = 0 @@ -201,7 +201,7 @@ def field(name, entry, verbose=Verbose): return val -def nodeinfo_raw(name, ninfo, prefix=""): +def nodeinfo_raw(name, ninfo, prefix: str=""): """ This just formats the dictionary, which we would normally use str() to do, except that we want the keys sorted for deterministic output. @@ -219,7 +219,7 @@ def nodeinfo_raw(name, ninfo, prefix=""): return name + ': {' + ', '.join(values) + '}' -def nodeinfo_cooked(name, ninfo, prefix=""): +def nodeinfo_cooked(name, ninfo, prefix: str=""): try: field_list = ninfo.field_list except AttributeError: @@ -239,7 +239,7 @@ def nodeinfo_cooked(name, ninfo, prefix=""): nodeinfo_string = nodeinfo_cooked -def printfield(name, entry, prefix=""): +def printfield(name, entry, prefix: str="") -> None: outlist = field("implicit", entry, 0) if outlist: if Verbose: @@ -253,7 +253,7 @@ def printfield(name, entry, prefix=""): print(" " + outact) -def printentries(entries, location): +def printentries(entries, location) -> None: if Print_Entries: for name in Print_Entries: try: @@ -282,7 +282,7 @@ def printentries(entries, location): class Do_SConsignDB: - def __init__(self, dbm_name, dbm): + def __init__(self, dbm_name, dbm) -> None: self.dbm_name = dbm_name self.dbm = dbm @@ -346,7 +346,7 @@ class Do_SConsignDB: self.printentries(dir, db[dir]) @staticmethod - def printentries(dir, val): + def printentries(dir, val) -> None: try: print('=== ' + dir + ':') except TypeError: @@ -376,7 +376,7 @@ def Do_SConsignDir(name): ############################################################################## -def main(): +def main() -> None: global Do_Call global nodeinfo_string global args diff --git a/SCons/Variables/BoolVariableTests.py b/SCons/Variables/BoolVariableTests.py index 868e7e085..9cf3ae137 100644 --- a/SCons/Variables/BoolVariableTests.py +++ b/SCons/Variables/BoolVariableTests.py @@ -27,7 +27,7 @@ import SCons.Errors import SCons.Variables class BoolVariableTestCase(unittest.TestCase): - def test_BoolVariable(self): + def test_BoolVariable(self) -> None: """Test BoolVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.BoolVariable('test', 'test option help', False)) @@ -39,7 +39,7 @@ class BoolVariableTestCase(unittest.TestCase): assert o.validator is not None, o.validator assert o.converter is not None, o.converter - def test_converter(self): + def test_converter(self) -> None: """Test the BoolVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.BoolVariable('test', 'test option help', False)) @@ -80,7 +80,7 @@ class BoolVariableTestCase(unittest.TestCase): caught = True assert caught, "did not catch expected ValueError for 'x'" - def test_validator(self): + def test_validator(self) -> None: """Test the BoolVariable validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.BoolVariable('test', 'test option help', False)) diff --git a/SCons/Variables/EnumVariable.py b/SCons/Variables/EnumVariable.py index e39eb0283..1a4f3fbde 100644 --- a/SCons/Variables/EnumVariable.py +++ b/SCons/Variables/EnumVariable.py @@ -56,7 +56,7 @@ def _validator(key, val, env, vals) -> None: 'Invalid value for option %s: %s. Valid values are: %s' % (key, val, vals)) -def EnumVariable(key, help, default, allowed_values, map={}, ignorecase=0) -> Tuple[str, str, str, Callable, Callable]: +def EnumVariable(key, help, default, allowed_values, map={}, ignorecase: int=0) -> Tuple[str, str, str, Callable, Callable]: """Return a tuple describing an enumaration SCons Variable. The input parameters describe an option with only certain values diff --git a/SCons/Variables/EnumVariableTests.py b/SCons/Variables/EnumVariableTests.py index 75bb54f1f..cc004f881 100644 --- a/SCons/Variables/EnumVariableTests.py +++ b/SCons/Variables/EnumVariableTests.py @@ -27,7 +27,7 @@ import SCons.Errors import SCons.Variables class EnumVariableTestCase(unittest.TestCase): - def test_EnumVariable(self): + def test_EnumVariable(self) -> None: """Test EnumVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, @@ -41,7 +41,7 @@ class EnumVariableTestCase(unittest.TestCase): assert o.validator is not None, o.validator assert o.converter is not None, o.converter - def test_converter(self): + def test_converter(self) -> None: """Test the EnumVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.EnumVariable('test', 'test option help', 0, @@ -127,7 +127,7 @@ class EnumVariableTestCase(unittest.TestCase): x = o2.converter(k) assert x == l[2], "o2 got %s, expected %s" % (x, l[2]) - def test_validator(self): + def test_validator(self) -> None: """Test the EnumVariable validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.EnumVariable('test0', 'test option help', 0, @@ -153,10 +153,10 @@ class EnumVariableTestCase(unittest.TestCase): o1 = opts.options[1] o2 = opts.options[2] - def valid(o, v): + def valid(o, v) -> None: o.validator('X', v, {}) - def invalid(o, v): + def invalid(o, v) -> None: caught = None try: o.validator('X', v, {}) diff --git a/SCons/Variables/ListVariable.py b/SCons/Variables/ListVariable.py index 7bd6053d0..bfa48f5eb 100644 --- a/SCons/Variables/ListVariable.py +++ b/SCons/Variables/ListVariable.py @@ -61,7 +61,7 @@ __all__ = ['ListVariable',] class _ListVariable(collections.UserList): - def __init__(self, initlist=None, allowedElems=None): + def __init__(self, initlist=None, allowedElems=None) -> None: if initlist is None: initlist = [] if allowedElems is None: @@ -87,7 +87,7 @@ class _ListVariable(collections.UserList): def __lt__(self, other): raise NotImplementedError - def __str__(self): + def __str__(self) -> str: if not len(self): return 'none' self.data.sort() diff --git a/SCons/Variables/ListVariableTests.py b/SCons/Variables/ListVariableTests.py index c73cef326..172a54ff0 100644 --- a/SCons/Variables/ListVariableTests.py +++ b/SCons/Variables/ListVariableTests.py @@ -28,7 +28,7 @@ import SCons.Errors import SCons.Variables class ListVariableTestCase(unittest.TestCase): - def test_ListVariable(self): + def test_ListVariable(self) -> None: """Test ListVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', @@ -49,7 +49,7 @@ class ListVariableTestCase(unittest.TestCase): o = opts.options[0] assert o.default == 'one,three' - def test_converter(self): + def test_converter(self) -> None: """Test the ListVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', @@ -108,7 +108,7 @@ class ListVariableTestCase(unittest.TestCase): caught = 1 assert caught, "did not catch expected ValueError" - def test_copy(self): + def test_copy(self) -> None: """Test copying a ListVariable like an Environment would""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.ListVariable('test', 'test option help', 'all', diff --git a/SCons/Variables/PackageVariableTests.py b/SCons/Variables/PackageVariableTests.py index 988fbe01d..ad5ba0612 100644 --- a/SCons/Variables/PackageVariableTests.py +++ b/SCons/Variables/PackageVariableTests.py @@ -29,7 +29,7 @@ import SCons.Variables import TestCmd class PackageVariableTestCase(unittest.TestCase): - def test_PackageVariable(self): + def test_PackageVariable(self) -> None: """Test PackageVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) @@ -41,7 +41,7 @@ class PackageVariableTestCase(unittest.TestCase): assert o.validator is not None, o.validator assert o.converter is not None, o.converter - def test_converter(self): + def test_converter(self) -> None: """Test the PackageVariable converter""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) @@ -82,7 +82,7 @@ class PackageVariableTestCase(unittest.TestCase): x = o.converter(str(False)) assert not x, "converter returned a string when given str(False)" - def test_validator(self): + def test_validator(self) -> None: """Test the PackageVariable validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PackageVariable('test', 'test option help', '/default/path')) diff --git a/SCons/Variables/PathVariableTests.py b/SCons/Variables/PathVariableTests.py index a9aa8f035..aacfc9ea7 100644 --- a/SCons/Variables/PathVariableTests.py +++ b/SCons/Variables/PathVariableTests.py @@ -30,7 +30,7 @@ import SCons.Variables import TestCmd class PathVariableTestCase(unittest.TestCase): - def test_PathVariable(self): + def test_PathVariable(self) -> None: """Test PathVariable creation""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PathVariable('test', @@ -164,7 +164,7 @@ class PathVariableTestCase(unittest.TestCase): except: raise Exception("did not catch expected UserError") - def test_PathAccept(self): + def test_PathAccept(self) -> None: """Test the PathAccept validator""" opts = SCons.Variables.Variables() opts.Add(SCons.Variables.PathVariable('test', diff --git a/SCons/Variables/VariablesTests.py b/SCons/Variables/VariablesTests.py index 4672cdd8a..fcc1e1417 100644 --- a/SCons/Variables/VariablesTests.py +++ b/SCons/Variables/VariablesTests.py @@ -32,24 +32,24 @@ from SCons.Util import cmp class Environment: - def __init__(self): + def __init__(self) -> None: self.dict = {} def subst(self, x): return SCons.Subst.scons_subst(x, self, gvars=self.dict) - def __setitem__(self, key, value): + def __setitem__(self, key, value) -> None: self.dict[key] = value def __getitem__(self, key): return self.dict[key] - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self.dict -def check(key, value, env): +def check(key, value, env) -> None: assert int(value) == 6 * 9, "key %s = %s" % (key, repr(value)) # Check saved option file by executing and comparing against # the expected dictionary -def checkSave(file, expected): +def checkSave(file, expected) -> None: gdict = {} ldict = {} with open(file, 'r') as f: @@ -59,7 +59,7 @@ def checkSave(file, expected): class VariablesTestCase(unittest.TestCase): - def test_keys(self): + def test_keys(self) -> None: """Test the Variables.keys() method""" opts = SCons.Variables.Variables() @@ -72,7 +72,7 @@ class VariablesTestCase(unittest.TestCase): keys = list(opts.keys()) assert keys == ['VAR1', 'VAR2'], keys - def test_Add(self): + def test_Add(self) -> None: """Test adding to a Variables object""" opts = SCons.Variables.Variables() @@ -96,7 +96,7 @@ class VariablesTestCase(unittest.TestCase): assert o.default == "42" o.validator(o.key, o.converter(o.default), {}) - def test_it(var, opts=opts): + def test_it(var, opts=opts) -> None: exc_caught = None try: opts.Add(var) @@ -107,7 +107,7 @@ class VariablesTestCase(unittest.TestCase): test_it('foo-bar') test_it('foo.bar') - def test_AddVariables(self): + def test_AddVariables(self) -> None: """Test adding a list of options to a Variables object""" opts = SCons.Variables.Variables() @@ -131,7 +131,7 @@ class VariablesTestCase(unittest.TestCase): assert o.default == "42", o.default o.validator(o.key, o.converter(o.default), {}) - def test_Update(self): + def test_Update(self) -> None: """Test updating an Environment""" # Test that a default value is validated correctly. @@ -270,7 +270,7 @@ class VariablesTestCase(unittest.TestCase): opts.Update(env, {}) assert 'ANSWER' not in env - def test_noaggregation(self): + def test_noaggregation(self) -> None: """Test that the 'files' and 'args' attributes of the Variables class don't aggregate entries from one instance to another. This used to be a bug in SCons version 2.4.1 and earlier. @@ -286,7 +286,7 @@ class VariablesTestCase(unittest.TestCase): assert len(nopts.files) == 0 assert len(nopts.args) == 0 - def test_args(self): + def test_args(self) -> None: """Test updating an Environment with arguments overridden""" # Test that a bad (command-line) argument is used @@ -343,7 +343,7 @@ class VariablesTestCase(unittest.TestCase): opts.Update(env, {'ANSWER':42}) assert env['ANSWER'] == 54 - def test_Save(self): + def test_Save(self) -> None: """Testing saving Variables""" test = TestSCons.TestSCons() @@ -396,9 +396,9 @@ class VariablesTestCase(unittest.TestCase): # Test against some old bugs class Foo: - def __init__(self, x): + def __init__(self, x) -> None: self.x = x - def __str__(self): + def __str__(self) -> str: return self.x test = TestSCons.TestSCons() @@ -426,7 +426,7 @@ class VariablesTestCase(unittest.TestCase): 'THIS_ALSO_BROKE' : "\\Escape\nSequences\t", 'THIS_SHOULD_WORK' : 'baz' }) - def test_GenerateHelpText(self): + def test_GenerateHelpText(self) -> None: """Test generating the default format help text""" opts = SCons.Variables.Variables() @@ -507,11 +507,11 @@ A: a - alpha test expectBackwards, ) - def test_FormatVariableHelpText(self): + def test_FormatVariableHelpText(self) -> None: """Test generating custom format help text""" opts = SCons.Variables.Variables() - def my_format(env, opt, help, default, actual, aliases): + def my_format(env, opt, help, default, actual, aliases) -> str: return '%s %s %s %s %s\n' % (opt, default, actual, help, aliases) opts.FormatVariableHelpText = my_format @@ -554,7 +554,7 @@ B 42 54 b - alpha test ['B'] text = opts.GenerateHelpText(env, sort=cmp) assert text == expectAlpha, text - def test_Aliases(self): + def test_Aliases(self) -> None: """Test option aliases""" # test alias as a tuple opts = SCons.Variables.Variables() @@ -595,7 +595,7 @@ B 42 54 b - alpha test ['B'] class UnknownVariablesTestCase(unittest.TestCase): - def test_unknown(self): + def test_unknown(self) -> None: """Test the UnknownVariables() method""" opts = SCons.Variables.Variables() @@ -615,7 +615,7 @@ class UnknownVariablesTestCase(unittest.TestCase): assert r == {'UNKNOWN' : 'unknown'}, r assert env['ANSWER'] == 'answer', env['ANSWER'] - def test_AddOptionUpdatesUnknown(self): + def test_AddOptionUpdatesUnknown(self) -> None: """Test updating of the 'unknown' dict""" opts = SCons.Variables.Variables() @@ -650,7 +650,7 @@ class UnknownVariablesTestCase(unittest.TestCase): assert len(r) == 0, r assert env['ADDEDLATER'] == 'added', env['ADDEDLATER'] - def test_AddOptionWithAliasUpdatesUnknown(self): + def test_AddOptionWithAliasUpdatesUnknown(self) -> None: """Test updating of the 'unknown' dict (with aliases)""" opts = SCons.Variables.Variables() diff --git a/SCons/Variables/__init__.py b/SCons/Variables/__init__.py index fc78de553..4d40986bd 100644 --- a/SCons/Variables/__init__.py +++ b/SCons/Variables/__init__.py @@ -57,7 +57,7 @@ class Variables: """ instance = None - def __init__(self, files=None, args=None, is_global=True): + def __init__(self, files=None, args=None, is_global: bool=True) -> None: if args is None: args = {} self.options = [] @@ -76,7 +76,7 @@ class Variables: if not Variables.instance: Variables.instance=self - def _do_add(self, key, help="", default=None, validator=None, converter=None, **kwargs) -> None: + def _do_add(self, key, help: str="", default=None, validator=None, converter=None, **kwargs) -> None: class Variable: pass diff --git a/SCons/Warnings.py b/SCons/Warnings.py index f77a24a2d..5c2a0db62 100644 --- a/SCons/Warnings.py +++ b/SCons/Warnings.py @@ -144,15 +144,15 @@ _warningAsException = False # If not None, a function to call with the warning _warningOut = None -def suppressWarningClass(clazz): +def suppressWarningClass(clazz) -> None: """Suppresses all warnings of type clazz or derived from clazz.""" _enabled.insert(0, (clazz, False)) -def enableWarningClass(clazz): +def enableWarningClass(clazz) -> None: """Enables all warnings of type clazz or derived from clazz.""" _enabled.insert(0, (clazz, True)) -def warningAsException(flag=True): +def warningAsException(flag: bool=True): """Set global _warningAsExeption flag. Args: @@ -185,7 +185,7 @@ def warn(clazz, *args): _warningOut(warning) break -def process_warn_strings(arguments): +def process_warn_strings(arguments) -> None: """Process requests to enable/disable warnings. The requests are strings passed to the --warn option or the diff --git a/SCons/WarningsTests.py b/SCons/WarningsTests.py index c22b049bd..85dbb6edc 100644 --- a/SCons/WarningsTests.py +++ b/SCons/WarningsTests.py @@ -26,14 +26,14 @@ import unittest import SCons.Warnings class TestOutput: - def __call__(self, x): + def __call__(self, x) -> None: args = x.args[0] if len(args) == 1: args = args[0] self.out = str(args) class WarningsTestCase(unittest.TestCase): - def test_Warning(self): + def test_Warning(self) -> None: """Test warn function.""" # Reset global state @@ -50,7 +50,7 @@ class WarningsTestCase(unittest.TestCase): "Foo", 1) assert to.out == "('Foo', 1)", to.out - def test_WarningAsExc(self): + def test_WarningAsExc(self) -> None: """Test warnings as exceptions.""" # Reset global state @@ -76,7 +76,7 @@ class WarningsTestCase(unittest.TestCase): exc_caught = 1 assert exc_caught == 0 - def test_Disable(self): + def test_Disable(self) -> None: """Test disabling/enabling warnings.""" # Reset global state diff --git a/SCons/compat/__init__.py b/SCons/compat/__init__.py index 03b12af99..2174f38c1 100644 --- a/SCons/compat/__init__.py +++ b/SCons/compat/__init__.py @@ -64,7 +64,7 @@ import importlib PYPY = hasattr(sys, 'pypy_translation_info') -def rename_module(new, old): +def rename_module(new, old) -> bool: """ Attempt to import the old module and load it under the new name. Used for purely cosmetic name changes in Python 3.x. diff --git a/SCons/cpp.py b/SCons/cpp.py index 144f49870..c9c9a70f0 100644 --- a/SCons/cpp.py +++ b/SCons/cpp.py @@ -180,7 +180,7 @@ del override class FunctionEvaluator: """Handles delayed evaluation of a #define function call.""" - def __init__(self, name, args, expansion): + def __init__(self, name, args, expansion) -> None: """ Squirrels away the arguments and expansion value of a #define macro function for later evaluation when we must actually expand @@ -230,7 +230,7 @@ function_arg_separator = re.compile(r',\s*') class PreProcessor: """The main workhorse class for handling C pre-processing.""" - def __init__(self, current=os.curdir, cpppath=(), dict={}, all=0, depth=-1): + def __init__(self, current=os.curdir, cpppath=(), dict={}, all: int=0, depth=-1) -> None: global Table cpppath = tuple(cpppath) @@ -339,7 +339,7 @@ class PreProcessor: # Dispatch table stack manipulation methods. - def save(self): + def save(self) -> None: """ Pushes the current dispatch table on the stack and re-initializes the current dispatch table to the default. @@ -347,7 +347,7 @@ class PreProcessor: self.stack.append(self.dispatch_table) self.dispatch_table = self.default_table.copy() - def restore(self): + def restore(self) -> None: """ Pops the previous dispatch table off the stack and makes it the current one. @@ -357,14 +357,14 @@ class PreProcessor: # Utility methods. - def do_nothing(self, t): + def do_nothing(self, t) -> None: """ Null method for when we explicitly want the action for a specific preprocessor directive to do nothing. """ pass - def scons_current_file(self, t): + def scons_current_file(self, t) -> None: self.current_file = t[1] def eval_expression(self, t): @@ -381,7 +381,7 @@ class PreProcessor: except (NameError, TypeError, SyntaxError): return 0 - def initialize_result(self, fname): + def initialize_result(self, fname) -> None: self.result = [fname] def finalize_result(self, fname): @@ -407,7 +407,7 @@ class PreProcessor: # Start and stop processing include lines. - def start_handling_includes(self, t=None): + def start_handling_includes(self, t=None) -> None: """ Causes the PreProcessor object to start processing #import, #include and #include_next lines. @@ -424,7 +424,7 @@ class PreProcessor: for k in ('import', 'include', 'include_next', 'define', 'undef'): d[k] = p[k] - def stop_handling_includes(self, t=None): + def stop_handling_includes(self, t=None) -> None: """ Causes the PreProcessor object to stop processing #import, #include and #include_next lines. @@ -444,7 +444,7 @@ class PreProcessor: # (Note that what actually gets called for a given directive at any # point in time is really controlled by the dispatch_table.) - def _do_if_else_condition(self, condition): + def _do_if_else_condition(self, condition) -> None: """ Common logic for evaluating the conditions on #if, #ifdef and #ifndef lines. @@ -460,25 +460,25 @@ class PreProcessor: d['elif'] = self.do_elif d['else'] = self.start_handling_includes - def do_ifdef(self, t): + def do_ifdef(self, t) -> None: """ Default handling of a #ifdef line. """ self._do_if_else_condition(t[1] in self.cpp_namespace) - def do_ifndef(self, t): + def do_ifndef(self, t) -> None: """ Default handling of a #ifndef line. """ self._do_if_else_condition(t[1] not in self.cpp_namespace) - def do_if(self, t): + def do_if(self, t) -> None: """ Default handling of a #if line. """ self._do_if_else_condition(self.eval_expression(t)) - def do_elif(self, t): + def do_elif(self, t) -> None: """ Default handling of a #elif line. """ @@ -488,19 +488,19 @@ class PreProcessor: d['elif'] = self.stop_handling_includes d['else'] = self.stop_handling_includes - def do_else(self, t): + def do_else(self, t) -> None: """ Default handling of a #else line. """ pass - def do_endif(self, t): + def do_endif(self, t) -> None: """ Default handling of a #endif line. """ self.restore() - def do_define(self, t): + def do_define(self, t) -> None: """ Default handling of a #define line. """ @@ -519,21 +519,21 @@ class PreProcessor: else: self.cpp_namespace[name] = expansion - def do_undef(self, t): + def do_undef(self, t) -> None: """ Default handling of a #undef line. """ try: del self.cpp_namespace[t[1]] except KeyError: pass - def do_import(self, t): + def do_import(self, t) -> None: """ Default handling of a #import line. """ # XXX finish this -- maybe borrow/share logic from do_include()...? pass - def do_include(self, t): + def do_include(self, t) -> None: """ Default handling of a #include line. """ @@ -614,7 +614,7 @@ class PreProcessor: return None return (t[0], s[0], s[1:-1]) - def all_include(self, t): + def all_include(self, t) -> None: """ """ self.result.append(self.resolve_include(t)) @@ -630,7 +630,7 @@ class DumbPreProcessor(PreProcessor): an example of how the main PreProcessor class can be sub-classed to tailor its behavior. """ - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: PreProcessor.__init__(self, *args, **kw) d = self.default_table for func in ['if', 'elif', 'else', 'endif', 'ifdef', 'ifndef']: diff --git a/SCons/cppTests.py b/SCons/cppTests.py index f781e81b0..5f00d500a 100644 --- a/SCons/cppTests.py +++ b/SCons/cppTests.py @@ -441,89 +441,89 @@ if_no_space_input = """ class cppTestCase(unittest.TestCase): - def setUp(self): + def setUp(self) -> None: self.cpp = self.cpp_class(current = ".", cpppath = ['/usr/include'], dict={"SHELL_ESCAPED_H": '\\"file-shell-computed-yes\\"'}) - def test_basic(self): + def test_basic(self) -> None: """Test basic #include scanning""" expect = self.basic_expect result = self.cpp.process_contents(basic_input) assert expect == result, (expect, result) - def test_substitution(self): + def test_substitution(self) -> None: """Test substitution of #include files using CPP variables""" expect = self.substitution_expect result = self.cpp.process_contents(substitution_input) assert expect == result, (expect, result) - def test_ifdef(self): + def test_ifdef(self) -> None: """Test basic #ifdef processing""" expect = self.ifdef_expect result = self.cpp.process_contents(ifdef_input) assert expect == result, (expect, result) - def test_if_boolean(self): + def test_if_boolean(self) -> None: """Test #if with Boolean values""" expect = self.if_boolean_expect result = self.cpp.process_contents(if_boolean_input) assert expect == result, (expect, result) - def test_if_defined(self): + def test_if_defined(self) -> None: """Test #if defined() idioms""" expect = self.if_defined_expect result = self.cpp.process_contents(if_defined_input) assert expect == result, (expect, result) - def test_expression(self): + def test_expression(self) -> None: """Test #if with arithmetic expressions""" expect = self.expression_expect result = self.cpp.process_contents(expression_input) assert expect == result, (expect, result) - def test_undef(self): + def test_undef(self) -> None: """Test #undef handling""" expect = self.undef_expect result = self.cpp.process_contents(undef_input) assert expect == result, (expect, result) - def test_macro_function(self): + def test_macro_function(self) -> None: """Test using macro functions to express file names""" expect = self.macro_function_expect result = self.cpp.process_contents(macro_function_input) assert expect == result, (expect, result) - def test_token_pasting(self): + def test_token_pasting(self) -> None: """Test token-pasting to construct file names""" expect = self.token_pasting_expect result = self.cpp.process_contents(token_pasting_input) assert expect == result, (expect, result) - def test_no_space(self): + def test_no_space(self) -> None: """Test no space between #include and the quote""" expect = self.no_space_expect result = self.cpp.process_contents(no_space_input) assert expect == result, (expect, result) - def test_nested_ifs(self): + def test_nested_ifs(self) -> None: expect = self.nested_ifs_expect result = self.cpp.process_contents(nested_ifs_input) assert expect == result, (expect, result) - def test_ifndef(self): + def test_ifndef(self) -> None: """Test basic #ifndef processing""" expect = self.ifndef_expect result = self.cpp.process_contents(ifndef_input) assert expect == result, (expect, result) - def test_if_defined_no_space(self): + def test_if_defined_no_space(self) -> None: """Test #if(defined, i.e.without space but parenthesis""" expect = self.if_defined_no_space_expect result = self.cpp.process_contents(if_defined_no_space_input) assert expect == result, (expect, result) - def test_if_no_space(self): + def test_if_no_space(self) -> None: """Test #if(, i.e. without space but parenthesis""" expect = self.if_no_space_expect result = self.cpp.process_contents(if_no_space_input) @@ -531,7 +531,7 @@ class cppTestCase(unittest.TestCase): class cppAllTestCase(cppTestCase): - def setUp(self): + def setUp(self) -> None: self.cpp = self.cpp_class(current = ".", cpppath = ['/usr/include'], dict={"SHELL_ESCAPED_H": '\\"file-shell-computed-yes\\"'}, @@ -792,7 +792,7 @@ import tempfile _Cleanup = [] -def _clean(): +def _clean() -> None: for dir in _Cleanup: if os.path.exists(dir): shutil.rmtree(dir) @@ -807,14 +807,14 @@ else: class fileTestCase(unittest.TestCase): cpp_class = cpp.DumbPreProcessor - def setUp(self): + def setUp(self) -> None: path = tempfile.mkdtemp(prefix=tmpprefix) _Cleanup.append(path) self.tempdir = path self.orig_cwd = os.getcwd() os.chdir(path) - def tearDown(self): + def tearDown(self) -> None: os.chdir(self.orig_cwd) shutil.rmtree(self.tempdir) _Cleanup.remove(self.tempdir) @@ -828,11 +828,11 @@ class fileTestCase(unittest.TestCase): return l return '\n'.join(map(strip_spaces, lines)) - def write(self, file, contents): + def write(self, file, contents) -> None: with open(file, 'w') as f: f.write(self.strip_initial_spaces(contents)) - def test_basic(self): + def test_basic(self) -> None: """Test basic file inclusion""" self.write('f1.h', """\ #include "f2.h" @@ -847,7 +847,7 @@ class fileTestCase(unittest.TestCase): result = p('f1.h') assert result == ['f2.h', 'f3.h'], result - def test_current_file(self): + def test_current_file(self) -> None: """Test use of the .current_file attribute""" self.write('f1.h', """\ #include @@ -858,7 +858,7 @@ class fileTestCase(unittest.TestCase): self.write('f3.h', """\ """) class MyPreProcessor(cpp.DumbPreProcessor): - def __init__(self, *args, **kw): + def __init__(self, *args, **kw) -> None: super().__init__(*args, **kw) self.files = [] def __call__(self, file): diff --git a/SCons/dblite.py b/SCons/dblite.py index 9cf975c1d..dd05f6691 100644 --- a/SCons/dblite.py +++ b/SCons/dblite.py @@ -37,7 +37,7 @@ KEEP_ALL_FILES = False IGNORE_CORRUPT_DBFILES = False -def corruption_warning(filename): +def corruption_warning(filename) -> None: """Local warning for corrupt db. Used for self-tests. SCons overwrites this with a @@ -76,7 +76,7 @@ class dblite: _shutil_copyfile = shutil.copyfile _time_time = time.time - def __init__(self, file_base_name, flag, mode): + def __init__(self, file_base_name, flag, mode) -> None: assert flag in (None, "r", "w", "c", "n") if flag is None: flag = "r" @@ -136,14 +136,14 @@ class dblite: else: raise - def close(self): + def close(self) -> None: if self._needs_sync: self.sync() - def __del__(self): + def __del__(self) -> None: self.close() - def sync(self): + def sync(self) -> None: self._check_writable() with self._open(self._tmp_name, "wb", self._mode) as f: self._pickle_dump(self._dict, f, self._pickle_protocol) @@ -197,17 +197,17 @@ class dblite: def keys(self): return list(self._dict.keys()) - def __contains__(self, key): + def __contains__(self, key) -> bool: return key in self._dict def __iter__(self): return iter(self._dict) - def __len__(self): + def __len__(self) -> int: return len(self._dict) -def open(file, flag=None, mode=0o666): +def open(file, flag=None, mode: int=0o666): return dblite(file, flag, mode) diff --git a/SCons/exitfuncs.py b/SCons/exitfuncs.py index ba6243a7a..d28bba4d0 100644 --- a/SCons/exitfuncs.py +++ b/SCons/exitfuncs.py @@ -28,7 +28,7 @@ import atexit _exithandlers = [] -def _run_exitfuncs(): +def _run_exitfuncs() -> None: """run any registered exit functions _exithandlers is traversed in reverse order so functions are executed @@ -39,7 +39,7 @@ def _run_exitfuncs(): func, targs, kargs = _exithandlers.pop() func(*targs, **kargs) -def register(func, *targs, **kargs): +def register(func, *targs, **kargs) -> None: """register a function to be executed upon normal program termination func - function to be called at exit -- cgit v1.2.1 From 8bb3d1b1d8966b451ed2f3d63a38b32e99e7bde9 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 2 May 2023 10:49:49 -0600 Subject: Eliminate pylint warning on direct use of __call__ C2801: Unnecessarily calls dunder method __call__. Invoke instance directly. These were all in the same file (docbook tool) Signed-off-by: Mats Wichmann --- SCons/Tool/docbook/__init__.py | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) (limited to 'SCons') diff --git a/SCons/Tool/docbook/__init__.py b/SCons/Tool/docbook/__init__.py index 52e291144..ea5bf03d0 100644 --- a/SCons/Tool/docbook/__init__.py +++ b/SCons/Tool/docbook/__init__.py @@ -244,7 +244,7 @@ def __xml_scan(node, env, path, arg): # for xi:includes... contents = node.get_text_contents() return include_re.findall(contents) - + from lxml import etree xsl_tree = etree.parse(xsl_file) @@ -490,7 +490,7 @@ def DocbookEpub(env, target, source=None, *args, **kw): # Set the fixed base_dir kw['base_dir'] = 'OEBPS/' - tocncx = __builder.__call__(env, 'toc.ncx', source[0], **kw) + tocncx = __builder(env, 'toc.ncx', source[0], **kw) cxml = env.File('META-INF/container.xml') env.SideEffect(cxml, tocncx) @@ -524,7 +524,7 @@ def DocbookHtml(env, target, source=None, *args, **kw): # Create targets result = [] for t,s in zip(target,source): - r = __builder.__call__(env, __ensure_suffix(t,'.html'), s, **kw) + r = __builder(env, __ensure_suffix(t,'.html'), s, **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) @@ -556,7 +556,7 @@ def DocbookHtmlChunked(env, target, source=None, *args, **kw): # Create targets result = [] - r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + r = __builder(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) # Add supporting files for cleanup @@ -591,7 +591,7 @@ def DocbookHtmlhelp(env, target, source=None, *args, **kw): # Create targets result = [] - r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + r = __builder(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) # Add supporting files for cleanup @@ -617,10 +617,10 @@ def DocbookPdf(env, target, source=None, *args, **kw): result = [] for t,s in zip(target,source): t, stem = __ensure_suffix_stem(t, '.pdf') - xsl = __builder.__call__(env, stem+'.fo', s, **kw) + xsl = __builder(env, stem+'.fo', s, **kw) result.extend(xsl) env.Depends(xsl, kw['DOCBOOK_XSL']) - result.extend(__fop_builder.__call__(env, t, xsl, **kw)) + result.extend(__fop_builder(env, t, xsl, **kw)) return result @@ -681,7 +681,7 @@ def DocbookMan(env, target, source=None, *args, **kw): # We have to completely rely on the given target name outfiles.append(t) - __builder.__call__(env, outfiles[0], s, **kw) + __builder(env, outfiles[0], s, **kw) env.Depends(outfiles[0], kw['DOCBOOK_XSL']) result.append(outfiles[0]) if len(outfiles) > 1: @@ -707,10 +707,10 @@ def DocbookSlidesPdf(env, target, source=None, *args, **kw): result = [] for t,s in zip(target,source): t, stem = __ensure_suffix_stem(t, '.pdf') - xsl = __builder.__call__(env, stem+'.fo', s, **kw) + xsl = __builder(env, stem+'.fo', s, **kw) env.Depends(xsl, kw['DOCBOOK_XSL']) result.extend(xsl) - result.extend(__fop_builder.__call__(env, t, xsl, **kw)) + result.extend(__fop_builder(env, t, xsl, **kw)) return result @@ -740,7 +740,7 @@ def DocbookSlidesHtml(env, target, source=None, *args, **kw): # Create targets result = [] - r = __builder.__call__(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) + r = __builder(env, __ensure_suffix(str(target[0]), '.html'), source[0], **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) # Add supporting files for cleanup @@ -762,7 +762,7 @@ def DocbookXInclude(env, target, source, *args, **kw): # Create targets result = [] for t,s in zip(target,source): - result.extend(__builder.__call__(env, t, s, **kw)) + result.extend(__builder(env, t, s, **kw)) return result @@ -782,7 +782,7 @@ def DocbookXslt(env, target, source=None, *args, **kw): # Create targets result = [] for t,s in zip(target,source): - r = __builder.__call__(env, t, s, **kw) + r = __builder(env, t, s, **kw) env.Depends(r, kw['DOCBOOK_XSL']) result.extend(r) -- cgit v1.2.1 From 1ee43f4691dc7ab651fd22f07748c237f0301675 Mon Sep 17 00:00:00 2001 From: Mats Wichmann Date: Tue, 2 May 2023 11:28:46 -0600 Subject: Change bas64 decodestring -> decodebytes The former was an alias in Python 3, deprecated since 3.1. Use the replacement. Signed-off-by: Mats Wichmann --- SCons/Tool/msvs.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'SCons') diff --git a/SCons/Tool/msvs.py b/SCons/Tool/msvs.py index 86df1ef66..d21803890 100644 --- a/SCons/Tool/msvs.py +++ b/SCons/Tool/msvs.py @@ -777,7 +777,7 @@ class _GenerateV6DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -798,7 +798,7 @@ class _GenerateV6DSP(_DSPGenerator): # OK, we've found our little pickled cache of data. # it has a "# " in front of it, so we strip that. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -1095,7 +1095,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -1115,7 +1115,7 @@ class _GenerateV7DSP(_DSPGenerator, _GenerateV7User): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise @@ -1592,7 +1592,7 @@ class _GenerateV7DSW(_DSWGenerator): # OK, we've found our little pickled cache of data. try: - datas = base64.decodestring(datas) + datas = base64.decodebytes(datas) data = pickle.loads(datas) except KeyboardInterrupt: raise -- cgit v1.2.1