From 5c1712628b310b6736929a03a6e339ab74d62e97 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 20:22:56 -0700 Subject: [PATCH 01/24] src/sage/misc/package_dir.py (update_distribution): New --- src/sage/misc/package_dir.py | 101 ++++++++++++++++++++++++++++++++++- 1 file changed, 100 insertions(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 9f075b16c31..fe636fa7a37 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -14,6 +14,7 @@ import os import glob +import re import sys from contextlib import contextmanager @@ -90,8 +91,11 @@ def __contains__(self, filename): return distribution not in self._exclude_distributions +distribution_directive = re.compile(r"(\s*#?\s*)(sage_setup:\s*distribution\s*=\s*([-_A-Za-z0-9]*))") + + def read_distribution(src_file): - """ + r""" Parse ``src_file`` for a ``# sage_setup: distribution = PKG`` directive. INPUT: @@ -130,6 +134,101 @@ def read_distribution(src_file): return '' +def update_distribution(src_file, distribution, *, verbose=False): + r""" + Add or update a ``# sage_setup: distribution = PKG`` directive in ``src_file``. + + For a Python or Cython file, if a ``sage_setup: distribution`` directive + is not already present, it is added. + + For any other file, if a ``sage_setup: distribution`` directive is not already + present, no action is taken. + + INPUT: + + - ``src_file`` -- file name of a source file + + EXAMPLES:: + + sage: from sage.misc.package_dir import read_distribution, update_distribution + sage: import tempfile + sage: def test(filename, file_contents): + ....: with tempfile.TemporaryDirectory() as d: + ....: fname = os.path.join(d, filename) + ....: with open(fname, 'w') as f: + ....: f.write(file_contents) + ....: with open(fname, 'r') as f: + ....: print(f.read() + "====") + ....: update_distribution(fname, 'sagemath-categories') + ....: with open(fname, 'r') as f: + ....: print(f.read() + "====") + ....: update_distribution(fname, '') + ....: with open(fname, 'r') as f: + ....: print(f.read(), end="") + sage: test('module.py', '# Python file\n') + # Python file + ==== + # sage_setup: distribution = sagemath-categories + # Python file + ==== + # sage_setup: distribution = + # Python file + sage: test('file.cpp', '// sage_setup: distribution=sagemath-modules\n' + ....: '// C++ file with existing directive\n') + // sage_setup: distribution=sagemath-modules + // C++ file with existing directive + ==== + // sage_setup: distribution = sagemath-categories + // C++ file with existing directive + ==== + // sage_setup: distribution = + // C++ file with existing directive + sage: test('file.cpp', '// C++ file without existing directive\n') + // C++ file without existing directive + ==== + // C++ file without existing directive + ==== + // C++ file without existing directive + """ + if not distribution: + distribution = '' + directive = f'sage_setup: distribution = {distribution}'.rstrip() + with open(src_file, 'r') as f: + src_lines = f.read().splitlines(keepends=True) + any_found = False + any_change = False + for i, line in enumerate(src_lines): + if m := distribution_directive.search(line): + old_distribution = m.group(3) + if any_found: + # Found a second distribution directive; remove it. + if not (line := distribution_directive.sub(r'', line)): + line = None + else: + line = distribution_directive.sub(fr'\1{directive}', line) + if line != src_lines[i]: + src_lines[i] = line + any_change = True + if verbose: + print(f"Changed 'sage_setup: distribution' in {src_file!r} " + f"from {old_distribution!r} to {distribution!r}") + any_found = True + if not any_found: + if any(src_file.endswith(ext) + for ext in [".pxd", ".pxi", ".py", ".pyx", ".sage"]): + src_lines.insert(0, f'# {directive}\n') + any_change = True + if verbose: + print(f"Added 'sage_setup: distribution = {distribution}' " + f"directive in {src_file!r}") + if not any_change: + return + with open(src_file, 'w') as f: + for line in src_lines: + if line is not None: + f.write(line) + + def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): r""" Return whether ``path`` is a directory that contains a Python package. From 534bcc74c4244bd6f9dbec21e5788d900d004e48 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 20:23:43 -0700 Subject: [PATCH 02/24] sage --fixdistributions: New command --- src/bin/sage | 10 ++++++- src/sage/misc/package_dir.py | 57 ++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 1 deletion(-) diff --git a/src/bin/sage b/src/bin/sage index 64d7986482b..e5bb07e4882 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -482,10 +482,13 @@ usage_advanced() { echo " --fixdoctests file.py" echo " -- Run doctests and replace output of failing doctests" echo " with actual output." - echo " --fiximports " + echo " --fiximports " echo " -- Replace imports from sage.PAC.KAGE.all by specific" echo " imports when sage.PAC.KAGE is an implicit namespace" echo " package" + echo " --fixdistributions " + echo " -- Check or update 'sage_setup: distribution' directives" + echo " in source files" fi echo " --sh [...] -- run a shell with Sage environment variables" echo " as they are set in the runtime of Sage" @@ -986,6 +989,11 @@ if [ "$1" = '-fiximports' -o "$1" = '--fiximports' ]; then exec sage-python -m sage.misc.replace_dot_all "$@" fi +if [ "$1" = '-fixdistributions' -o "$1" = '--fixdistributions' ]; then + shift + exec sage-python -m sage.misc.package_dir "$@" +fi + if [ "$1" = '-tox' -o "$1" = '--tox' ]; then shift if [ -n "$SAGE_SRC" -a -f "$SAGE_SRC/tox.ini" ]; then diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index fe636fa7a37..aaf054dd5b8 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -432,3 +432,60 @@ def seen(p, m={}): path = [p for p in path if not seen(p)] yield from walk_packages(path, info.name + '.', onerror) + + +if __name__ == '__main__': + + from argparse import ArgumentParser + + parser = ArgumentParser(description="Maintenance tool for distribution packages of the Sage library", + epilog=("Example usage:\n\n grep '^sage/' pkgs/sagemath-ntl/sagemath_ntl.egg-info/SOURCES.txt " + "| (cd src && xargs ../sage -fixdistributions --set sagemath-ntl)""")) + parser.add_argument('--add', metavar='distribution', type=str, default=None, + help=("add a 'sage_setup: distribution' directive to FILES; " + "do not change files that already have a nonempty directive")) + parser.add_argument('--set', metavar='distribution', type=str, default=None, + help="add or update the 'sage_setup: distribution' directive in FILES") + parser.add_argument("filename", nargs='*', type=str, + help="source files or directories (default: all file from SAGE_SRC)") + + args = parser.parse_args() + + if not args.filename: + from sage.env import SAGE_SRC + if (not SAGE_SRC + or not os.path.exists(os.path.join(SAGE_SRC, 'sage')) + or not os.path.exists(os.path.join(SAGE_SRC, 'conftest_test.py'))): + print(f'{SAGE_SRC=} does not seem to contain a copy of the Sage source tree') + sys.exit(1) + args.filename = [os.path.join(SAGE_SRC, 'sage')] + + def handle_file(path): + if args.set is not None: + update_distribution(path, args.set, verbose=True) + elif args.add is not None and not read_distribution(path): + update_distribution(path, args.add, verbose=True) + else: + distribution = read_distribution(path) + print(f'{path}: file in distribution {distribution!r}') + + for path in args.filename: + if os.path.isdir(path): + if not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + else: + for root, dirs, files in os.walk(path): + for dir in sorted(dirs): + path = os.path.join(root, dir) + if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): + # Silently skip + dirs.remove(dir) + elif not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + dirs.remove(dir) + for file in sorted(files): + if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): + continue + handle_file(os.path.join(root, file)) + else: + handle_file(path) From b5311bf6d0c4bbc5e3302e4557d35bfac01e880d Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 21 Aug 2023 20:32:35 -0700 Subject: [PATCH 03/24] src/sage/misc/package_dir.py (update_distribution): Prevent self-mutilation --- src/sage/misc/package_dir.py | 42 ++++++++++++++++++++---------------- 1 file changed, 23 insertions(+), 19 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index aaf054dd5b8..9a03d34e329 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -1,4 +1,4 @@ -# sage_setup: distribution = sagemath-environment +# sage_setup:distribution = sagemath-environment """ Recognizing package directories """ @@ -27,12 +27,12 @@ class SourceDistributionFilter: - ``include_distributions`` -- (default: ``None``) if not ``None``, should be a sequence or set of strings: include files whose - ``distribution`` (from a ``# sage_setup: distribution = PACKAGE`` + ``distribution`` (from a ``# sage_setup:`` ``distribution = PACKAGE`` directive in the source file) is an element of ``distributions``. - ``exclude_distributions`` -- (default: ``None``) if not ``None``, should be a sequence or set of strings: exclude files whose - ``distribution`` (from a ``# sage_setup: distribution = PACKAGE`` + ``distribution`` (from a ``# sage_setup:`` ``distribution = PACKAGE`` directive in the module source file) is in ``exclude_distributions``. EXAMPLES:: @@ -96,7 +96,7 @@ def __contains__(self, filename): def read_distribution(src_file): r""" - Parse ``src_file`` for a ``# sage_setup: distribution = PKG`` directive. + Parse ``src_file`` for a ``# sage_setup:`` ``distribution = PKG`` directive. INPUT: @@ -136,12 +136,12 @@ def read_distribution(src_file): def update_distribution(src_file, distribution, *, verbose=False): r""" - Add or update a ``# sage_setup: distribution = PKG`` directive in ``src_file``. + Add or update a ``# sage_setup:`` ``distribution = PKG`` directive in ``src_file``. - For a Python or Cython file, if a ``sage_setup: distribution`` directive + For a Python or Cython file, if a ``distribution`` directive is not already present, it is added. - For any other file, if a ``sage_setup: distribution`` directive is not already + For any other file, if a ``distribution`` directive is not already present, no action is taken. INPUT: @@ -168,20 +168,20 @@ def update_distribution(src_file, distribution, *, verbose=False): sage: test('module.py', '# Python file\n') # Python file ==== - # sage_setup: distribution = sagemath-categories + # sage_setup: distribution...= sagemath-categories # Python file ==== - # sage_setup: distribution = + # sage_setup: distribution...= # Python file - sage: test('file.cpp', '// sage_setup: distribution=sagemath-modules\n' + sage: test('file.cpp', '// sage_setup: ' 'distribution=sagemath-modules\n' ....: '// C++ file with existing directive\n') - // sage_setup: distribution=sagemath-modules + // sage_setup: distribution...=sagemath-modules // C++ file with existing directive ==== - // sage_setup: distribution = sagemath-categories + // sage_setup: distribution...= sagemath-categories // C++ file with existing directive ==== - // sage_setup: distribution = + // sage_setup: distribution...= // C++ file with existing directive sage: test('file.cpp', '// C++ file without existing directive\n') // C++ file without existing directive @@ -192,9 +192,13 @@ def update_distribution(src_file, distribution, *, verbose=False): """ if not distribution: distribution = '' - directive = f'sage_setup: distribution = {distribution}'.rstrip() - with open(src_file, 'r') as f: - src_lines = f.read().splitlines(keepends=True) + directive = 'sage_setup: ' f'distribution = {distribution}'.rstrip() + try: + with open(src_file, 'r') as f: + src_lines = f.read().splitlines(keepends=True) + except UnicodeDecodeError: + # Silently skip binary files + return any_found = False any_change = False for i, line in enumerate(src_lines): @@ -210,7 +214,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines[i] = line any_change = True if verbose: - print(f"Changed 'sage_setup: distribution' in {src_file!r} " + print(f"Changed 'sage_setup: " f"distribution' in {src_file!r} " f"from {old_distribution!r} to {distribution!r}") any_found = True if not any_found: @@ -219,7 +223,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines.insert(0, f'# {directive}\n') any_change = True if verbose: - print(f"Added 'sage_setup: distribution = {distribution}' " + print("Added 'sage_setup: " f"distribution = {distribution}' " f"directive in {src_file!r}") if not any_change: return @@ -246,7 +250,7 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): - ``distribution_filter`` -- (optional, default: ``None``) only consider ``all*.py`` files whose distribution (from a - ``# sage_setup: distribution = PACKAGE`` directive in the source file) + ``# sage_setup:`` ``distribution = PACKAGE`` directive in the source file) is an element of ``distribution_filter``. EXAMPLES: From 05681086a9c68340886e288454e6e1024dd2c6b6 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 22 Aug 2023 22:13:18 -0700 Subject: [PATCH 04/24] sage --fixdistributions: Add switch --from-egg-info --- src/sage/misc/package_dir.py | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 9a03d34e329..c00d7148510 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -1,4 +1,4 @@ -# sage_setup:distribution = sagemath-environment +# sage_setup: distribution = sagemath-environment """ Recognizing package directories """ @@ -450,12 +450,32 @@ def seen(p, m={}): "do not change files that already have a nonempty directive")) parser.add_argument('--set', metavar='distribution', type=str, default=None, help="add or update the 'sage_setup: distribution' directive in FILES") + parser.add_argument('--from-egg-info', action="store_true", default=False, + help="take FILES from pkgs/DISTRIBUTION/DISTRIBUTION.egg-info/SOURCES.txt") parser.add_argument("filename", nargs='*', type=str, - help="source files or directories (default: all file from SAGE_SRC)") + help="source files or directories (default: all files from SAGE_SRC)") args = parser.parse_args() - if not args.filename: + distribution = args.set or args.add + + if args.from_egg_info: + from sage.env import SAGE_ROOT + if not distribution: + print("Switch '--from-egg-info' must be used with either " + "'--add DISTRIBUTION' or '--set DISTRIBUTION'") + sys.exit(1) + if (not SAGE_ROOT + or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): + print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') + sys.exit(1) + distribution_underscore = distribution.replace('-', '_') + with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, + f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: + args.filename.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) + for line in f + if line.startswith('sage/')) + elif not args.filename: from sage.env import SAGE_SRC if (not SAGE_SRC or not os.path.exists(os.path.join(SAGE_SRC, 'sage')) From 299e6ceb119a1ea215845a3270719f850d2d4741 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 23:18:05 -0700 Subject: [PATCH 05/24] src/doc/en/developer/packaging_sage_library.rst: Explain sage --fixdistributions --- .../en/developer/packaging_sage_library.rst | 24 +++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index 0244d96e5ac..bebcee72747 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -146,6 +146,30 @@ The source directory of a distribution package, such as controls which files and directories of the monolithic Sage library source tree are included in the distribution + The manifest should be kept in sync with the directives of the form + ``# sage_setup: distribution = sagemath-polyhedra`` at the top of + source files. Sage provides a tool ``sage --fixdistributions`` + that assists with this task. For example:: + + $ ./sage --fixdistributions --set sagemath-polyhedra \ + src/sage/geometry/polyhedron/base*.py + + adds or updates the directives in the specified files; and:: + + $ ./sage --fixdistributions --set sagemath-polyhedra \ + src/sage/geometry/polyhedron + + adds the directive to all files in the given directory that do not + include a directive yet. + + After a distribution has been built (for example, by the command + ``make pypi-wheels``) or at least an sdist has been built (for + example, by the command ``make sagemath_polyhedra-sdist``), the + distribution directives in all files in the source distribution + can be updated using the switch ``--from--egg-info``:: + + $ ./sage --fixdistributions --set sagemath-polyhedra --from-egg-info + - `pyproject.toml `_, `setup.cfg `_, and `requirements.txt `_ -- From db827cff3a884e6e7c0e99095c9537ae8d362668 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 23:31:22 -0700 Subject: [PATCH 06/24] sage --fixpackages: Require at least one filename with --add and --set --- src/sage/misc/package_dir.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index c00d7148510..9d427981402 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -476,6 +476,10 @@ def seen(p, m={}): for line in f if line.startswith('sage/')) elif not args.filename: + if distribution: + print("Switches '--add' and '--set' require the switch '--from-egg-info' " + "or one or more file or directory names") + sys.exit(1) from sage.env import SAGE_SRC if (not SAGE_SRC or not os.path.exists(os.path.join(SAGE_SRC, 'sage')) From a55265f98a0157c9fd7bcf90d71d5ca7fe76bb3a Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 24 Aug 2023 23:36:52 -0700 Subject: [PATCH 07/24] src/doc/en/developer/packaging_sage_library.rst: Explain sage --fixdistributions (fixup) --- src/doc/en/developer/packaging_sage_library.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index bebcee72747..de19c135a24 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -156,7 +156,7 @@ The source directory of a distribution package, such as adds or updates the directives in the specified files; and:: - $ ./sage --fixdistributions --set sagemath-polyhedra \ + $ ./sage --fixdistributions --add sagemath-polyhedra \ src/sage/geometry/polyhedron adds the directive to all files in the given directory that do not From 3e9af944f4e2c1111d424181a21ab5c56e33182b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 18:18:44 -0700 Subject: [PATCH 08/24] sage --fixdistributions: Put filename first in all messages --- src/sage/misc/package_dir.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 9d427981402..1e4656aa115 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -214,7 +214,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines[i] = line any_change = True if verbose: - print(f"Changed 'sage_setup: " f"distribution' in {src_file!r} " + print(f"{src_file}: changed 'sage_setup: " f"distribution' " f"from {old_distribution!r} to {distribution!r}") any_found = True if not any_found: @@ -223,8 +223,8 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines.insert(0, f'# {directive}\n') any_change = True if verbose: - print("Added 'sage_setup: " f"distribution = {distribution}' " - f"directive in {src_file!r}") + print(f"{src_file}: Added 'sage_setup: " + f"distribution = {distribution}' directive") if not any_change: return with open(src_file, 'w') as f: From d1bbc45321d8e25ece7ab5b1f47351eadd6877ae Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 18:24:44 -0700 Subject: [PATCH 09/24] sage --fixdistributions: Check all*.py and __init__.py files --- src/sage/misc/package_dir.py | 49 +++++++++++++++++++++++++++++++++--- 1 file changed, 46 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 1e4656aa115..2d76393c031 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -16,6 +16,8 @@ import glob import re import sys + +from collections import defaultdict from contextlib import contextmanager @@ -438,6 +440,20 @@ def seen(p, m={}): yield from walk_packages(path, info.name + '.', onerror) +def _all_filename(distribution): + if not distribution: + return 'all.py' + return f"all__{distribution.replace('-', '_')}.py" + + +def _distribution_from_all_filename(filename): + if m := re.match('all(__(.*?))?[.]py', file): + if distribution_per_all_filename := m.group(2): + return distribution_per_all_filename.replace('_', '-') + return '' + return False + + if __name__ == '__main__': from argparse import ArgumentParser @@ -486,9 +502,14 @@ def seen(p, m={}): or not os.path.exists(os.path.join(SAGE_SRC, 'conftest_test.py'))): print(f'{SAGE_SRC=} does not seem to contain a copy of the Sage source tree') sys.exit(1) - args.filename = [os.path.join(SAGE_SRC, 'sage')] + args.filename = [os.path.relpath(os.path.join(SAGE_SRC, 'sage'))] - def handle_file(path): + ordinary_packages = set() + package_distributions_per_directives = defaultdict(set) # path -> set of strings (distributions) + package_distributions_per_all_files = defaultdict(set) # path -> set of strings (distributions) + + def handle_file(root, file): + path = os.path.join(root, file) if args.set is not None: update_distribution(path, args.set, verbose=True) elif args.add is not None and not read_distribution(path): @@ -496,6 +517,13 @@ def handle_file(path): else: distribution = read_distribution(path) print(f'{path}: file in distribution {distribution!r}') + package_distributions_per_directives[root].add(distribution) + if file.startswith('__init__.'): + ordinary_packages.add(root) + elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is not False: + if distribution_per_all_filename != distribution: + print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {distribution!r}') + package_distributions_per_all_files[root].add(distribution_per_all_filename) for path in args.filename: if os.path.isdir(path): @@ -514,6 +542,21 @@ def handle_file(path): for file in sorted(files): if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): continue - handle_file(os.path.join(root, file)) + handle_file(root, file) else: handle_file(path) + + for package in ordinary_packages: + if len(package_distributions_per_directives[package]) > 1: + print(f'{package}: ordinary packages (with __init__.py) cannot be split in several distributions (' + + ', '.join(f'{dist!r}' + for dist in sorted(package_distributions_per_directives[package])) + ')') + + for package, distributions in package_distributions_per_directives.items(): + if package in ordinary_packages: + pass + elif ((missing_all_files := distributions - package_distributions_per_all_files[package]) + and not(missing_all_files == set(['']) and len(distributions) < 2)): + s = '' if len(missing_all_files) == 1 else 's' + print(f'{package}: missing file{s} ' + ', '.join(_all_filename(distribution) + for distribution in missing_all_files)) From 54c5b794359ab5d61f991cc7674116c600f1e278 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 19:00:17 -0700 Subject: [PATCH 10/24] src/sage/misc/package_dir.py: Make case of messages uniform --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 2d76393c031..6e35421d17e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -225,7 +225,7 @@ def update_distribution(src_file, distribution, *, verbose=False): src_lines.insert(0, f'# {directive}\n') any_change = True if verbose: - print(f"{src_file}: Added 'sage_setup: " + print(f"{src_file}: added 'sage_setup: " f"distribution = {distribution}' directive") if not any_change: return From b61c4915285bbce96c23f215deca75bf1aac10d4 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 19:06:18 -0700 Subject: [PATCH 11/24] sage --fixdistributions: Update --help epilog --- src/sage/misc/package_dir.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 6e35421d17e..fb7ee372d8e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -459,8 +459,7 @@ def _distribution_from_all_filename(filename): from argparse import ArgumentParser parser = ArgumentParser(description="Maintenance tool for distribution packages of the Sage library", - epilog=("Example usage:\n\n grep '^sage/' pkgs/sagemath-ntl/sagemath_ntl.egg-info/SOURCES.txt " - "| (cd src && xargs ../sage -fixdistributions --set sagemath-ntl)""")) + epilog="By default, 'sage -fixdistributions' shows the distribution of each file.") parser.add_argument('--add', metavar='distribution', type=str, default=None, help=("add a 'sage_setup: distribution' directive to FILES; " "do not change files that already have a nonempty directive")) From 59bb4292d0e91e144a5524c9b4066b4a219f4628 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 19:37:10 -0700 Subject: [PATCH 12/24] sage --fixdistributions: Improve --help --- src/sage/misc/package_dir.py | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index fb7ee372d8e..5eef56479da 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -458,17 +458,19 @@ def _distribution_from_all_filename(filename): from argparse import ArgumentParser - parser = ArgumentParser(description="Maintenance tool for distribution packages of the Sage library", + parser = ArgumentParser(prog="sage --fixdistributions", + description="Maintenance tool for distribution packages of the Sage library", epilog="By default, 'sage -fixdistributions' shows the distribution of each file.") - parser.add_argument('--add', metavar='distribution', type=str, default=None, - help=("add a 'sage_setup: distribution' directive to FILES; " + parser.add_argument('--add', metavar='DISTRIBUTION', type=str, default=None, + help=("add a 'sage_setup: DISTRIBUTION' directive to FILES; " "do not change files that already have a nonempty directive")) - parser.add_argument('--set', metavar='distribution', type=str, default=None, - help="add or update the 'sage_setup: distribution' directive in FILES") + parser.add_argument('--set', metavar='DISTRIBUTION', type=str, default=None, + help="add or update the 'sage_setup: DISTRIBUTION' directive in FILES") parser.add_argument('--from-egg-info', action="store_true", default=False, help="take FILES from pkgs/DISTRIBUTION/DISTRIBUTION.egg-info/SOURCES.txt") - parser.add_argument("filename", nargs='*', type=str, - help="source files or directories (default: all files from SAGE_SRC)") + parser.add_argument("filename", metavar='FILES', nargs='*', type=str, + help=("source files or directories (default: all files from SAGE_SRC, " + "unless --from-egg-info, --add, or --set are used)")) args = parser.parse_args() From df4f4050f55f4df7d8fe0497d7e3bb0260d55fef Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 23:02:58 -0700 Subject: [PATCH 13/24] src/sage/misc/package_dir.py (update_distribution): Fix for empty string as distribution --- src/sage/misc/package_dir.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 5eef56479da..70dca22865e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -197,7 +197,7 @@ def update_distribution(src_file, distribution, *, verbose=False): directive = 'sage_setup: ' f'distribution = {distribution}'.rstrip() try: with open(src_file, 'r') as f: - src_lines = f.read().splitlines(keepends=True) + src_lines = f.read().splitlines() except UnicodeDecodeError: # Silently skip binary files return @@ -222,7 +222,7 @@ def update_distribution(src_file, distribution, *, verbose=False): if not any_found: if any(src_file.endswith(ext) for ext in [".pxd", ".pxi", ".py", ".pyx", ".sage"]): - src_lines.insert(0, f'# {directive}\n') + src_lines.insert(0, f'# {directive}') any_change = True if verbose: print(f"{src_file}: added 'sage_setup: " @@ -232,7 +232,7 @@ def update_distribution(src_file, distribution, *, verbose=False): with open(src_file, 'w') as f: for line in src_lines: if line is not None: - f.write(line) + f.write(line + '\n') def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): From be49fa74d126313528f24a635df93721f4ba8b40 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 23:11:44 -0700 Subject: [PATCH 14/24] sage --fixdistributions: Fix handling of file args, --set/--add --- src/sage/misc/package_dir.py | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 70dca22865e..1d6920d28d0 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -474,7 +474,7 @@ def _distribution_from_all_filename(filename): args = parser.parse_args() - distribution = args.set or args.add + distribution = args.set or args.add or '' if args.from_egg_info: from sage.env import SAGE_ROOT @@ -513,17 +513,20 @@ def handle_file(root, file): path = os.path.join(root, file) if args.set is not None: update_distribution(path, args.set, verbose=True) - elif args.add is not None and not read_distribution(path): - update_distribution(path, args.add, verbose=True) + file_distribution = distribution + elif args.add is not None: + if not (file_distribution := read_distribution(path)): + update_distribution(path, args.add, verbose=True) + file_distribution = distribution else: - distribution = read_distribution(path) - print(f'{path}: file in distribution {distribution!r}') - package_distributions_per_directives[root].add(distribution) + file_distribution = read_distribution(path) + print(f'{path}: file in distribution {file_distribution!r}') + package_distributions_per_directives[root].add(file_distribution) if file.startswith('__init__.'): ordinary_packages.add(root) elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is not False: - if distribution_per_all_filename != distribution: - print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {distribution!r}') + if distribution_per_all_filename != file_distribution: + print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {file_distribution!r}') package_distributions_per_all_files[root].add(distribution_per_all_filename) for path in args.filename: @@ -545,7 +548,7 @@ def handle_file(root, file): continue handle_file(root, file) else: - handle_file(path) + handle_file(*os.path.split(path)) for package in ordinary_packages: if len(package_distributions_per_directives[package]) > 1: From ebbca9998eab3a198cf9929ebfb0e6442e1e2e33 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 26 Aug 2023 23:12:08 -0700 Subject: [PATCH 15/24] sage --fixdistributions: Use %(prog)s --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 1d6920d28d0..347310dce29 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -460,7 +460,7 @@ def _distribution_from_all_filename(filename): parser = ArgumentParser(prog="sage --fixdistributions", description="Maintenance tool for distribution packages of the Sage library", - epilog="By default, 'sage -fixdistributions' shows the distribution of each file.") + epilog="By default, '%(prog)s' shows the distribution of each file.") parser.add_argument('--add', metavar='DISTRIBUTION', type=str, default=None, help=("add a 'sage_setup: DISTRIBUTION' directive to FILES; " "do not change files that already have a nonempty directive")) From af9bf68b77ead4c4bf87321328fc22160e6f030b Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Aug 2023 18:34:00 -0700 Subject: [PATCH 16/24] sage --fixdistributions: Fix checks --- src/sage/misc/package_dir.py | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 347310dce29..0fe4f932891 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -447,7 +447,7 @@ def _all_filename(distribution): def _distribution_from_all_filename(filename): - if m := re.match('all(__(.*?))?[.]py', file): + if m := re.match('all(__(.*?))?[.]py', filename): if distribution_per_all_filename := m.group(2): return distribution_per_all_filename.replace('_', '-') return '' @@ -524,7 +524,18 @@ def handle_file(root, file): package_distributions_per_directives[root].add(file_distribution) if file.startswith('__init__.'): ordinary_packages.add(root) - elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is not False: + elif (distribution_per_all_filename := _distribution_from_all_filename(file)) is False: + # Not an all*.py file. + pass + elif not distribution_per_all_filename: + # An all.py file. + if file_distribution: + # The all.py is declared to belong to a named distribution, that's OK + package_distributions_per_all_files[root].add(file_distribution) + else: + pass + else: + # An all__*.py file if distribution_per_all_filename != file_distribution: print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {file_distribution!r}') package_distributions_per_all_files[root].add(distribution_per_all_filename) From 47a89b5b67cde0c2171ebee6b0e5fa979589f404 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sun, 27 Aug 2023 20:53:52 -0700 Subject: [PATCH 17/24] sage --fixdistributions: Allow --set/add all --from-egg-info --- src/sage/misc/package_dir.py | 110 +++++++++++++++++++++++------------ 1 file changed, 74 insertions(+), 36 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 0fe4f932891..7d106d66740 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -476,22 +476,25 @@ def _distribution_from_all_filename(filename): distribution = args.set or args.add or '' + if distribution == 'all': + distributions = ["sagemath-symbolics", + "sagemath-schemes", + "sagemath-glpk", + "sagemath-polyhedra", + "sagemath-graphs", + "sagemath-combinat", + "sagemath-modules", + "sagemath-categories", + "sagemath-repl", + "sagemath-objects"] + else: + distributions = [distribution] + if args.from_egg_info: - from sage.env import SAGE_ROOT if not distribution: print("Switch '--from-egg-info' must be used with either " "'--add DISTRIBUTION' or '--set DISTRIBUTION'") sys.exit(1) - if (not SAGE_ROOT - or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): - print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') - sys.exit(1) - distribution_underscore = distribution.replace('-', '_') - with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, - f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: - args.filename.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) - for line in f - if line.startswith('sage/')) elif not args.filename: if distribution: print("Switches '--add' and '--set' require the switch '--from-egg-info' " @@ -503,7 +506,7 @@ def _distribution_from_all_filename(filename): or not os.path.exists(os.path.join(SAGE_SRC, 'conftest_test.py'))): print(f'{SAGE_SRC=} does not seem to contain a copy of the Sage source tree') sys.exit(1) - args.filename = [os.path.relpath(os.path.join(SAGE_SRC, 'sage'))] + args.filename = [os.path.join(SAGE_SRC, 'sage')] ordinary_packages = set() package_distributions_per_directives = defaultdict(set) # path -> set of strings (distributions) @@ -512,11 +515,11 @@ def _distribution_from_all_filename(filename): def handle_file(root, file): path = os.path.join(root, file) if args.set is not None: - update_distribution(path, args.set, verbose=True) + update_distribution(path, distribution, verbose=True) file_distribution = distribution elif args.add is not None: if not (file_distribution := read_distribution(path)): - update_distribution(path, args.add, verbose=True) + update_distribution(path, distribution, verbose=True) file_distribution = distribution else: file_distribution = read_distribution(path) @@ -540,26 +543,61 @@ def handle_file(root, file): print(f'{path}: file should go in distribution {distribution_per_all_filename!r}, not {file_distribution!r}') package_distributions_per_all_files[root].add(distribution_per_all_filename) - for path in args.filename: - if os.path.isdir(path): - if not is_package_or_sage_namespace_package_dir(path): - print(f'{path}: non-package directory') + for distribution in distributions: + + paths = list(args.filename) + + if args.from_egg_info: + from sage.env import SAGE_ROOT + if not distribution: + print("Switch '--from-egg-info' must be used with either " + "'--add DISTRIBUTION' or '--set DISTRIBUTION'") + sys.exit(1) + if (not SAGE_ROOT + or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): + print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') + sys.exit(1) + distribution_underscore = distribution.replace('-', '_') + try: + with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, + f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: + paths.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) + for line in f + if line.startswith('sage/')) + print(f"sage --fixdistributions: found egg-info of distribution {distribution!r}") + except FileNotFoundError: + if len(distributions) > 1: + print(f"sage --fixdistributions: distribution {distribution!r} does not have egg-info, skipping it; " + f"run 'make {distribution_underscore}-sdist' or 'make {distribution_underscore}' to create it") + continue + else: + print(f"sage --fixdistributions: distribution {distribution!r} does not have egg-info; " + f"run 'make {distribution_underscore}-sdist' or 'make {distribution_underscore}' to create it") + sys.exit(1) + + for path in paths: + path = os.path.relpath(path) + if os.path.isdir(path): + if not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + else: + for root, dirs, files in os.walk(path): + for dir in sorted(dirs): + path = os.path.join(root, dir) + if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): + # Silently skip + dirs.remove(dir) + elif not is_package_or_sage_namespace_package_dir(path): + print(f'{path}: non-package directory') + dirs.remove(dir) + for file in sorted(files): + if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): + continue + handle_file(root, file) else: - for root, dirs, files in os.walk(path): - for dir in sorted(dirs): - path = os.path.join(root, dir) - if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): - # Silently skip - dirs.remove(dir) - elif not is_package_or_sage_namespace_package_dir(path): - print(f'{path}: non-package directory') - dirs.remove(dir) - for file in sorted(files): - if any(file.endswith(ext) for ext in [".pyc", ".pyo", ".bak", ".so", "~"]): - continue - handle_file(root, file) - else: - handle_file(*os.path.split(path)) + handle_file(*os.path.split(path)) + + print(f"sage --fixdistributions: checking consistency") for package in ordinary_packages: if len(package_distributions_per_directives[package]) > 1: @@ -567,11 +605,11 @@ def handle_file(root, file): + ', '.join(f'{dist!r}' for dist in sorted(package_distributions_per_directives[package])) + ')') - for package, distributions in package_distributions_per_directives.items(): + for package, distributions_per_directives in package_distributions_per_directives.items(): if package in ordinary_packages: pass - elif ((missing_all_files := distributions - package_distributions_per_all_files[package]) - and not(missing_all_files == set(['']) and len(distributions) < 2)): + elif ((missing_all_files := distributions_per_directives - package_distributions_per_all_files[package]) + and not(missing_all_files == set(['']) and len(distributions_per_directives) < 2)): s = '' if len(missing_all_files) == 1 else 's' print(f'{package}: missing file{s} ' + ', '.join(_all_filename(distribution) for distribution in missing_all_files)) From e6083d5b4aa1b1f9923e7feac83b749f76bee289 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Fri, 1 Sep 2023 12:07:02 -0700 Subject: [PATCH 18/24] sage --fixdistributions: Skip directories _vendor, .tox --- src/sage/misc/package_dir.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 7d106d66740..222a415bf9a 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -584,7 +584,7 @@ def handle_file(root, file): for root, dirs, files in os.walk(path): for dir in sorted(dirs): path = os.path.join(root, dir) - if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__']): + if any(dir.startswith(prefix) for prefix in ['.', 'build', 'dist', '__pycache__', '_vendor', '.tox']): # Silently skip dirs.remove(dir) elif not is_package_or_sage_namespace_package_dir(path): From 71b9c3cf59c788996f4457c29288503cff29c539 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Sat, 16 Sep 2023 17:25:42 -0700 Subject: [PATCH 19/24] src/sage/misc/package_dir.py (read_distribution): Handle C comments --- src/sage/misc/package_dir.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 222a415bf9a..d0fdb98ae3e 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -125,9 +125,12 @@ def read_distribution(src_file): line = line.lstrip() if not line: continue - if line[0] != '#': + if line.startswith('#'): + line = line[1:].lstrip() + elif line.startswith('/*') or line.startswith('//'): + line = line[2:].lstrip() + else: break - line = line[1:].lstrip() kind = "sage_setup:" if line.startswith(kind): key, _, value = (s.strip() for s in line[len(kind):].partition('=')) From 13bfb6663c947efb4f8a25afa9ec00304f8a61ff Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Tue, 19 Sep 2023 20:03:17 -0700 Subject: [PATCH 20/24] src/sage/misc/package_dir.py: Normalize distribution names, improve error message --- src/sage/misc/package_dir.py | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index d0fdb98ae3e..6fa69176596 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -491,7 +491,7 @@ def _distribution_from_all_filename(filename): "sagemath-repl", "sagemath-objects"] else: - distributions = [distribution] + distributions = [distribution.replace('_', '-')] if args.from_egg_info: if not distribution: @@ -556,13 +556,16 @@ def handle_file(root, file): print("Switch '--from-egg-info' must be used with either " "'--add DISTRIBUTION' or '--set DISTRIBUTION'") sys.exit(1) - if (not SAGE_ROOT - or not os.path.exists(os.path.join(SAGE_ROOT, 'pkgs', distribution))): + if not SAGE_ROOT: print(f'{SAGE_ROOT=} does not seem to contain a copy of the Sage source root') sys.exit(1) + distribution_dir = os.path.join(SAGE_ROOT, 'pkgs', distribution) + if not os.path.exists(distribution_dir): + print(f'{distribution_dir} does not exist') + sys.exit(1) distribution_underscore = distribution.replace('-', '_') try: - with open(os.path.join(SAGE_ROOT, 'pkgs', distribution, + with open(os.path.join(distribution_dir, f'{distribution_underscore}.egg-info', 'SOURCES.txt'), "r") as f: paths.extend(os.path.join(SAGE_ROOT, 'src', line.strip()) for line in f From 9663e10a80d8da63c4657cf9100f6cdafedc6ea7 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Thu, 21 Sep 2023 22:27:30 -0700 Subject: [PATCH 21/24] src/sage/misc/package_dir.py: Also recognize Lisp comments for sage_setup directives --- src/sage/misc/package_dir.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 6fa69176596..dea5e8e421b 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -125,9 +125,9 @@ def read_distribution(src_file): line = line.lstrip() if not line: continue - if line.startswith('#'): + if line.startswith('#') or line.startswith(';'): line = line[1:].lstrip() - elif line.startswith('/*') or line.startswith('//'): + elif line.startswith('/*') or line.startswith('//') or line.startswith(';;'): line = line[2:].lstrip() else: break From 331d02a12b115eec3fdea8f3366238576977d005 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 23 Oct 2023 11:44:29 -0700 Subject: [PATCH 22/24] src/sage/misc/package_dir.py: Update distribution list --- src/sage/misc/package_dir.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index dea5e8e421b..3749a4f2a91 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -480,13 +480,13 @@ def _distribution_from_all_filename(filename): distribution = args.set or args.add or '' if distribution == 'all': - distributions = ["sagemath-symbolics", - "sagemath-schemes", - "sagemath-glpk", - "sagemath-polyhedra", - "sagemath-graphs", - "sagemath-combinat", - "sagemath-modules", + distributions = ["sagemath-bliss", + "sagemath-coxeter3", + "sagemath-mcqd", + "sagemath-meataxe", + "sagemath-sirocco", + "sagemath-tdlib", + "sagemath-environment", "sagemath-categories", "sagemath-repl", "sagemath-objects"] From 880776f622abd90b24897fe74657fec39c9bc8ee Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Mon, 23 Oct 2023 11:49:01 -0700 Subject: [PATCH 23/24] src/doc/en/developer/packaging_sage_library.rst: Document 'sage --fixdistributions --set all --from-egg-info' --- src/doc/en/developer/packaging_sage_library.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/doc/en/developer/packaging_sage_library.rst b/src/doc/en/developer/packaging_sage_library.rst index de19c135a24..576356a9dff 100644 --- a/src/doc/en/developer/packaging_sage_library.rst +++ b/src/doc/en/developer/packaging_sage_library.rst @@ -170,6 +170,10 @@ The source directory of a distribution package, such as $ ./sage --fixdistributions --set sagemath-polyhedra --from-egg-info + To take care of all distributions, use:: + + $ ./sage --fixdistributions --set all --from-egg-info + - `pyproject.toml `_, `setup.cfg `_, and `requirements.txt `_ -- From f6fabd8956b0e7522128a1ad287e702a284c2202 Mon Sep 17 00:00:00 2001 From: Matthias Koeppe Date: Wed, 8 Nov 2023 15:11:53 -0800 Subject: [PATCH 24/24] src/bin/sage: Suggested help string edit --- src/bin/sage | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bin/sage b/src/bin/sage index e5bb07e4882..ec6c356f994 100755 --- a/src/bin/sage +++ b/src/bin/sage @@ -487,8 +487,8 @@ usage_advanced() { echo " imports when sage.PAC.KAGE is an implicit namespace" echo " package" echo " --fixdistributions " - echo " -- Check or update 'sage_setup: distribution' directives" - echo " in source files" + echo " -- Check or update '# sage_setup: distribution'" + echo " directives in source files" fi echo " --sh [...] -- run a shell with Sage environment variables" echo " as they are set in the runtime of Sage"