On 4/10/24 7:17 AM, Bruno Haible wrote:
> Pretty good. The only thing that's missing is the type check for
> module_filter.
> Is it
> module_filter is function Nope!
> module_filter is Callable Nope!
> module_filter is callable Nope!
Yes, I tried to add it but was confused since:
>>> print(type(lambda x: True).__name__)
function
But 'is function' does not work.
> The previous knowledge summarization engine told me how to write it:
> callable(module_filter)
Ah, it was correct this time. I guess that makes sense because you can
create classes with the '__call__' method. Then use objects in a
similar way to functions.
> What I considered is write 3 constants:
> ALL_MODULES_FILTER = lambda module: True
> NON_TESTS_MODULES_FILTER = lambda module: module.isNonTests()
> TESTS_MODULES_FILTER = lambda module: module.isTests()
> but that's probably not worth it either.
Yeah, now that I think about it the lambda's are fine. That way we
don't have to deal with importing those across multiple files.
> This is a problem with gcc's warnings as well. Such tools don't make
> the distinction between a function that is only meant to be called
> directly and a function which needs to adhere to a certain signature.
True. Sometimes I forget about those and use -Wall + -Wextra and get
greeted with the unused variable/function spam.
I attached the patch with the callable(module_filter) check.
Collin
From ff1164711c1397f0f76f6919b395ff132312864f Mon Sep 17 00:00:00 2001
From: Collin Funk <collin.fu...@gmail.com>
Date: Wed, 10 Apr 2024 08:24:58 -0700
Subject: [PATCH] gnulib-tool.py: Use function arguments instead of magic
numbers.
* pygnulib/GLEmiter.py (GLEmiter.autoconfSnippets): Remove the
'verifier' integer flag argument. Add the 'module_filter' function
argument. Use it to determine if Autoconf snippets should be printed for
each module.
* pygnulib/GLImport.py (GLImport.gnulib_comp): Update call to use a
lambda function.
* pygnulib/GLTestDir.py (GLTestDir.execute): Likewise.
---
ChangeLog | 11 ++++++++
pygnulib/GLEmiter.py | 65 +++++++++----------------------------------
pygnulib/GLImport.py | 4 +--
pygnulib/GLTestDir.py | 21 ++++++++------
4 files changed, 38 insertions(+), 63 deletions(-)
diff --git a/ChangeLog b/ChangeLog
index 7de60dfead..f8fcd38de7 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,14 @@
+2024-04-10 Collin Funk <collin.fu...@gmail.com>
+
+ gnulib-tool.py: Use function arguments instead of magic numbers.
+ * pygnulib/GLEmiter.py (GLEmiter.autoconfSnippets): Remove the
+ 'verifier' integer flag argument. Add the 'module_filter' function
+ argument. Use it to determine if Autoconf snippets should be printed for
+ each module.
+ * pygnulib/GLImport.py (GLImport.gnulib_comp): Update call to use a
+ lambda function.
+ * pygnulib/GLTestDir.py (GLTestDir.execute): Likewise.
+
2024-04-10 Collin Funk <collin.fu...@gmail.com>
gnulib-tool: Fix a typo.
diff --git a/pygnulib/GLEmiter.py b/pygnulib/GLEmiter.py
index e6143645be..6d82657e7c 100644
--- a/pygnulib/GLEmiter.py
+++ b/pygnulib/GLEmiter.py
@@ -22,6 +22,7 @@ import os
import re
import codecs
import subprocess as sp
+from collections.abc import Callable
from . import constants
from .GLInfo import GLInfo
from .GLConfig import GLConfig
@@ -257,7 +258,7 @@ class GLEmiter:
return emit
def autoconfSnippets(self, modules: list[GLModule], referenceable_modules: list[GLModule],
- moduletable: GLModuleTable, verifier: int, toplevel: bool,
+ moduletable: GLModuleTable, module_filter: Callable[[GLModule], bool], 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.
@@ -271,10 +272,8 @@ class GLEmiter:
dependencies.
moduletable is a GLModuleTable instance, which contains necessary
information about dependencies of the modules.
- verifier is an integer, which can be 0, 1 or 2.
- if verifier == 0, then process every module;
- if verifier == 1, then process only non-tests modules;
- if verifier == 2, then process only tests modules.
+ module_filter is a function that accepts a GLModule and returns a bool describing
+ whether or not Autoconf snippets should be emitted for it.
toplevel is a bool variable, False means a subordinate use of pygnulib.
disable_libtool is a bool variable; it tells whether to disable libtool
handling even if it has been specified through the GLConfig class.
@@ -291,11 +290,9 @@ class GLEmiter:
if type(moduletable) is not GLModuleTable:
raise TypeError('moduletable must be a GLModuleTable, not %s'
% type(moduletable).__name__)
- if type(verifier) is not int:
- raise TypeError('verifier must be an int, not %s'
- % type(verifier).__name__)
- if not (0 <= verifier <= 2):
- raise ValueError('verifier must be 0, 1 or 2, not %d' % verifier)
+ if not callable(module_filter):
+ raise TypeError('module_filter must be a function, not %s'
+ % type(module_filter).__name__)
if type(toplevel) is not bool:
raise TypeError('toplevel must be a bool, not %s'
% type(toplevel).__name__)
@@ -314,37 +311,19 @@ class GLEmiter:
if not conddeps:
# Ignore the conditions, and enable all modules unconditionally.
for module in modules:
- if verifier == 0:
- solution = True
- elif verifier == 1:
- solution = module.isNonTests()
- elif verifier == 2:
- solution = module.isTests()
- if solution:
+ if module_filter(module):
emit += self.autoconfSnippet(module, toplevel,
disable_libtool, disable_gettext, replace_auxdir, ' ')
else: # if conddeps
# Emit the autoconf code for the unconditional modules.
for module in modules:
- if verifier == 0:
- solution = True
- elif verifier == 1:
- solution = module.isNonTests()
- elif verifier == 2:
- solution = module.isTests()
- if solution:
+ if module_filter(module):
if not moduletable.isConditional(module):
emit += self.autoconfSnippet(module, toplevel,
disable_libtool, disable_gettext, replace_auxdir, ' ')
# Initialize the shell variables indicating that the modules are enabled.
for module in modules:
- if verifier == 0:
- solution = True
- elif verifier == 1:
- solution = module.isNonTests()
- elif verifier == 2:
- solution = module.isTests()
- if solution:
+ if module_filter(module):
if moduletable.isConditional(module):
shellvar = module.getShellVar()
emit += ' %s=false\n' % module.getShellVar()
@@ -352,13 +331,7 @@ class GLEmiter:
# function. This makes it possible to support cycles among conditional
# modules.
for module in modules:
- if verifier == 0:
- solution = True
- elif verifier == 1:
- solution = module.isNonTests()
- elif verifier == 2:
- solution = module.isTests()
- if solution:
+ if module_filter(module):
if moduletable.isConditional(module):
shellfunc = module.getShellFunc()
shellvar = module.getShellVar()
@@ -390,13 +363,7 @@ class GLEmiter:
emit += ' }\n'
# Emit the dependencies from the unconditional to the conditional modules.
for module in modules:
- if verifier == 0:
- solution = True
- elif verifier == 1:
- solution = module.isNonTests()
- elif verifier == 2:
- solution = module.isTests()
- if solution:
+ if module_filter(module):
if not moduletable.isConditional(module):
depmodules = module.getDependenciesWithoutConditions()
# Intersect dependencies with the modules list.
@@ -419,13 +386,7 @@ class GLEmiter:
# Define the Automake conditionals.
emit += ' m4_pattern_allow([^%s_GNULIB_ENABLED_])\n' % macro_prefix
for module in modules:
- if verifier == 0:
- solution = True
- elif verifier == 1:
- solution = module.isNonTests()
- elif verifier == 2:
- solution = module.isTests()
- if solution:
+ if module_filter(module):
if moduletable.isConditional(module):
condname = module.getConditionalName()
shellvar = module.getShellVar()
diff --git a/pygnulib/GLImport.py b/pygnulib/GLImport.py
index 4a6f7c48b8..66d8eb922c 100644
--- a/pygnulib/GLImport.py
+++ b/pygnulib/GLImport.py
@@ -678,7 +678,7 @@ AC_DEFUN([%s_INIT],
emit += ' m4_pushdef([gl_MODULE_INDICATOR_CONDITION], [%s])\n' % witness_c_macro
# Emit main autoconf snippets.
emit += self.emitter.autoconfSnippets(moduletable.getMainModules(), moduletable.getMainModules(),
- moduletable, 0, True, False, True, replace_auxdir)
+ moduletable, lambda module: True, True, False, True, replace_auxdir)
if witness_c_macro:
emit += ' m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
emit += ' # End of code from modules\n'
@@ -702,7 +702,7 @@ AC_DEFUN([%s_INIT],
# Emit tests autoconf snippets.
emit += self.emitter.autoconfSnippets(moduletable.getTestsModules(),
moduletable.getMainModules() + moduletable.getTestsModules(),
- moduletable, 0, True, True, True, replace_auxdir)
+ moduletable, lambda module: True, True, True, True, replace_auxdir)
emit += ' m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
emit += self.emitter.initmacro_end('%stests' % macro_prefix, gentests)
emit += ' AC_REQUIRE([gl_CC_GNULIB_WARNINGS])\n'
diff --git a/pygnulib/GLTestDir.py b/pygnulib/GLTestDir.py
index e8c8f63faf..f6ab4f9d2e 100644
--- a/pygnulib/GLTestDir.py
+++ b/pygnulib/GLTestDir.py
@@ -497,13 +497,13 @@ class GLTestDir:
# autoconf snippets. It's cleanest to put those of the library before
# those of the tests.
emit += self.emitter.shellvars_init(True, f'../{sourcebase}')
- emit += self.emitter.autoconfSnippets(modules, modules,
- moduletable, 1, False, False, False,
- replace_auxdir)
+ emit += self.emitter.autoconfSnippets(modules, modules, moduletable,
+ lambda module: module.isNonTests(),
+ False, False, False, replace_auxdir)
emit += self.emitter.shellvars_init(True, '.')
- emit += self.emitter.autoconfSnippets(modules, modules,
- moduletable, 2, False, False, False,
- replace_auxdir)
+ emit += self.emitter.autoconfSnippets(modules, modules, moduletable,
+ lambda module: module.isTests(),
+ False, False, False, replace_auxdir)
emit += self.emitter.initmacro_end(macro_prefix, True)
# _LIBDEPS and _LTLIBDEPS variables are not needed if this library is
# created using libtool, because libtool already handles the
@@ -613,10 +613,12 @@ class GLTestDir:
emit += self.emitter.shellvars_init(False, sourcebase)
if single_configure:
emit += self.emitter.autoconfSnippets(main_modules, main_modules, moduletable,
- 0, True, False, False, replace_auxdir)
+ lambda module: True,
+ True, False, False, replace_auxdir)
else: # if not single_configure
emit += self.emitter.autoconfSnippets(modules, modules, moduletable,
- 1, True, False, False, replace_auxdir)
+ lambda module: module.isNonTests(),
+ True, False, False, replace_auxdir)
emit += self.emitter.initmacro_end(macro_prefix, False)
if single_configure:
emit += ' gltests_libdeps=\n'
@@ -630,7 +632,8 @@ class GLTestDir:
emit += ' m4_pushdef([gl_MODULE_INDICATOR_CONDITION], '
emit += '[$gl_module_indicator_condition])\n'
snippets = self.emitter.autoconfSnippets(tests_modules, main_modules + tests_modules,
- moduletable, 0, True, False, False, replace_auxdir)
+ moduletable, lambda module: True,
+ True, False, False, replace_auxdir)
emit += snippets
emit += ' m4_popdef([gl_MODULE_INDICATOR_CONDITION])\n'
emit += self.emitter.initmacro_end('%stests' % macro_prefix, True)
--
2.44.0