+2024-03-27 Collin Funk <collin.funk1@gmail.com>
+
+ gnulib-tool.py: Add type hints to all functions.
+ * pygnulib/*.py: Add type hints and remove duplicate function signatures
+ from docstrings.
+
2024-03-26 Collin Funk <collin.funk1@gmail.com>
gnulib-tool.py: Allow the use of both configure.ac and configure.in.
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
By default all attributes are set to empty string, empty list or zero.
The most common value, however, is a None value.'''
- def __init__(self, destdir=None, localpath=None, auxdir=None,
- sourcebase=None, m4base=None, pobase=None, docbase=None, testsbase=None,
- modules=None, avoids=None, files=None,
- incl_test_categories=None, excl_test_categories=None, libname=None,
- lgpl=None, gnu_make=None, makefile_name=None, tests_makefile_name=None,
- automake_subdir=None, automake_subdir_tests=None, libtool=None,
- conddeps=None, macro_prefix=None,
- podomain=None, witness_c_macro=None, vc_files=None, copymode=None,
- lcopymode=None, configure_ac=None, ac_version=None, libtests=None,
- single_configure=None, verbose=None, dryrun=None, errors=None):
- '''GLConfig.__init__(arguments) -> GLConfig
-
- Create new GLConfig instance.'''
+ def __init__(self,
+ destdir: str | None = None,
+ localpath: list[str] | None = None,
+ auxdir: str | None = None,
+ sourcebase: str | None = None,
+ m4base: str | None = None,
+ pobase: str | None = None,
+ docbase: str | None = None,
+ testsbase: str | None = None,
+ modules: list[str] | None = None,
+ avoids: list[str] | None = None,
+ files: list[str] | None = None,
+ incl_test_categories: list[int] | tuple[int] | None = None,
+ excl_test_categories: list[int] | tuple[int] | None = None,
+ libname: str | None = None,
+ lgpl: str | bool | None = None,
+ gnu_make: bool | None = None,
+ makefile_name: str | None = None,
+ tests_makefile_name: str | None = None,
+ automake_subdir: bool | None = None,
+ automake_subdir_tests: bool | None = None,
+ libtool: bool | None = None,
+ conddeps: bool | None = None,
+ macro_prefix: str | None = None,
+ podomain: str | None = None,
+ witness_c_macro: str | None = None,
+ vc_files: bool | None = None,
+ copymode: classes.CopyAction | None = None,
+ lcopymode: classes.CopyAction | None = None,
+ configure_ac: str | None = None,
+ ac_version: float | int | None = None,
+ libtests: bool | None = None,
+ single_configure: bool | None = None,
+ verbose: int | None = None,
+ dryrun: bool | None = None,
+ errors: bool | None = None) -> None:
+ '''Create new GLConfig instance.'''
self.table = dict()
self.table['tempdir'] = tempfile.mkdtemp()
# Check and store the attributes.
self.setErrors(errors)
# Define special methods.
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__() <==> repr(x)'''
return '<pygnulib.GLConfig>'
- def __getitem__(self, y):
+ def __getitem__(self, y: str) -> str | float | int | bool | classes.CopyAction | list[str] | None:
'''x.__getitem__(y) <==> x[y]'''
if y in self.table:
result = self.table[y]
else: # if y not in self.table
raise KeyError('GLConfig does not contain key: %s' % repr(y))
- def dictionary(self):
+ def dictionary(self) -> dict[str, str | float | int | bool | classes.CopyAction | list[str] | None]:
'''Return the configuration as a dict object.'''
return dict(self.table)
- def copy(self):
+ def copy(self) -> GLConfig:
'''Return the copy of the configuration.'''
table = copy.deepcopy(self)
return table
- def update(self, dictionary):
+ def update(self, dictionary: GLConfig) -> None:
'''Specify the dictionary whose keys will be used to update config.'''
if type(dictionary) is not GLConfig:
raise TypeError('dictionary must be a GLConfig, not %s'
result[key] = dest
self.table = dict(result)
- def update_key(self, dictionary, key):
+ def update_key(self, dictionary: GLConfig, key: str) -> None:
'''Update the given key using value from the given dictionary.'''
if key in self.table:
if type(dictionary) is not GLConfig:
else: # if key not in self.table
raise KeyError('GLConfig does not contain key: %s' % repr(key))
- def default(self, key):
+ def default(self, key: str) -> str | float | int | bool | classes.CopyAction | list[str] | None:
'''Return default value for the given key.'''
if key in self.table:
if key == 'libname':
else: # if key not in self.table
raise KeyError('GLConfig does not contain key: %s' % repr(key))
- def isdefault(self, key, value):
+ def isdefault(self, key: str, value: str | float | int | bool | classes.CopyAction | list[str] | None) -> bool:
'''Check whether the value for the given key is a default value.'''
if key in self.table:
default = self.default(key)
else: # if key not in self.table
raise KeyError('GLConfig does not contain key: %s' % repr(key))
- def keys(self):
+ def keys(self) -> list[str]:
'''Return list of keys.'''
return list(self.table.keys())
- def values(self):
+ def values(self) -> list[str | float | int | bool | classes.CopyAction | list[str] | None]:
'''Return list of values.'''
return list(self.table.values())
# Define destdir methods.
- def getDestDir(self):
+ def getDestDir(self) -> str:
'''Return the target directory. For --import, this specifies where your
configure.ac can be found. Defaults to current directory.'''
return self.table['destdir']
- def setDestDir(self, destdir):
+ def setDestDir(self, destdir: str) -> None:
'''Specify the target directory. For --import, this specifies where your
configure.ac can be found. Defaults to current directory.'''
if type(destdir) is str:
raise TypeError('destdir must be a string, not %s'
% type(destdir).__name__)
- def resetDestDir(self):
+ def resetDestDir(self) -> None:
'''Reset the target directory. For --import, this specifies where your
configure.ac can be found. Defaults to current directory.'''
self.table['destdir'] = ''
# Define localpath methods.
- def getLocalPath(self):
+ def getLocalPath(self) -> list[str]:
'''Return a list of local override directories where to look up files
before looking in gnulib's directory. The first one has the highest
priority.'''
return self.table['localpath']
- def setLocalPath(self, localpath):
+ def setLocalPath(self, localpath: list[str]) -> None:
'''Specify a list of local override directories where to look up files
before looking in gnulib's directory. The first one has the highest
priority.'''
self.table['localpath'] = [ remove_trailing_slashes(dir)
for dir in localpath ]
- def resetLocalPath(self):
+ def resetLocalPath(self) -> None:
'''Reset a list of local override directories where to look up files
before looking in gnulib's directory.'''
self.table['localpath'] = []
# Define auxdir methods.
- def getAuxDir(self):
+ def getAuxDir(self) -> str:
'''Return directory relative to --dir where auxiliary build tools are
placed. Default comes from configure.ac or configure.in.'''
if self.table['auxdir']:
return self.table['auxdir']
return "build-aux"
- def setAuxDir(self, auxdir):
+ def setAuxDir(self, auxdir: str) -> None:
'''Specify directory relative to --dir where auxiliary build tools are
placed. Default comes from configure.ac or configure.in.'''
if type(auxdir) is str:
raise TypeError('auxdir must be a string, not %s'
% type(auxdir).__name__)
- def resetAuxDir(self):
+ def resetAuxDir(self) -> None:
'''Reset directory relative to --dir where auxiliary build tools are
placed. Default comes from configure.ac or configure.in.'''
self.table['auxdir'] = ''
# Define sourcebase methods.
- def getSourceBase(self):
+ def getSourceBase(self) -> str:
'''Return directory relative to destdir where source code is placed.'''
return self.table['sourcebase']
- def setSourceBase(self, sourcebase):
+ def setSourceBase(self, sourcebase: str) -> None:
'''Specify directory relative to destdir where source code is placed.'''
if type(sourcebase) is str:
if sourcebase:
raise TypeError('sourcebase must be a string, not %s'
% type(sourcebase).__name__)
- def resetSourceBase(self):
+ def resetSourceBase(self) -> None:
'''Return directory relative to destdir where source code is placed.'''
self.table['sourcebase'] = ''
# Define m4base methods.
- def getM4Base(self):
+ def getM4Base(self) -> str:
'''Return directory relative to destdir where *.m4 macros are placed.'''
return self.table['m4base']
- def setM4Base(self, m4base):
+ def setM4Base(self, m4base: str) -> None:
'''Specify directory relative to destdir where *.m4 macros are placed.'''
if type(m4base) is str:
if m4base:
raise TypeError('m4base must be a string, not %s'
% type(m4base).__name__)
- def resetM4Base(self):
+ def resetM4Base(self) -> None:
'''Reset directory relative to destdir where *.m4 macros are placed.'''
self.table['m4base'] = ''
# Define pobase methods.
- def getPoBase(self):
+ def getPoBase(self) -> str:
'''Return directory relative to destdir where *.po files are placed.'''
return self.table['pobase']
- def setPoBase(self, pobase):
+ def setPoBase(self, pobase: str) -> None:
'''Specify directory relative to destdir where *.po files are placed.'''
if type(pobase) is str:
if pobase:
raise TypeError('pobase must be a string, not %s'
% type(pobase).__name__)
- def resetPoBase(self):
+ def resetPoBase(self) -> None:
'''Reset directory relative to destdir where *.po files are placed.'''
self.table['pobase'] = ''
# Define docbase methods.
- def getDocBase(self):
+ def getDocBase(self) -> str:
'''Return directory relative to destdir where doc files are placed.
Default value for this variable is 'doc').'''
return self.table['docbase']
- def setDocBase(self, docbase):
+ def setDocBase(self, docbase: str) -> None:
'''Specify directory relative to destdir where doc files are placed.
Default value for this variable is 'doc').'''
if type(docbase) is str:
raise TypeError('docbase must be a string, not %s'
% type(docbase).__name__)
- def resetDocBase(self):
+ def resetDocBase(self) -> None:
'''Reset directory relative to destdir where doc files are placed.
Default value for this variable is 'doc').'''
self.table['docbase'] = ''
# Define testsbase methods.
- def getTestsBase(self):
+ def getTestsBase(self) -> str:
'''Return directory relative to destdir where unit tests are placed.
Default value for this variable is 'tests').'''
return self.table['testsbase']
- def setTestsBase(self, testsbase):
+ def setTestsBase(self, testsbase: str) -> None:
'''Specify directory relative to destdir where unit tests are placed.
Default value for this variable is 'tests').'''
if type(testsbase) is str:
raise TypeError('testsbase must be a string, not %s'
% type(testsbase).__name__)
- def resetTestsBase(self):
+ def resetTestsBase(self) -> None:
'''Reset directory relative to destdir where unit tests are placed.
Default value for this variable is 'tests').'''
self.table['testsbase'] = ''
# Define modules methods.
- def addModule(self, module):
+ def addModule(self, module: str) -> None:
'''Add the module to the modules list.'''
if type(module) is str:
if module not in self.table['modules']:
raise TypeError('module must be a string, not %s'
% type(module).__name__)
- def removeModule(self, module):
+ def removeModule(self, module: str) -> None:
'''Remove the module from the modules list.'''
if type(module) is str:
if module in self.table['modules']:
raise TypeError('module must be a string, not %s'
% type(module).__name__)
- def getModules(self):
+ def getModules(self) -> list[str]:
'''Return the modules list.'''
return list(self.table['modules'])
- def setModules(self, modules):
+ def setModules(self, modules: list[str] | tuple[str]) -> None:
'''Set the modules list.'''
if type(modules) is list or type(modules) is tuple:
old_modules = self.table['modules']
raise TypeError('modules must be a list or a tuple, not %s'
% type(modules).__name__)
- def resetModules(self):
+ def resetModules(self) -> None:
'''Reset the list of the modules.'''
self.table['modules'] = list()
# Define avoids methods.
- def addAvoid(self, module):
+ def addAvoid(self, module: str) -> None:
'''Avoid including the given module. Useful if you have code that provides
equivalent functionality.'''
if type(module) is str:
raise TypeError('avoid must be a string, not %s'
% type(module).__name__)
- def removeAvoid(self, module):
+ def removeAvoid(self, module: str) -> None:
'''Remove the given module from the list of avoided modules.'''
if type(module) is str:
if module in self.table['avoids']:
raise TypeError('avoid must be a string, not %s'
% type(module).__name__)
- def getAvoids(self):
+ def getAvoids(self) -> list[str]:
'''Return the list of the avoided modules.'''
return list(self.table['avoids'])
- def setAvoids(self, modules):
+ def setAvoids(self, modules: list[str] | tuple[str]) -> None:
'''Specify the modules which will be avoided.'''
if type(modules) is list or type(modules) is tuple:
old_avoids = self.table['avoids']
raise TypeError('modules must be a list or a tuple, not %s'
% type(modules).__name__)
- def resetAvoids(self):
+ def resetAvoids(self) -> None:
'''Reset the list of the avoided modules.'''
self.table['avoids'] = list()
# Define files methods.
- def addFile(self, file):
+ def addFile(self, file: str) -> None:
'''Add file to the list of files.'''
if type(file) is str:
if file not in self.table['files']:
raise TypeError('file must be a string, not %s'
% type(file).__name__)
- def removeFile(self, file):
+ def removeFile(self, file: str) -> None:
'''Remove the given file from the list of files.'''
if type(file) is str:
if file in self.table['files']:
raise TypeError('file must be a string, not %s'
% type(file).__name__)
- def getFiles(self):
+ def getFiles(self) -> list[str]:
'''Return the list of files.'''
return list(self.table['files'])
- def setFiles(self, files):
+ def setFiles(self, files: list[str] | tuple[str]) -> None:
'''Specify the list of files.'''
if type(files) is list or type(files) is tuple:
old_files = self.table['files']
raise TypeError('files must be a list or a tuple, not %s'
% type(files).__name__)
- def resetFiles(self):
+ def resetFiles(self) -> None:
'''Reset the list of files.'''
self.table['files'] = list()
# Define incl_test_categories methods
- def checkInclTestCategory(self, category):
+ def checkInclTestCategory(self, category: int) -> bool:
'''Tests whether the given test category is included.'''
if category in TESTS.values():
return category in self.table['incl_test_categories']
else: # if category is not in TESTS
raise TypeError('unknown category: %s' % repr(category))
- def enableInclTestCategory(self, category):
+ def enableInclTestCategory(self, category: int) -> None:
'''Enable the given test category.'''
if category in TESTS.values():
if category not in self.table['incl_test_categories']:
else: # if category is not in TESTS
raise TypeError('unknown category: %s' % repr(category))
- def disableInclTestCategory(self, category):
+ def disableInclTestCategory(self, category: int) -> None:
'''Disable the given test category.'''
if category in TESTS.values():
if category in self.table['incl_test_categories']:
else: # if category is not in TESTS
raise TypeError('unknown category: %s' % repr(category))
- def setInclTestCategory(self, category, enable):
+ def setInclTestCategory(self, category: int, enable: bool) -> None:
'''Enable or disable the given test category.'''
if enable:
self.enableInclTestCategory(category)
else:
self.disableInclTestCategory(category)
- def getInclTestCategories(self):
+ def getInclTestCategories(self) -> list[int]:
'''Return the test categories that should be included.
To get the list of all test categories, use the TESTS variable.'''
return list(self.table['incl_test_categories'])
- def setInclTestCategories(self, categories):
+ def setInclTestCategories(self, categories: list[int] | tuple[int]) -> None:
'''Specify the test categories that should be included.'''
if type(categories) is list or type(categories) is tuple:
old_categories = self.table['incl_test_categories']
raise TypeError('categories must be a list or a tuple, not %s'
% type(categories).__name__)
- def resetInclTestCategories(self):
+ def resetInclTestCategories(self) -> None:
'''Reset test categories.'''
self.table['incl_test_categories'] = list()
# Define excl_test_categories methods
- def checkExclTestCategory(self, category):
+ def checkExclTestCategory(self, category: int) -> bool:
'''Tests whether the given test category is excluded.'''
if category in TESTS.values():
return category in self.table['excl_test_categories']
else: # if category is not in TESTS
raise TypeError('unknown category: %s' % repr(category))
- def enableExclTestCategory(self, category):
+ def enableExclTestCategory(self, category: int) -> None:
'''Enable the given test category.'''
if category in TESTS.values():
if category not in self.table['excl_test_categories']:
else: # if category is not in TESTS
raise TypeError('unknown category: %s' % repr(category))
- def disableExclTestCategory(self, category):
+ def disableExclTestCategory(self, category: int) -> None:
'''Disable the given test category.'''
if category in TESTS.values():
if category in self.table['excl_test_categories']:
else: # if category is not in TESTS
raise TypeError('unknown category: %s' % repr(category))
- def getExclTestCategories(self):
+ def getExclTestCategories(self) -> list[int]:
'''Return the test categories that should be excluded.
To get the list of all test categories, use the TESTS variable.'''
return list(self.table['excl_test_categories'])
- def setExclTestCategories(self, categories):
+ def setExclTestCategories(self, categories: list[int] | tuple[int]) -> None:
'''Specify the test categories that should be excluded.'''
if type(categories) is list or type(categories) is tuple:
old_categories = self.table['excl_test_categories']
raise TypeError('categories must be a list or a tuple, not %s'
% type(categories).__name__)
- def resetExclTestCategories(self):
+ def resetExclTestCategories(self) -> None:
'''Reset test categories.'''
self.table['excl_test_categories'] = list()
# Define libname methods.
- def getLibName(self):
+ def getLibName(self) -> str:
'''Return the library name.'''
return self.table['libname']
- def setLibName(self, libname):
+ def setLibName(self, libname: str) -> None:
'''Specify the library name.'''
if type(libname) is str:
if libname:
raise TypeError('libname must be a string, not %s'
% type(libname).__name__)
- def resetLibName(self):
+ def resetLibName(self) -> None:
'''Reset the library name to 'libgnu'.'''
self.table['libname'] = 'libgnu'
# Define libtool methods.
- def checkLibtool(self):
+ def checkLibtool(self) -> bool:
'''Check if user enabled libtool rules.'''
return self.table['libtool']
- def setLibtool(self, value):
+ def setLibtool(self, value: bool) -> None:
'''Enable / disable libtool rules.'''
if type(value) is bool:
self.table['libtool'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetLibtool(self):
+ def resetLibtool(self) -> None:
'''Reset libtool rules.'''
self.table['libtool'] = False
# Define conddeps methods.
- def checkCondDeps(self):
+ def checkCondDeps(self) -> bool:
'''Check if user enabled conditional dependencies.'''
return self.table['conddeps']
- def setCondDeps(self, value):
+ def setCondDeps(self, value: bool) -> None:
'''Enable / disable conditional dependencies (may save configure time and object code).'''
if type(value) is bool:
self.table['conddeps'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetCondDeps(self):
+ def resetCondDeps(self) -> None:
'''Reset conditional dependencies (may save configure time and object code).'''
self.table['conddeps'] = False
# Define lgpl methods.
- def getLGPL(self):
+ def getLGPL(self) -> str | bool | None:
'''Check for abort if modules aren't available under the LGPL.
Default value is None, which means that lgpl is disabled.'''
return self.table['lgpl']
- def setLGPL(self, lgpl):
+ def setLGPL(self, lgpl: str | bool | None) -> None:
'''Abort if modules aren't available under the LGPL.
Default value is None, which means that lgpl is disabled.'''
if lgpl in [None, True, '2', '3orGPLv2', '3']:
else:
raise TypeError('invalid LGPL version: %s' % repr(lgpl))
- def resetLGPL(self):
+ def resetLGPL(self) -> None:
'''Disable abort if modules aren't available under the LGPL.
Default value is None, which means that lgpl is disabled.'''
self.table['lgpl'] = None
# Define gnu-make methods.
- def getGnuMake(self):
+ def getGnuMake(self) -> bool:
'''Return a boolean value describing whether the --gnu-make argument
was used.'''
return self.table['gnu_make']
- def setGnuMake(self, value):
+ def setGnuMake(self, value: bool) -> None:
'''Set the --gnu-make argument as if it were invoked using the
command-line or disable it.'''
if type(value) is bool:
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetGnuMake(self):
+ def resetGnuMake(self) -> None:
'''Reset the --gnu-make argument to its default. This feature must be
explicitly enabled by programs who utilize GNU Make features instead
of Autmake.'''
self.table['gnu_make'] = False
- def getModuleIndicatorPrefix(self):
+ def getModuleIndicatorPrefix(self) -> str:
'''Return module_indicator_prefix to use inside GLEmiter class.'''
return self.getIncludeGuardPrefix()
# Define macro_prefix and include_guard_prefix methods.
# The include_guard_prefix is a replacement for ${gl_include_guard_prefix}.
# It is determined from the macro_prefix.
- def getMacroPrefix(self):
+ def getMacroPrefix(self) -> str:
'''Return the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
Default macro_prefix is 'gl'.'''
return self.table['macro_prefix']
- def getIncludeGuardPrefix(self):
+ def getIncludeGuardPrefix(self) -> str:
'''Return the replacement for ${gl_include_guard_prefix}.'''
return self.table['include_guard_prefix']
- def setMacroPrefix(self, macro_prefix):
+ def setMacroPrefix(self, macro_prefix: str) -> None:
'''Specify the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
Default macro_prefix is 'gl'.'''
if type(macro_prefix) is str:
include_guard_prefix = 'GL_%s' % macro_prefix.upper()
self.table['include_guard_prefix'] = include_guard_prefix
- def resetMacroPrefix(self):
+ def resetMacroPrefix(self) -> None:
'''Reset the prefix of the macros 'gl_EARLY' and 'gl_INIT'.
Default macro_prefix is 'gl'.'''
self.table['macro_prefix'] = 'gl'
self.table['include_guard_prefix'] = 'GL'
# Define makefile_name methods.
- def getMakefileName(self):
+ def getMakefileName(self) -> str:
'''Return the name of makefile in automake syntax in the sourcebase directory.
Default is 'Makefile.am'.'''
return self.table['makefile_name']
- def setMakefileName(self, makefile_name):
+ def setMakefileName(self, makefile_name: str) -> None:
'''Specify the name of makefile in automake syntax in the sourcebase directory.
Default is 'Makefile.am'.'''
if type(makefile_name) is str:
raise TypeError('makefile_name must be a string, not %s'
% type(makefile_name).__name__)
- def resetMakefileName(self):
+ def resetMakefileName(self) -> None:
'''Reset the name of makefile in automake syntax in the sourcebase directory.
Default is 'Makefile.am'.'''
self.table['makefile_name'] = ''
# Define tests_makefile_name methods.
- def getTestsMakefileName(self):
+ def getTestsMakefileName(self) -> str:
'''Return the name of makefile in automake syntax in the testsbase directory.
Default is the the value of 'makefile_name'.'''
return self.table['tests_makefile_name']
- def setTestsMakefileName(self, tests_makefile_name):
+ def setTestsMakefileName(self, tests_makefile_name: str) -> None:
'''Specify the name of makefile in automake syntax in the testsbase directory.
Default is the value of 'makefile_name'.'''
if type(tests_makefile_name) is str:
raise TypeError('tests_makefile_name must be a string, not %s'
% type(tests_makefile_name).__name__)
- def resetTestsMakefileName(self):
+ def resetTestsMakefileName(self) -> None:
'''Reset the name of makefile in automake syntax in the testsbase directory.
Default is the value of 'makefile_name'.'''
self.table['tests_makefile_name'] = ''
self.table['automake_subdir_tests'] = False
# Define podomain methods.
- def getPoDomain(self):
+ def getPoDomain(self) -> str:
'''Return the prefix of the i18n domain. Usually use the package name.
A suffix '-gnulib' is appended.'''
return self.table['podomain']
- def setPoDomain(self, podomain):
+ def setPoDomain(self, podomain: str) -> None:
'''Specify the prefix of the i18n domain. Usually use the package name.
A suffix '-gnulib' is appended.'''
if type(podomain) is str:
raise TypeError('podomain must be a string, not %s'
% type(podomain).__name__)
- def resetPoDomain(self):
+ def resetPoDomain(self) -> None:
'''Reset the prefix of the i18n domain. Usually use the package name.
A suffix '-gnulib' is appended.'''
self.table['podomain'] = ''
# Define witness_c_macro methods.
- def getWitnessCMacro(self):
+ def getWitnessCMacro(self) -> str:
'''Return the C macro that is defined when the sources in this directory
are compiled or used.'''
return self.table['witness_c_macro']
- def setWitnessCMacro(self, witness_c_macro):
+ def setWitnessCMacro(self, witness_c_macro: str) -> None:
'''Specify the C macro that is defined when the sources in this directory
are compiled or used.'''
if type(witness_c_macro) is str:
raise TypeError('witness_c_macro must be a string, not %s'
% type(witness_c_macro).__name__)
- def resetWitnessCMacro(self):
+ def resetWitnessCMacro(self) -> None:
'''Return the C macro that is defined when the sources in this directory
are compiled or used.'''
self.table['witness_c_macro'] = ''
# Define vc_files methods.
- def checkVCFiles(self):
+ def checkVCFiles(self) -> bool | None:
'''Check if update of the version control files is enabled or disabled.'''
return self.table['vc_files']
- def setVCFiles(self, value):
+ def setVCFiles(self, value: bool) -> None:
'''Enable /disable update of the version control files.'''
if type(value) is bool:
self.table['vc_files'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetVCFiles(self):
+ def resetVCFiles(self) -> None:
'''Reset update of the version control files and set it to None.'''
self.table['vc_files'] = None
# Define configure_ac methods.
- def getAutoconfFile(self):
+ def getAutoconfFile(self) -> str:
'''Return path of autoconf file relative to destdir.'''
return self.table['configure_ac']
- def setAutoconfFile(self, configure_ac):
+ def setAutoconfFile(self, configure_ac: str) -> None:
'''Specify path of autoconf file relative to destdir.'''
if type(configure_ac) is str:
if configure_ac:
raise TypeError('configure_ac must be a string, not %s'
% type(configure_ac).__name__)
- def resetAutoconfFile(self):
+ def resetAutoconfFile(self) -> None:
'''Reset path of autoconf file relative to destdir.'''
configure_ac = ''
if isfile(joinpath(self.table['destdir'], 'configure.ac')):
self.table['configure_ac'] = configure_ac
# Define ac_version methods.
- def getAutoconfVersion(self):
+ def getAutoconfVersion(self) -> float:
'''Return preferred autoconf version. Default value is 2.64.'''
return self.table['ac_version']
- def setAutoconfVersion(self, ac_version):
+ def setAutoconfVersion(self, ac_version: float | int) -> None:
'''Specify preferred autoconf version. Default value is 2.64.'''
if type(ac_version) is float or type(ac_version) is int:
self.table['ac_version'] = float(ac_version)
raise TypeError('ac_version must be an int or a float, not %s'
% type(ac_version).__name__)
- def resetAutoconfVersion(self):
+ def resetAutoconfVersion(self) -> None:
'''Specify preferred autoconf version. Default value is 2.64.'''
self.table['ac_version'] = 2.64
# Define copymode methods.
- def checkCopyMode(self):
+ def checkCopyMode(self) -> classes.CopyAction:
'''Check if pygnulib will copy files, create symlinks, or create hard links.'''
return self.table['copymode']
- def setCopyMode(self, value):
+ def setCopyMode(self, value: classes.CopyAction) -> None:
'''Change the method used for copying / linking files.'''
if type(value) is classes.CopyAction:
self.table['copymode'] = value
raise TypeError('value must be a CopyAction, not %s'
% type(value).__name__)
- def resetCopyMode(self):
+ def resetCopyMode(self) -> None:
'''Reset the method used for creating files to copying instead of linking.'''
self.table['copymode'] = classes.CopyAction.Copy
# Define lcopymode methods.
- def checkLCopyMode(self):
+ def checkLCopyMode(self) -> classes.CopyAction:
'''Check if pygnulib will copy files, create symlinks, or create hard links,
only for files from the local override directories.'''
return self.table['lcopymode']
- def setLCopyMode(self, value):
+ def setLCopyMode(self, value: classes.CopyAction) -> None:
'''Change the method used for copying / linking files, only for files from
the local override directories.'''
if type(value) is classes.CopyAction:
raise TypeError('value must be a CopyAction, not %s'
% type(value).__name__)
- def resetLCopyMode(self):
+ def resetLCopyMode(self) -> None:
'''Reset the method used for creating files to copying instead of linking,
only for files from the local override directories.'''
self.table['lcopymode'] = classes.CopyAction.Copy
# Define verbosity methods.
- def getVerbosity(self):
+ def getVerbosity(self) -> int:
'''Get verbosity level.'''
return self.table['verbosity']
- def decreaseVerbosity(self):
+ def decreaseVerbosity(self) -> None:
'''Decrease verbosity level.'''
if self.table['verbosity'] > MODES['verbose-min']:
self.table['verbosity'] -= 1
- def increaseVerbosity(self):
+ def increaseVerbosity(self) -> None:
'''Increase verbosity level.'''
if self.table['verbosity'] < MODES['verbose-max']:
self.table['verbosity'] += 1
- def setVerbosity(self, verbose):
+ def setVerbosity(self, verbose: int) -> None:
'''Set verbosity level to verbose, where -2 <= verbose <= 2.
If verbosity level is less than -2, verbosity level will be set to -2.
If verbosity level is greater than 2, verbosity level will be set to 2.'''
raise TypeError('verbosity must be an int, not %s'
% type(verbose).__name__)
- def resetVerbosity(self):
+ def resetVerbosity(self) -> None:
'''Reset verbosity level.'''
self.table['verbosity'] = 0
# Define libtests methods.
- def checkLibtests(self):
+ def checkLibtests(self) -> bool:
'''Return True if a testsbase/libtests.a is needed.'''
return self.table['libtests']
- def setLibtests(self, value):
+ def setLibtests(self, value: bool) -> None:
'''Specifies whether testsbase/libtests.a is needed.'''
if type(value) is bool:
self.table['libtests'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetLibtests(self):
+ def resetLibtests(self) -> None:
'''Reset status of testsbase/libtests.a.'''
self.table['libtests'] = False
# Define single_configure methods.
- def checkSingleConfigure(self):
+ def checkSingleConfigure(self) -> bool:
'''Check whether single configure file should be generated.'''
return self.table['single_configure']
- def setSingleConfigure(self, value):
+ def setSingleConfigure(self, value: bool) -> None:
'''Enable / disable generation of the single configure file.'''
if type(value) is bool:
self.table['single_configure'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetSingleConfigure(self):
+ def resetSingleConfigure(self) -> None:
'''Reset status of the single configure file generation.'''
self.table['single_configure'] = False
# Define dryrun methods.
- def checkDryRun(self):
+ def checkDryRun(self) -> bool:
'''Check whether dryrun is enabled.'''
return self.table['dryrun']
- def setDryRun(self, value):
+ def setDryRun(self, value: bool) -> None:
'''Enable / disable dryrun mode.'''
if type(value) is bool:
self.table['dryrun'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetDryRun(self):
+ def resetDryRun(self) -> None:
'''Reset status of dryrun mode.'''
self.table['dryrun'] = False
# Define errors methods.
- def checkErrors(self):
+ def checkErrors(self) -> bool:
'''Check if GLError will be raised in non-critical situations.'''
return self.table['errors']
- def setErrors(self, value):
+ def setErrors(self, value: bool) -> None:
'''Enable / disable raising GLError in non-critical situations.'''
if type(value) is bool:
self.table['errors'] = value
raise TypeError('value must be a bool, not %s'
% type(value).__name__)
- def resetErrors(self):
+ def resetErrors(self) -> None:
'''Reset status of raising GLError in non-critical situations.'''
self.table['errors'] = False
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
-# Allow the use of union type specifiers, using the syntax Type1 | Type2,
-# in Python ≥ 3.7. Cf. <https://docs.python.org/3/library/__future__.html>
-# and <https://stackoverflow.com/questions/73879925/>.
from __future__ import annotations
#===============================================================================
class GLEmiter(object):
'''This class is used to emit the contents of necessary files.'''
- def __init__(self, config):
- '''GLEmiter.__init__(config) -> GLEmiter
-
- Create GLEmiter instance.'''
+ def __init__(self, config: GLConfig) -> None:
+ '''Create GLEmiter instance.'''
self.info = GLInfo()
if type(config) is not GLConfig:
raise TypeError('config must be a GLConfig, not %s'
% type(config).__name__)
self.config = config
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__() <==> repr(x)'''
result = '<pygnulib.GLEmiter %s>' % hex(id(self))
return result
- def copyright_notice(self):
- '''GLEmiter.copyright_notice() -> str
-
- Emit a header for a generated file.'''
+ def copyright_notice(self) -> str:
+ '''Emit a header for a generated file.'''
emit = '# %s' % self.info.copyright_range()
emit += """
#
emit += ' gl_source_base_prefix=\n'
return emit
- def autoconfSnippet(self, module, toplevel,
- disable_libtool, disable_gettext, replace_auxdir, indentation):
- '''GLEmiter.autoconfSnippet(module, toplevel,
- disable_libtool, disable_gettext, replace_auxdir, indentation) -> str
-
- Emit the autoconf snippet of a module.
+ def autoconfSnippet(self, module: GLModule, toplevel: bool, disable_libtool: bool,
+ disable_gettext: bool, replace_auxdir: bool, indentation: str) -> str:
+ '''Emit the autoconf snippet of a module.
GLConfig: include_guard_prefix.
module is a GLModule instance, which is processed.
emit = lines_to_multiline(lines)
return emit
- def autoconfSnippets(self, modules, referenceable_modules, moduletable,
- verifier, toplevel, disable_libtool, disable_gettext, replace_auxdir):
- '''GLEmiter.autoconfSnippets(modules,
- verifier, toplevel, disable_libtool, disable_gettext, replace_auxdir) -> str
-
- Collect and emit the autoconf snippets of a set of modules.
+ def autoconfSnippets(self, modules: list[GLModule], referenceable_modules: list[GLModule],
+ moduletable: GLModuleTable, verifier: int, toplevel: bool,
+ disable_libtool: bool, disable_gettext: bool, replace_auxdir: bool) -> str:
+ '''Collect and emit the autoconf snippets of a set of modules.
GLConfig: conddeps.
basemodules argument represents list of modules; every module in this list
emit = lines_to_multiline(lines)
return emit
- def preEarlyMacros(self, require, indentation, modules):
- '''GLEmiter.preEarlyMacros(require, indentation, modules) -> str
-
- Collect and emit the pre-early section.
+ def preEarlyMacros(self, require: bool, indentation: str, modules: list[GLModule]) -> str:
+ '''Collect and emit the pre-early section.
require parameter can be True (AC_REQUIRE) or False (direct call).
indentation parameter is a string.
emit += '\n'
return emit
- def po_Makevars(self):
- '''GLEmiter.po_Makevars() -> str
-
- Emit the contents of po/ makefile parameterization.
+ def po_Makevars(self) -> str:
+ '''Emit the contents of po/ makefile parameterization.
GLConfig: pobase, podomain.'''
pobase = self.config['pobase']
podomain = self.config['podomain']
USE_MSGCTXT = no\n"""
return emit
- def po_POTFILES_in(self, files):
- '''GLEmiter.po_POTFILES_in(files) -> str
-
- Emit the file list to be passed to xgettext.
+ def po_POTFILES_in(self, files: list[str]) -> str:
+ '''Emit the file list to be passed to xgettext.
GLConfig: sourcebase.'''
sourcebase = self.config['sourcebase'] + os.path.sep
emit = ''
emit += '%s\n' % constants.substart('lib/', sourcebase, file)
return emit
- def initmacro_start(self, macro_prefix_arg, gentests):
- '''GLEmiter.initmacro_start(macro_prefix_arg, gentests) -> str
-
- Emit the first few statements of the gl_INIT macro.
+ def initmacro_start(self, macro_prefix_arg: str, gentests: bool) -> str:
+ '''Emit the first few statements of the gl_INIT macro.
macro_prefix_arg is the prefix of gl_EARLY and gl_INIT macros to use.
gentests is True if a tests Makefile.am is being generated, False
emit += ' AC_REQUIRE([gl_CXX_ALLOW_WARNINGS])\n'
return emit
- def initmacro_end(self, macro_prefix_arg, gentests):
- '''GLEmiter.initmacro_end(macro_prefix_arg) -> str
-
- Emit the last few statements of the gl_INIT macro.
+ def initmacro_end(self, macro_prefix_arg: str, gentests: bool) -> str:
+ '''Emit the last few statements of the gl_INIT macro.
macro_prefix_arg is the prefix of gl_EARLY, gl_INIT macros to use.
gentests is a bool that is True if a tests Makefile.am is being
'''
return emit
- def initmacro_done(self, macro_prefix_arg, sourcebase_arg):
- '''GLEmiter.initmacro_done(macro_prefix_arg, sourcebase_arg) -> str
-
- Emit a few statements after the gl_INIT macro.
+ def initmacro_done(self, macro_prefix_arg: str, sourcebase_arg: str) -> str:
+ '''Emit a few statements after the gl_INIT macro.
GLConfig: sourcebase.'''
if type(macro_prefix_arg) is not str:
raise TypeError('macro_prefix_arg must be a string, not %s'
emit = emit.replace('%V2%', sourcebase_arg)
return emit
- def lib_Makefile_am(self, destfile, modules,
- moduletable, makefiletable, actioncmd, for_test):
- '''GLEmiter.lib_Makefile_am(destfile, modules, moduletable, makefiletable,
- actioncmd, for_test) -> tuple of str and bool
-
- Emit the contents of the library Makefile. Returns str and a bool
+ def lib_Makefile_am(self, destfile: str, modules: list[GLModule], moduletable: GLModuleTable,
+ makefiletable: GLMakefileTable, actioncmd: str, for_test: bool) -> tuple[str, bool]:
+ '''Emit the contents of the library Makefile. Returns str and a bool
variable which shows if subdirectories are used.
GLConfig: localpath, sourcebase, libname, pobase, auxdir, makefile_name, libtool,
macro_prefix, podomain, conddeps, witness_c_macro.
result = tuple([emit, uses_subdirs])
return result
- def tests_Makefile_am(self, destfile, modules, moduletable,
- makefiletable, witness_macro, for_test):
- '''GLEmiter.tests_Makefile_am(destfile, modules, moduletable,
- makefiletable, witness_c_macro, for_test) -> tuple of string and bool
-
- Emit the contents of the tests Makefile. Returns str and a bool variable
+ def tests_Makefile_am(self, destfile: str, modules: list[GLModule], moduletable: GLModuleTable,
+ makefiletable: GLMakefileTable, witness_macro: str, for_test: bool) -> tuple[str, bool]:
+ '''Emit the contents of the tests Makefile. Returns str and a bool variable
which shows if subdirectories are used.
GLConfig: localpath, modules, libname, auxdir, makefile_name, libtool,
sourcebase, m4base, testsbase, macro_prefix, witness_c_macro,
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
class GLError(Exception):
'''Exception handler for pygnulib classes.'''
- def __init__(self, errno, errinfo=None):
+ def __init__(self, errno: int, errinfo: str | float | None = None) -> None:
'''Each error has following parameters:
errno: code of error; used to catch error type
1: file does not exist in GLFileSystem: <file>
self.errinfo = errinfo
self.args = (self.errno, self.errinfo)
- def __repr__(self):
+ def __repr__(self) -> str:
errno = self.errno
errinfo = self.errinfo
if self.message == None:
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
Its main method lookup(file) is used to find file in these directories or
combine it using Linux 'patch' utility.'''
- def __init__(self, config):
+ def __init__(self, config: GLConfig) -> None:
'''Create new GLFileSystem instance. The only argument is localpath,
which can be an empty list.'''
if type(config) is not GLConfig:
% type(config).__name__)
self.config = config
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__ <==> repr(x)'''
result = '<pygnulib.GLFileSystem %s>' % hex(id(self))
return result
- def lookup(self, name):
- '''GLFileSystem.lookup(name) -> tuple
-
- Lookup a file in gnulib and localpath directories or combine it using
+ def lookup(self, name: str) -> tuple[str, bool]:
+ '''Lookup a file in gnulib and localpath directories or combine it using
'patch' utility. If file was found, method returns string, else it raises
GLError telling that file was not found. Function also returns flag which
indicates whether file is a temporary file.
raise GLError(1, name)
return result
- def shouldLink(self, original, lookedup):
+ def shouldLink(self, original: str, lookedup: str) -> bool:
'''GLFileSystem.shouldLink(original, lookedup)
Determines whether the original file should be copied, symlinked,
class GLFileAssistant(object):
'''GLFileAssistant is used to help with file processing.'''
- def __init__(self, config, transformers=dict()):
+ def __init__(self, config: GLConfig, transformers: dict = dict()):
'''Create GLFileAssistant instance.'''
if type(config) is not GLConfig:
raise TypeError('config must be a GLConfig, not %s'
self.transformers = transformers
self.filesystem = GLFileSystem(self.config)
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__() <==> repr(x)'''
result = '<pygnulib.GLFileAssistant %s>' % hex(id(self))
return result
- def tmpfilename(self, path):
- '''GLFileAssistant.tmpfilename() -> str
-
- Return the name of a temporary file (file is relative to destdir).'''
+ def tmpfilename(self, path: str) -> str:
+ '''Return the name of a temporary file (file is relative to destdir).'''
if type(path) is not str:
raise TypeError('path must be a string, not %s'
% (type(path).__name__))
os.makedirs(dirname)
return result
- def setOriginal(self, original):
- '''GLFileAssistant.setOriginal(original)
-
- Set the name of the original file which will be used.'''
+ def setOriginal(self, original: str) -> None:
+ '''Set the name of the original file which will be used.'''
if type(original) is not str:
raise TypeError('original must be a string, not %s'
% (type(original).__name__))
self.original = original
- def setRewritten(self, rewritten):
- '''GLFileAssistant.setRewritten(rewritten)
-
- Set the name of the rewritten file which will be used.'''
+ def setRewritten(self, rewritten: str) -> None:
+ '''Set the name of the rewritten file which will be used.'''
if type(rewritten) is not str:
raise TypeError('rewritten must be a string, not %s'
% type(rewritten).__name__)
self.rewritten = rewritten
- def addFile(self, file):
- '''GLFileAssistant.addFile(file)
-
- Add file to the list of added files.'''
+ def addFile(self, file: str) -> None:
+ '''Add file to the list of added files.'''
if file not in self.added:
self.added += [file]
- def removeFile(self, file):
- '''GLFileAssistant.removeFile(file)
-
- Remove file from the list of added files.'''
+ def removeFile(self, file: str) -> None:
+ '''Remove file from the list of added files.'''
if file in self.added:
self.added.pop(file)
- def getFiles(self):
+ def getFiles(self) -> list[str]:
'''Return list of the added files.'''
return list(self.added)
- def add(self, lookedup, tmpflag, tmpfile):
- '''GLFileAssistant.add(lookedup, tmpflag, tmpfile)
-
- This method copies a file from gnulib into the destination directory.
+ def add(self, lookedup: str, tmpflag: bool, tmpfile: str) -> None:
+ '''This method copies a file from gnulib into the destination directory.
The destination is known to exist. If tmpflag is True, then lookedup file
is a temporary one.'''
original = self.original
else: # if self.config['dryrun']
print('Copy file %s' % rewritten)
- def update(self, lookedup, tmpflag, tmpfile, already_present):
- '''GLFileAssistant.update(lookedup, tmpflag, tmpfile, already_present)
-
- This method copies a file from gnulib into the destination directory.
+ def update(self, lookedup: str, tmpflag: bool, tmpfile: str, already_present: bool) -> None:
+ '''This method copies a file from gnulib into the destination directory.
The destination is known to exist. If tmpflag is True, then lookedup file
is a temporary one.'''
original = self.original
else: # if not already_present
print('Replace file %s (backup in %s)' % (rewritten, backupname))
- def add_or_update(self, already_present):
- '''GLFileAssistant.add_or_update(already_present)
-
- This method handles a file that ought to be present afterwards.'''
+ def add_or_update(self, already_present: bool) -> None:
+ '''This method handles a file that ought to be present afterwards.'''
original = self.original
rewritten = self.rewritten
if original == None:
if isfile(tmpfile):
os.remove(tmpfile)
- def super_update(self, basename, tmpfile):
- '''GLFileAssistant.super_update(basename, tmpfile) -> tuple
-
- Move tmpfile to destdir/basename path, making a backup of it.
+ def super_update(self, basename: str, tmpfile: str) -> tuple[str, str, int]:
+ '''Move tmpfile to destdir/basename path, making a backup of it.
Returns tuple, which contains basename, backupname and status.
0: tmpfile is the same as destfile;
1: tmpfile was used to update destfile;
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
scripts. However, if user needs just to use power of gnulib-tool, this class
is a very good choice.'''
- def __init__(self, config, mode):
+ def __init__(self, config: GLConfig, mode: int) -> None:
'''Create GLImport instance.
The first variable, mode, must be one of the values of the MODES dict
object, which is accessible from constants module. The second one, config,
self.config.checkInclTestCategory(TESTS['all-tests']))
self.makefiletable = GLMakefileTable(self.config)
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__ <==> repr(x)'''
result = '<pygnulib.GLImport %s>' % hex(id(self))
return result
- def rewrite_old_files(self, files):
- '''GLImport.rewrite_old_files(files) -> list
-
- Replace auxdir, docbase, sourcebase, m4base and testsbase from default
+ def rewrite_old_files(self, files: list[str]) -> list[str]:
+ '''Replace auxdir, docbase, sourcebase, m4base and testsbase from default
to their version from cached config.'''
if type(files) is not list:
raise TypeError('files argument must has list type, not %s'
result = sorted(set(result))
return list(result)
- def rewrite_new_files(self, files):
- '''GLImport.rewrite_new_files(files)
-
- Replace auxdir, docbase, sourcebase, m4base and testsbase from default
- to their version from config.'''
+ def rewrite_new_files(self, files: list[str]) -> list[str]:
+ '''Replace auxdir, docbase, sourcebase, m4base and testsbase from
+ default to their version from config.'''
if type(files) is not list:
raise TypeError('files argument must has list type, not %s'
% type(files).__name__)
result = sorted(set(result))
return list(result)
- def actioncmd(self):
+ def actioncmd(self) -> str:
'''Return command-line invocation comment.'''
modules = self.config.getModules()
avoids = self.config.getAvoids()
actioncmd += ''.join([f' \\\n# {x}' for x in modules])
return actioncmd
- def relative_to_destdir(self, dir):
- '''GLImport.relative_to_destdir(dir) -> str
-
- Convert a filename that represents dir, relative to the current directory,
- to a filename relative to destdir.
+ def relative_to_destdir(self, dir: str) -> str:
+ '''Convert a filename that represents dir, relative to the current
+ directory, to a filename relative to destdir.
GLConfig: destdir.'''
destdir = self.config['destdir']
if dir.startswith('/'):
else:
return constants.relativize(destdir, dir)
- def relative_to_currdir(self, dir):
- '''GLImport.relative_to_currdir(dir) -> str
-
- The opposite of GLImport.relative_to_destdir:
+ def relative_to_currdir(self, dir: str) -> str:
+ '''The opposite of GLImport.relative_to_destdir:
Convert a filename that represents dir, relative to destdir,
to a filename relative to the current directory.
GLConfig: destdir.'''
else:
return constants.relconcat(destdir, dir)
- def gnulib_cache(self):
- '''GLImport.gnulib_cache() -> str
-
- Emit the contents of generated $m4base/gnulib-cache.m4 file.
+ def gnulib_cache(self) -> str:
+ '''Emit the contents of generated $m4base/gnulib-cache.m4 file.
GLConfig: destdir, localpath, tests, sourcebase, m4base, pobase, docbase,
testsbase, conddeps, libtool, macro_prefix, podomain, vc_files.'''
emit = ''
emit += 'gl_VC_FILES([%s])\n' % str(vc_files).lower()
return constants.nlconvert(emit)
- def gnulib_comp(self, filetable, gentests):
- '''GLImport.gnulib_comp(files) -> str
-
- Emit the contents of generated $m4base/gnulib-comp.m4 file.
+ def gnulib_comp(self, filetable: dict[str, list[str]], gentests: bool) -> str:
+ '''Emit the contents of generated $m4base/gnulib-comp.m4 file.
GLConfig: destdir, localpath, tests, sourcebase, m4base, pobase, docbase,
testsbase, conddeps, libtool, macro_prefix, podomain, vc_files.
emit += '])\n'
return emit
- def _done_dir_(self, directory, files_added, files_removed):
- '''GLImport._done_dir_(directory, files_added, files_removed)
-
- This method is used to determine ignore argument for _update_ignorelist_
+ def _done_dir_(self, directory: str, files_added: list[str], files_removed: list[str]) -> None:
+ '''This method is used to determine ignore argument for _update_ignorelist_
method and then call it.'''
destdir = self.config['destdir']
if (isdir(joinpath(destdir, 'CVS'))
self._update_ignorelist_(directory, '.gitignore',
files_added, files_removed)
- def _update_ignorelist_(self, directory, ignore, files_added, files_removed):
- '''GLImport._update_ignorelist_(directory, ignore, files_added, files_removed)
-
- Update .gitignore or .cvsignore files.'''
+ def _update_ignorelist_(self, directory: str, ignore: str, files_added: list[str],
+ files_removed: list[str]) -> None:
+ '''Update .gitignore or .cvsignore files.'''
destdir = self.config['destdir']
if ignore == '.gitignore':
# In a .gitignore file, "foo" applies to the current directory and all
else: # if self.config['dryrun']
print('Create %s' % srcpath)
- def prepare(self):
+ def prepare(self) -> tuple[dict[str, list[str]], dict[str, str]]:
'''Make all preparations before the execution of the code.
Returns filetable and sed transformers, which change the license.'''
destdir = self.config['destdir']
result = tuple([filetable, transformers])
return result
- def execute(self, filetable, transformers):
+ def execute(self, filetable: dict[str, list[str]], transformers: dict[str, str]) -> None:
'''Perform operations on the lists of files, which are given in a special
format except filelist argument. Such lists of files can be created using
GLImport.prepare() function.'''
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
anywhere else. The return values are not the same as for the module,
but still depends on them.'''
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__ <==> repr(x)'''
result = '<pygnulib.GLInfo %s>' % hex(id(self))
return result
- def package(self):
+ def package(self) -> str:
'''Return formatted string which contains name of the package.'''
result = 'GNU gnulib'
return result
- def authors(self):
+ def authors(self) -> str:
'''Return formatted string which contains authors.
The special __author__ variable is used (type is list).'''
result = ''
result += '%s, ' % item
return result
- def license(self):
+ def license(self) -> str:
'''Return formatted string which contains license and its description.'''
result = 'License GPLv3+: GNU GPL version 3 or later <https://gnu.org/licenses/gpl.html>\n'
result += 'This is free software: you are free to change and redistribute it.\n'
result += 'There is NO WARRANTY, to the extent permitted by law.'
return result
- def copyright(self):
+ def copyright(self) -> str:
'''Return formatted string which contains copyright.
The special __copyright__ variable is used (type is str).'''
copyright = __copyright__
result = 'Copyright (C) %s' % copyright
return result
- def date(self):
+ def date(self) -> str:
'''Return formatted string which contains date and time in GMT format.'''
if isdir(DIRS['git']):
have_git = None
result = re.compile(r' .*').sub(r'', first_changelog_line)
return result
- def copyright_range(self):
+ def copyright_range(self) -> str:
'''Returns a formatted copyright string showing a year range.'''
return f'Copyright (C) {constants.__copyright__}'
- def usage(self):
+ def usage(self) -> str:
'''Show help message.'''
result = '''\
Usage: gnulib-tool --list
Report bugs to <bug-gnulib@gnu.org>.'''
return result
- def version(self):
+ def version(self) -> str:
'''Return formatted string which contains git version.'''
if isdir(DIRS['git']):
have_git = None
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
'''This class is used to edit Makefile and store edits as table.
When user creates Makefile, he may need to use this class.'''
- def __init__(self, config):
- '''GLMakefileTable.__init__(config) -> GLMakefileTable
-
- Create GLMakefileTable instance.'''
+ def __init__(self, config: GLConfig) -> None:
+ '''Create GLMakefileTable instance.'''
if type(config) is not GLConfig:
raise TypeError('config must be a GLConfig, not %s'
% type(config).__name__)
self.config = config
self.table = list()
- def __getitem__(self, y):
+ def __getitem__(self, y: int) -> dict[str, bool]:
'''x.__getitem__(y) = x[y]'''
if type(y) is not int:
raise TypeError('indices must be integers, not %s'
result = self.table[y]
return dict(result)
- def editor(self, dir, var, val, dotfirst=False):
- '''GLMakefileTable.editor(dir, var, val, dotfirst)
-
- This method is used to remember that ${dir}Makefile.am needs to be edited
+ def editor(self, dir: str, var: str, val: str, dotfirst: bool = False) -> None:
+ '''This method is used to remember that ${dir}Makefile.am needs to be edited
to that ${var} mentions ${val}.
If ${dotfirst} is non-empty, this mention needs to be present after '.'.
This is a special hack for the SUBDIRS variable, cf.
dictionary = {'dir': dir, 'var': var, 'val': val, 'dotfirst': dotfirst}
self.table += [dictionary]
- def parent(self, gentests, source_makefile_am, tests_makefile_am):
- '''GLMakefileTable.parent(gentests)
-
- Add a special row to Makefile.am table with the first parent directory
+ def parent(self, gentests: bool, source_makefile_am: str, tests_makefile_am: str) -> None:
+ '''Add a special row to Makefile.am table with the first parent directory
which contains or will contain Makefile.am file.
GLConfig: sourcebase, m4base, testsbase, incl_test_categories,
excl_test_categories, makefile_name.
dir1 = os.path.dirname(dir1)
self.editor(dir1, 'EXTRA_DIST', joinpath(dir2, 'gnulib-cache.m4'))
- def count(self):
- '''GLMakefileTable.count() -> int
-
- Count number of edits which were applied.'''
+ def count(self) -> int:
+ '''Count number of edits which were applied.'''
return len(self.table)
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
'''GLModuleSystem is used to operate with module system using dynamic
searching and patching.'''
- def __init__(self, config):
- '''GLModuleSystem.__init__(config) -> GLModuleSystem
-
- Create new GLModuleSystem instance. Some functions use GLFileSystem class
+ def __init__(self, config: GLConfig) -> None:
+ '''Create new GLModuleSystem instance. Some functions use GLFileSystem class
to look up a file in localpath or gnulib directories, or combine it through
'patch' utility.'''
self.args = dict()
self.config = config
self.filesystem = GLFileSystem(self.config)
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__ <==> repr(x)'''
result = '<pygnulib.GLModuleSystem %s>' % hex(id(self))
return result
- def exists(self, module):
- '''GLModuleSystem.exists(module) -> bool
-
- Check whether the given module exists.
+ def exists(self, module: str) -> bool:
+ '''Check whether the given module exists.
GLConfig: localpath.'''
if type(module) is not str:
raise TypeError('module must be a string, not %s'
break
return result
- def find(self, module):
- '''GLModuleSystem.find(module) -> GLModule
-
- Find the given module.'''
+ def find(self, module: str) -> GLModule | None:
+ '''Find the given module.'''
if type(module) is not str:
raise TypeError('module must be a string, not %s'
% type(module).__name__)
sys.stderr.write('gnulib-tool: warning: ')
sys.stderr.write('file %s does not exist\n' % str(module))
- def file_is_module(self, filename):
+ def file_is_module(self, filename: str) -> bool:
'''Given the name of a file in the modules/ directory, return true
if should be viewed as a module description file.'''
return not (filename == 'ChangeLog' or filename.endswith('/ChangeLog')
or filename.endswith('.rej')
or filename.endswith('~'))
- def list(self):
- '''GLModuleSystem.list() -> list
-
- Return the available module names as tuple. We could use a combination
+ def list(self) -> list[str]:
+ '''Return the available module names as tuple. We could use a combination
of os.walk() function and re module. However, it takes too much time to
complete, so this version uses subprocess to run shell commands.'''
result = ''
# List of characters allowed in shell identifiers.
shell_id_chars = 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_'
- def __init__(self, config, path, patched=False):
- '''GLModule.__init__(config, path[, patched]) -> GLModule
-
- Create new GLModule instance. Arguments are path and patched, where
+ def __init__(self, config: GLConfig, path: str, patched: bool = False) -> None:
+ '''Create new GLModule instance. Arguments are path and patched, where
path is a string representing the path to the module and patched is a
bool indicating that module was created after applying patch.'''
self.args = dict()
if last_section_label != None:
self.sections[last_section_label] = self.content[last_section_start:]
- def __eq__(self, module):
+ def __eq__(self, module: object) -> bool:
'''x.__eq__(y) <==> x==y'''
result = False
if type(module) is GLModule:
result = True
return result
- def __ne__(self, module):
+ def __ne__(self, module: object) -> bool:
'''x.__ne__(y) <==> x!=y'''
result = False
if type(module) is GLModule:
result = True
return result
- def __ge__(self, module):
+ def __ge__(self, module: object) -> bool:
'''x.__ge__(y) <==> x>=y'''
result = False
if type(module) is GLModule:
result = True
return result
- def __gt__(self, module):
+ def __gt__(self, module: object) -> bool:
'''x.__gt__(y) <==> x>y'''
result = False
if type(module) is GLModule:
result = True
return result
- def __hash__(self):
+ def __hash__(self) -> int:
'''x.__hash__() <==> hash(x)'''
result = hash(self.path) ^ hash(self.patched)
return result
- def __le__(self, module):
+ def __le__(self, module: object) -> bool:
'''x.__le__(y) <==> x<=y'''
result = False
if type(module) is GLModule:
result = True
return result
- def __lt__(self, module):
+ def __lt__(self, module: object) -> bool:
'''x.__lt__(y) <==> x<y'''
result = False
if type(module) is GLModule:
result = True
return result
- def __str__(self):
+ def __str__(self) -> str:
'''x.__str__() <==> str(x)'''
result = self.getName()
return result
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__ <==> repr(x)'''
result = '<pygnulib.GLModule %s %s>' % (repr(self.getName()), hex(id(self)))
return result
- def getName(self):
- '''GLModule.getName() -> str
-
- Return the name of the module.'''
+ def getName(self) -> str:
+ '''Return the name of the module.'''
pattern = re.compile(joinpath('modules', '(.*)$'))
result = pattern.findall(self.path)[0]
return result
- def isPatched(self):
- '''GLModule.isPatched() -> bool
-
- Check whether module was created after applying patch.'''
+ def isPatched(self) -> bool:
+ '''Check whether module was created after applying patch.'''
return self.patched
- def isTests(self):
- '''GLModule.isTests() -> bool
-
- Check whether module is a *-tests module or a module of
+ def isTests(self) -> bool:
+ '''Check whether module is a *-tests module or a module of
applicability 'all'.'''
result = self.getApplicability() != 'main'
return result
- def isNonTests(self):
- '''GLModule.isNonTests() -> bool
-
- Check whether module is not a *-tests module.'''
+ def isNonTests(self) -> bool:
+ '''Check whether module is not a *-tests module.'''
result = not self.getName().endswith('-tests')
return result
- def getTestsName(self):
+ def getTestsName(self) -> str:
'''Return -tests version of the module name.'''
result = self.getName()
if not result.endswith('-tests'):
result += '-tests'
return result
- def getTestsModule(self):
+ def getTestsModule(self) -> GLModule | None:
'''Return -tests version of the module as GLModule.'''
result = self.modulesystem.find(self.getTestsName())
return result
for line in section.splitlines() })
return lines_to_multiline(directives)
- def getShellFunc(self):
- '''GLModule.getShellFunc() -> str
-
- Computes the shell function name that will contain the m4 macros for the
- module.'''
+ def getShellFunc(self) -> str:
+ '''Computes the shell function name that will contain the m4 macros
+ for the module.'''
macro_prefix = self.config['macro_prefix']
valid_shell_id = True
for char in self.getName():
result = 'func_%s_gnulib_m4code_%s' % (macro_prefix, identifier)
return result
- def getShellVar(self):
- '''GLModule.getShellVar() -> str
-
- Compute the shell variable name the will be set to true once the m4 macros
- for the module have been executed.'''
+ def getShellVar(self) -> str:
+ '''Compute the shell variable name the will be set to true once the
+ m4 macros for the module have been executed.'''
macro_prefix = self.config['macro_prefix']
valid_shell_id = True
for char in self.getName():
result = '%s_gnulib_enabled_%s' % (macro_prefix, identifier)
return result
- def getConditionalName(self):
- '''GLModule.getConditionalName() -> str
-
- Return the automake conditional name.
+ def getConditionalName(self) -> str:
+ '''Return the automake conditional name.
GLConfig: macro_prefix.'''
macro_prefix = self.config['macro_prefix']
valid_shell_id = True
result = '%s_GNULIB_ENABLED_%s' % (macro_prefix, identifier)
return result
- def getDescription(self):
- '''GLModule.getDescription() -> str
-
- Return description of the module.'''
+ def getDescription(self) -> str:
+ '''Return description of the module.'''
return self.sections.get('Description', '')
- def getComment(self):
- '''GLModule.getComment() -> str
-
- Return comment to module.'''
+ def getComment(self) -> str:
+ '''Return comment to module.'''
return self.sections.get('Comment', '')
- def getStatus(self):
- '''GLModule.getStatus() -> str
-
- Return module status.'''
+ def getStatus(self) -> str:
+ '''Return module status.'''
return self.sections.get('Status', '')
- def getStatuses(self):
- '''GLModule.getStatuses() -> list
-
- Return module status.'''
+ def getStatuses(self) -> list[str]:
+ '''Return module status.'''
if 'statuses' not in self.cache:
snippet = self.getStatus()
result = [ line.strip()
self.cache['statuses'] = result
return self.cache['statuses']
- def getNotice(self):
- '''GLModule.getNotice() -> str
-
- Return notice to module.'''
+ def getNotice(self) -> str:
+ '''Return notice to module.'''
return self.sections.get('Notice', '')
- def getApplicability(self):
- '''GLModule.getApplicability() -> str
-
- Return applicability of module.'''
+ def getApplicability(self) -> str:
+ '''Return applicability of module.'''
if 'applicability' not in self.cache:
result = self.sections.get('Applicability', '')
result = result.strip()
'''Return the unmodified list of files as a string.'''
return self.sections.get('Files', '')
- def getFiles(self):
- '''GLModule.getFiles() -> list
-
- Return list of files.
+ def getFiles(self) -> list[str]:
+ '''Return list of files.
GLConfig: ac_version.'''
if 'files' not in self.cache:
snippet = self.getFiles_Raw()
self.cache['files'] = result
return self.cache['files']
- def getDependencies(self):
- '''GLModule.getDependencies() -> str
-
- Return list of dependencies, as a snippet.
+ def getDependencies(self) -> str:
+ '''Return list of dependencies, as a snippet.
GLConfig: localpath.'''
if 'dependencies' not in self.cache:
result = ''
self.cache['dependencies'] = result
return self.cache['dependencies']
- def getDependenciesWithoutConditions(self):
- '''GLModule.getDependenciesWithoutConditions() -> list
-
- Return list of dependencies, as a list of GLModule objects.
+ def getDependenciesWithoutConditions(self) -> list[GLModule | None]:
+ '''Return list of dependencies, as a list of GLModule objects.
GLConfig: localpath.'''
if 'dependenciesWithoutCond' not in self.cache:
snippet = self.getDependencies()
self.cache['dependenciesWithoutCond'] = result
return self.cache['dependenciesWithoutCond']
- def getDependenciesWithConditions(self):
- '''GLModule.getDependenciesWithConditions() -> list
-
- Return list of dependencies, as a list of pairs (GLModule object, condition).
+ def getDependenciesWithConditions(self) -> list[tuple[GLModule, str | None]]:
+ '''Return list of dependencies, as a list of pairs (GLModule object, condition).
The "true" condition is denoted by None.
GLConfig: localpath.'''
self.cache['dependenciesWithCond'] = result
return self.cache['dependenciesWithCond']
- def getAutoconfEarlySnippet(self):
- '''GLModule.getAutoconfEarlySnippet() -> str
-
- Return autoconf-early snippet.'''
+ def getAutoconfEarlySnippet(self) -> str:
+ '''Return autoconf-early snippet.'''
return self.sections.get('configure.ac-early', '')
- def getAutoconfSnippet(self):
- '''GLModule.getAutoconfSnippet() -> str
-
- Return autoconf snippet.'''
+ def getAutoconfSnippet(self) -> str:
+ '''Return autoconf snippet.'''
return self.sections.get('configure.ac', '')
- def getAutomakeSnippet(self):
- '''getAutomakeSnippet() -> str
-
- Get automake snippet.
+ def getAutomakeSnippet(self) -> str:
+ '''Get automake snippet.
GLConfig: auxdir, ac_version.'''
result = ''
conditional = self.getAutomakeSnippet_Conditional()
result += self.getAutomakeSnippet_Unconditional()
return result
- def getAutomakeSnippet_Conditional(self):
- '''GLModule.getAutomakeSnippet_Conditional() -> str
-
- Return conditional automake snippet.'''
+ def getAutomakeSnippet_Conditional(self) -> str:
+ '''Return conditional automake snippet.'''
return self.sections.get('Makefile.am', '')
- def getAutomakeSnippet_Unconditional(self):
- '''GLModule.getAutomakeSnippet_Unconditional() -> str
-
- Return unconditional automake snippet.
+ def getAutomakeSnippet_Unconditional(self) -> str:
+ '''Return unconditional automake snippet.
GLConfig: auxdir, ac_version.'''
auxdir = self.config['auxdir']
ac_version = self.config['ac_version']
self.cache['makefile-unconditional'] = result
return self.cache['makefile-unconditional']
- def getInclude(self):
- '''GLModule.getInclude() -> str
-
- Return include directive.'''
+ def getInclude(self) -> str:
+ '''Return include directive.'''
if 'include' not in self.cache:
snippet = self.sections.get('Include', '')
pattern = re.compile(r'^(["<])', re.M)
self.cache['include'] = result
return self.cache['include']
- def getLink(self):
- '''GLModule.getLink() -> str
-
- Return link directive.'''
+ def getLink(self) -> str:
+ '''Return link directive.'''
return self.sections.get('Link', '')
- def getLicense_Raw(self):
- '''GLModule.getLicense_Raw() -> str
-
- Return module license.'''
+ def getLicense_Raw(self) -> str:
+ '''Return module license.'''
return self.sections.get('License', '')
- def getLicense(self):
- '''GLModule.getLicense(self) -> str
-
- Get license and warn user if module lacks a license.'''
+ def getLicense(self) -> str:
+ '''Get license and warn user if module lacks a license.'''
if 'license' not in self.cache:
license = self.getLicense_Raw().strip()
# Warn if the License field is missing.
self.cache['license'] = result
return self.cache['license']
- def getMaintainer(self):
- '''GLModule.getMaintainer() -> str
-
- Return maintainer directive.'''
+ def getMaintainer(self) -> str:
+ '''Return maintainer directive.'''
return self.sections.get('Maintainer', '')
class GLModuleTable(object):
'''GLModuleTable is used to work with the list of the modules.'''
- def __init__(self, config, inc_all_direct_tests, inc_all_indirect_tests):
- '''GLModuleTable.__init__(config, inc_all_direct_tests, inc_all_indirect_tests) -> GLModuleTable
-
- Create new GLModuleTable instance. If modules are specified, then add
+ def __init__(self, config: GLConfig, inc_all_direct_tests: bool, inc_all_indirect_tests: bool) -> None:
+ '''Create new GLModuleTable instance. If modules are specified, then add
every module from iterable as unconditional module. If avoids is specified,
then in transitive_closure every dependency which is in avoids won't be
included in the final modules list. If conddeps are enabled,
if module:
self.avoids.append(module)
- def __repr__(self):
+ def __repr__(self) -> str:
'''x.__repr__() <==> repr(x)'''
result = '<pygnulib.GLModuleTable %s>' % hex(id(self))
return result
- def __getitem__(self, y):
+ def __getitem__(self, y: str) -> list[GLModule]:
'''x.__getitem__(y) <==> x[y]'''
if y in ['base', 'final', 'main', 'tests', 'avoids']:
if y == 'base':
else: # if y is not in list
raise KeyError('GLModuleTable does not contain key: %s' % repr(y))
- def addConditional(self, parent, module, condition):
- '''GLModuleTable.addConditional(module, condition)
-
- Add new conditional dependency from parent to module with condition.'''
+ def addConditional(self, parent: GLModule, module: GLModule, condition: str | bool) -> None:
+ '''Add new conditional dependency from parent to module with condition.'''
if type(parent) is not GLModule:
raise TypeError('parent must be a GLModule, not %s'
% type(parent).__name__)
key = '%s---%s' % (str(parent), str(module))
self.conditionals[key] = condition
- def addUnconditional(self, module):
- '''GLModuleTable.addUnconditional(module)
-
- Add module as unconditional dependency.'''
+ def addUnconditional(self, module: GLModule) -> None:
+ '''Add module as unconditional dependency.'''
if type(module) is not GLModule:
raise TypeError('module must be a GLModule, not %s'
% type(module).__name__)
if str(module) in self.dependers:
self.dependers.pop(str(module))
- def isConditional(self, module):
- '''GLModuleTable.isConditional(module) -> bool
-
- Check whether module is unconditional.'''
+ def isConditional(self, module: GLModule) -> bool:
+ '''Check whether module is unconditional.'''
if type(module) is not GLModule:
raise TypeError('module must be a GLModule, not %s'
% type(module).__name__)
result = str(module) in self.dependers
return result
- def getCondition(self, parent, module):
- '''GLModuleTable.getCondition(module) -> str or True
-
- Return condition from parent to module. Condition can be string or True.
+ def getCondition(self, parent: GLModule, module: GLModule) -> str | bool:
+ '''Return condition from parent to module. Condition can be string or True.
If module is not in the list of conddeps, method returns None.'''
if type(parent) is not GLModule:
raise TypeError('parent must be a GLModule, not %s'
result = self.conditionals.get(key, None)
return result
- def transitive_closure(self, modules):
- '''GLModuleTable.transitive_closure(modules) -> list
-
- Use transitive closure to add module and its dependencies. Add every
+ def transitive_closure(self, modules: list[GLModule]) -> list[GLModule]:
+ '''Use transitive closure to add module and its dependencies. Add every
module and its dependencies from modules list, but do not add dependencies
which contain in avoids list. If any incl_test_categories is enabled, then
add dependencies which are in these categories. If any excl_test_categories,
self.modules = modules
return list(modules)
- def transitive_closure_separately(self, basemodules, finalmodules):
- '''GLModuleTable.transitive_closure_separately(*args, **kwargs) -> tuple
-
- Determine main module list and tests-related module list separately.
+ def transitive_closure_separately(self, basemodules: list[GLModule],
+ finalmodules: list[GLModule]) -> tuple[list[GLModule], list[GLModule]]:
+ '''Determine main module list and tests-related module list separately.
The main module list is the transitive closure of the specified modules,
ignoring tests modules. Its lib/* sources go into $sourcebase/. If lgpl is
specified, it will consist only of LGPLed source.
cleansed.append(line)
return lines_to_multiline(cleansed)
- def add_dummy(self, modules):
- '''GLModuleTable.add_dummy(modules) -> list
-
- Add dummy package to list of modules if dummy package is needed. If not,
- return original list of modules.
+ def add_dummy(self, modules: list[GLModule]) -> list[GLModule]:
+ '''Add dummy package to list of modules if dummy package is needed.
+ If not, return original list of modules.
GLConfig: auxdir, ac_version, conddeps.'''
auxdir = self.config['auxdir']
ac_version = self.config['ac_version']
modules = sorted(set(modules)) + [dummy]
return list(modules)
- def filelist(self, modules):
- '''GLModuleTable.filelist(modules) -> list
-
- Determine the final file list for the given list of modules. The list of
- modules must already include dependencies.
+ def filelist(self, modules: list[GLModule]) -> list[str]:
+ '''Determine the final file list for the given list of modules.
+ The list of modules must already include dependencies.
GLConfig: ac_version.'''
ac_version = self.config['ac_version']
filelist = list()
filelist += [file]
return filelist
- def filelist_separately(self, main_modules, tests_modules):
- '''GLModuleTable.filelist_separately(**kwargs) -> list
-
- Determine the final file lists. They must be computed separately, because
+ def filelist_separately(self, main_modules: list[GLModule],
+ tests_modules: list[GLModule]) -> tuple[list[str], list[str]]:
+ '''Determine the final file lists. They must be computed separately, because
files in lib/* go into $sourcebase/ if they are in the main file list but
into $testsbase/ if they are in the tests-related file list. Furthermore
lib/dummy.c can be in both.'''
result = tuple([main_filelist, tests_filelist])
return result
- def getAvoids(self):
- '''GLModuleTable.getAvoids() -> list
-
- Return list of avoids.'''
+ def getAvoids(self) -> list[GLModule]:
+ '''Return list of avoids.'''
return list(self.avoids)
- def setAvoids(self, modules):
- '''GLModuleTable.setAvoids(modules)
-
- Specify list of avoids.'''
+ def setAvoids(self, modules: list[GLModule]) -> None:
+ '''Specify list of avoids.'''
for module in modules:
if type(module) is not GLModule:
raise TypeError('each module must be a GLModule instance')
self.avoids = sorted(set(modules))
- def getBaseModules(self):
- '''GLModuleTable.getBaseModules() -> list
-
- Return list of base modules.'''
+ def getBaseModules(self) -> list[GLModule]:
+ '''Return list of base modules.'''
return list(self.base_modules)
- def setBaseModules(self, modules):
- '''GLModuleTable.setBaseModules(modules)
-
- Specify list of base modules.'''
+ def setBaseModules(self, modules: list[GLModule]) -> None:
+ '''Specify list of base modules.'''
for module in modules:
if type(module) is not GLModule:
raise TypeError('each module must be a GLModule instance')
self.base_modules = sorted(set(modules))
- def getFinalModules(self):
- '''GLModuleTable.getFinalModules() -> list
-
- Return list of final modules.'''
+ def getFinalModules(self) -> list[GLModule]:
+ '''Return list of final modules.'''
return list(self.final_modules)
- def setFinalModules(self, modules):
- '''GLModuleTable.setFinalModules(modules)
-
- Specify list of final modules.'''
+ def setFinalModules(self, modules: list[GLModule]) -> None:
+ '''Specify list of final modules.'''
for module in modules:
if type(module) is not GLModule:
raise TypeError('each module must be a GLModule instance')
self.final_modules = sorted(set(modules))
- def getMainModules(self):
- '''GLModuleTable.getMainModules() -> list
-
- Return list of main modules.'''
+ def getMainModules(self) -> list[GLModule]:
+ '''Return list of main modules.'''
return list(self.main_modules)
- def setMainModules(self, modules):
- '''GLModuleTable.setMainModules(modules)
-
- Specify list of main modules.'''
+ def setMainModules(self, modules: list[GLModule]) -> None:
+ '''Specify list of main modules.'''
for module in modules:
if type(module) is not GLModule:
raise TypeError('each module must be a GLModule instance')
self.main_modules = sorted(set(modules))
- def getTestsModules(self):
- '''GLModuleTable.getTestsModules() -> list
-
- Return list of tests modules.'''
+ def getTestsModules(self) -> list[GLModule]:
+ '''Return list of tests modules.'''
return list(self.tests_modules)
- def setTestsModules(self, modules):
- '''GLModuleTable.setTestsModules(modules)
-
- Specify list of tests modules.'''
+ def setTestsModules(self, modules: list[GLModule]) -> None:
+ '''Specify list of tests modules.'''
for module in modules:
if type(module) is not GLModule:
raise TypeError('each module must be a GLModule instance')
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <https://www.gnu.org/licenses/>.
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
'''GLTestDir class is used to create a scratch package with the given
list of the modules.'''
- def __init__(self, config, testdir):
- '''GLTestDir.__init__(config, testdir) -> GLTestDir
-
- Create new GLTestDir instance.'''
+ def __init__(self, config: GLConfig, testdir: str) -> None:
+ '''Create new GLTestDir instance.'''
if type(config) is not GLConfig:
raise TypeError('config must be a GLConfig, not %s'
% type(config).__name__)
self.config.resetWitnessCMacro()
self.config.resetVCFiles()
- def rewrite_files(self, files):
- '''GLTestDir.rewrite_files(files)
-
- Replace auxdir, docbase, sourcebase, m4base and testsbase from default
- to their version from config.'''
+ def rewrite_files(self, files: list[str]) -> list[str]:
+ '''Replace auxdir, docbase, sourcebase, m4base and testsbase from
+ default to their version from config.'''
if type(files) is not list:
raise TypeError('files argument must have list type, not %s'
% type(files).__name__)
result = sorted(set(result))
return list(result)
- def execute(self):
- '''GLTestDir.execute()
-
- Create a scratch package with the given modules.'''
+ def execute(self) -> None:
+ '''Create a scratch package with the given modules.'''
auxdir = self.config['auxdir']
sourcebase = self.config['sourcebase']
m4base = self.config['m4base']
'''GLMegaTestDir class is used to create a mega scratch package with the
given modules one by one and all together.'''
- def __init__(self, config, megatestdir):
- '''GLMegaTestDir.__init__(config, megatestdir) -> GLMegaTestDir
-
- Create new GLTestDir instance.'''
+ def __init__(self, config: GLConfig, megatestdir: str) -> None:
+ '''Create new GLTestDir instance.'''
if type(config) is not GLConfig:
raise TypeError('config must be a GLConfig, not %s'
% type(config).__name__)
self.assistant = GLFileAssistant(self.config)
self.makefiletable = GLMakefileTable(self.config)
- def execute(self):
- '''GLMegaTestDir.execute()
-
- Create a mega scratch package with the given modules one by one and all
- together.'''
+ def execute(self) -> None:
+ '''Create a mega scratch package with the given modules one by one
+ and all together.'''
auxdir = self.config['auxdir']
verbose = self.config['verbosity']
'''An easy access to pygnulib constants.'''
from __future__ import unicode_literals
+from __future__ import annotations
+
#===============================================================================
# Define global imports
#===============================================================================
import subprocess as sp
import __main__ as interpreter
-
#===============================================================================
# Define module information
#===============================================================================
# Set DIRS directory
DIRS['cwd'] = os.getcwd()
-def init_DIRS(gnulib_dir):
+def init_DIRS(gnulib_dir: str) -> None:
DIRS['root'] = gnulib_dir
DIRS['build-aux'] = os.path.join(gnulib_dir, 'build-aux')
DIRS['config'] = os.path.join(gnulib_dir, 'config')
# Define global functions
#===============================================================================
-def force_output():
+def force_output() -> None:
'''This function is to be invoked before invoking external programs.
It initiates bringing the the contents of process-internal output buffers
to their respective destinations.'''
sys.stderr.flush()
-def execute(args, verbose):
+def execute(args: list[str], verbose: int) -> None:
'''Execute the given shell command.'''
if verbose >= 0:
print("executing %s" % ' '.join(args), flush=True)
sys.exit(retcode)
-def cleaner(sequence):
+def cleaner(sequence: str | list[str]) -> str | list[str | bool]:
'''Clean string or list of strings after using regex.'''
if type(sequence) is str:
sequence = sequence.replace('[', '')
return sequence
-def joinpath(head, *tail):
- '''joinpath(head, *tail) -> str
-
- Join two or more pathname components, inserting '/' as needed. If any
+def joinpath(head: str, *tail: str) -> str:
+ '''Join two or more pathname components, inserting '/' as needed. If any
component is an absolute path, all previous path components will be
discarded.'''
newtail = list()
return result
-def relativize(dir1, dir2):
+def relativize(dir1: str, dir2: str) -> str:
'''Compute a relative pathname reldir such that dir1/reldir = dir2.
dir1 and dir2 must be relative pathnames.'''
dir0 = os.getcwd()
return result
-def relconcat(dir1, dir2):
+def relconcat(dir1: str, dir2: str) -> str:
'''Compute a relative pathname dir1/dir2, with obvious simplifications.
dir1 and dir2 must be relative pathnames.
dir2 is considered to be relative to dir1.'''
os.chmod(dest, st.st_mode | stat.S_IWUSR)
-def relinverse(dir):
+def relinverse(dir: str) -> str:
'''Compute the inverse of dir. Namely, a relative pathname consisting only
of '..' components, such that dir/relinverse = '.'.
dir must be a relative pathname.'''
return os.path.normpath(inverse)
-def copyfile(src, dest):
+def copyfile(src: str, dest: str) -> None:
'''Copy file src to file dest. Like shutil.copy, but ignore errors e.g. on
VFAT file systems.'''
shutil.copyfile(src, dest)
pass
-def copyfile2(src, dest):
+def copyfile2(src: str, dest: str) -> None:
'''Copy file src to file dest, preserving modification time. Like
shutil.copy2, but ignore errors e.g. on VFAT file systems. This function
is to be used for backup files.'''
pass
-def movefile(src, dest):
+def movefile(src: str, dest: str) -> None:
'''Move/rename file src to file dest. Like shutil.move, but gracefully
handle common errors.'''
try:
os.remove(src)
-def symlink_relative(src, dest):
+def symlink_relative(src: str, dest: str) -> None:
'''Like ln -s, except use cp -p if ln -s fails.
src is either absolute or relative to the directory of dest.'''
try:
ensure_writable(dest)
-def as_link_value_at_dest(src, dest):
+def as_link_value_at_dest(src: str, dest: str) -> str:
'''Compute the symbolic link value to place at dest, such that the
resulting symbolic link points to src. src is given relative to the
current directory (or absolute).'''
return relativize(destdir, src)
-def link_relative(src, dest):
+def link_relative(src: str, dest: str) -> None:
'''Like ln -s, except that src is given relative to the current directory
(or absolute), not given relative to the directory of dest.'''
if type(src) is not str:
symlink_relative(link_value, dest)
-def link_if_changed(src, dest):
+def link_if_changed(src: str, dest: str) -> None:
'''Create a symlink, but avoids munging timestamps if the link is correct.'''
link_value = as_link_value_at_dest(src, dest)
if not (os.path.islink(dest) and os.readlink(dest) == link_value):
ensure_writable(dest)
-def filter_filelist(separator, filelist,
- prefix, suffix, removed_prefix, removed_suffix,
- added_prefix='', added_suffix=''):
- '''filter_filelist(*args) -> str
-
- Filter the given list of files. Filtering: Only the elements starting with
+def filter_filelist(separator: str, filelist: str, prefix: str, suffix: str,
+ removed_prefix: str, removed_suffix: str,
+ added_prefix: str = '', added_suffix: str = '') -> str:
+ '''Filter the given list of files. Filtering: Only the elements starting with
prefix and ending with suffix are considered. Processing: removed_prefix
and removed_suffix are removed from each element, added_prefix and
added_suffix are added to each element.'''
return result
-def lines_to_multiline(lines):
- '''lines_to_multiline(List[str]) -> str
-
- Combine the lines to a single string, terminating each line with a newline
- character.'''
+def lines_to_multiline(lines: list[str]) -> str:
+ '''Combine the lines to a single string, terminating each line with a
+ newline character.'''
if len(lines) > 0:
return '\n'.join(lines) + '\n'
else:
return ''
-def substart(orig, repl, data):
+def substart(orig: str, repl: str, data: str) -> str:
'''Replaces the start portion of a string.
Returns data with orig replaced by repl, but only at the beginning of data.
return result
-def subend(orig, repl, data):
+def subend(orig: str, repl: str, data: str) -> str:
'''Replaces the end portion of a string.
Returns data with orig replaced by repl, but only at the end of data.
return result
-def nlconvert(text):
+def nlconvert(text: str) -> str:
'''Convert line-endings to specific for this platform.'''
system = platform.system().lower()
text = text.replace('\r\n', '\n')
return text
-def remove_trailing_slashes(text):
+def remove_trailing_slashes(text: str) -> str:
'''Remove trailing slashes from a file name, except when the file name
consists only of slashes.'''
result = text
return result
-def remove_backslash_newline(text):
+def remove_backslash_newline(text: str) -> str:
'''Given a multiline string text, join lines:
When a line ends in a backslash, remove the backslash and join the next
line to it.'''
return text.replace('\\\n', '')
-def combine_lines(text):
+def combine_lines(text: str) -> str:
'''Given a multiline string text, join lines by spaces:
When a line ends in a backslash, remove the backslash and join the next
line to it, inserting a space between them.'''
return text.replace('\\\n', ' ')
-def combine_lines_matching(pattern, text):
+def combine_lines_matching(pattern: re.Pattern, text: str) -> str:
'''Given a multiline string text, join lines by spaces, when the first
such line matches a given RegexObject pattern.
When a line that matches the pattern ends in a backslash, remove the
# - Avoid conditional expressions as in PEP 308 <https://peps.python.org/pep-0308/>.
# Rationale: They violate the principle that in conditional code, the
# condition comes first.
+# - Use type hints to document functions and catch programming mistakes.
+# To allow for type annotations and union type specifiers, using the
+# syntax Type1 | Type2, for all versions of Python ≥ 3.7 use the
+# 'from __future__ import annotations' import at the top of files.
+# Cf. <https://docs.python.org/3/library/__future__.html>
+# and <https://stackoverflow.com/questions/73879925/>.
+# - Prefer the standard collection type hints over those provided in the
+# typing module. The latter are deprecated and may be removed.
+# Cf. <https://peps.python.org/pep-0585/>.
# You can use this command to check the style:
# $ pycodestyle *.py
# Documentation:
# <https://pylint.readthedocs.io/en/latest/user_guide/messages/messages_overview.html>
+from __future__ import annotations
#===============================================================================
# Define global imports
#===============================================================================
# Define main part
#===============================================================================
-def main():
+def main() -> None:
info = classes.GLInfo()
parser = argparse.ArgumentParser(
prog=constants.APP['name'],