Filter discovered modules to match the given %pyproject_save_files globs

When certain modules are deliberately not included into the built RPM,
they shouldn't be listed in the list of qualified module names which are
used by %pyproject_check_import to test importability of the
distribution.
Resolves: https://bugzilla.redhat.com/2127958
This commit is contained in:
Karolina Surma 2022-09-23 12:25:57 +02:00
parent 92ad52e5d4
commit 516e1511a7
5 changed files with 60 additions and 8 deletions

View File

@ -269,6 +269,7 @@ If `%pyproject_save_files` is not used, calling `%pyproject_check_import` will f
When `%pyproject_save_files` is invoked,
it creates a list of all valid and public (i.e. not starting with `_`)
importable module names found in the package.
Each top-level module name matches at least one of the globs provided as an argument to `%pyproject_save_files`.
This list is then usable by `%pyproject_check_import` which performs an import check for each listed module.
When a module fails to import, the build fails.

View File

@ -127,9 +127,12 @@ export HOSTNAME="rpmbuild" # to speedup tox in network-less mock, see rhbz#1856
%license LICENSE
%changelog
* Mon Sep 19 2022 Miro Hrončok <mhroncok@redhat.com> - 1.4.0-1
* Mon Sep 19 2022 Python Maint <python-maint@redhat.com> - 1.4.0-1
- %%pyproject_save_files: Support License-Files installed into the *Root License Directory* from PEP 369
- Fixes: rhbz#2127946
- %%pyproject_check_import: Import only the modules whose top-level names
match any of the globs provided to %%pyproject_save_files
- Fixes: rhbz#2127958
* Tue Aug 30 2022 Otto Liljalaakso <otto.liljalaakso@iki.fi> - 1.3.4-1
- Fix typo in internal function name

View File

@ -536,6 +536,50 @@ def generate_file_list(paths_dict, module_globs, include_others=False):
return sorted(files)
def generate_module_list(paths_dict, module_globs):
"""
This function takes the paths_dict created by the classify_paths() function and
reads the modules names from it.
It filters those whose top-level module names match any of the provided module_globs.
Returns list with matching qualified module names.
Examples:
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'foo'})
['foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'*foo'})
['foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'foo', 'baz'})
['baz', 'foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'*'})
['baz', 'foo', 'foo.bar']
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'bar'})
[]
Submodules aren't discovered:
>>> generate_module_list({'module_names': {'foo', 'foo.bar', 'baz'}}, {'*bar'})
[]
"""
module_names = paths_dict['module_names']
filtered_module_names = set()
for glob in module_globs:
for name in module_names:
# Match the top-level part of the qualified name, eg. 'foo.bar.baz' -> 'foo'
top_level_name = name.split('.')[0]
if fnmatch.fnmatchcase(top_level_name, glob):
filtered_module_names.add(name)
return sorted(filtered_module_names)
def parse_varargs(varargs):
"""
Parse varargs from the %pyproject_save_files macro
@ -664,7 +708,7 @@ def pyproject_save_files_and_modules(buildroot, sitelib, sitearch, python_versio
parsed_records = load_parsed_record(pyproject_record)
final_file_list = []
all_module_names = set()
final_module_list = []
for record_path, files in parsed_records.items():
metadata = dist_metadata(buildroot, record_path)
@ -675,12 +719,11 @@ def pyproject_save_files_and_modules(buildroot, sitelib, sitearch, python_versio
final_file_list.extend(
generate_file_list(paths_dict, globs, include_auto)
)
all_module_names.update(paths_dict["module_names"])
final_module_list.extend(
generate_module_list(paths_dict, globs)
)
# Sort values, so they are always checked in the same order
all_module_names = sorted(all_module_names)
return final_file_list, all_module_names
return final_file_list, final_module_list
def main(cli_args):

View File

@ -7755,7 +7755,6 @@ dumped:
- ipykernel.tests.utils
- ipykernel.trio_runner
- ipykernel.zmqshell
- ipykernel_launcher
- - zope
- zope
- - '%dir /usr/lib/python3.7/site-packages/zope'

View File

@ -86,6 +86,12 @@ grep -F %{python3_sitearch}/__pycache__/ldif.cpython-%{python3_version_nodots}.p
grep -F %{python3_sitearch}/__pycache__/ldif.cpython-%{python3_version_nodots}.opt-1.pyc %{pyproject_files} && exit 1 || true
grep -F %{python3_sitearch}/slapdtest %{pyproject_files} && exit 1 || true
# Internal check: Unmatched modules are not supposed to be listed in %%{_pyproject_modules}
grep -F slapdtest %{_pyproject_modules} && exit 1 || true
grep -F ldif %{_pyproject_modules} && exit 1 || true
# Let's check that at least one module is listed in %%{_pyproject_modules}
grep -F ldapurl %{_pyproject_modules}
# Internal check: Top level __pycache__ is never owned
grep -E '/site-packages/__pycache__$' %{pyproject_files} && exit 1 || true
grep -E '/site-packages/__pycache__/$' %{pyproject_files} && exit 1 || true