From 3dc5ce3e8f52ce688c5f184ba85a3b462c193494 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Tue, 11 Feb 2025 23:59:10 +0700 Subject: [PATCH 1/2] Fix more doctests in meson_editable install --- src/sage/doctest/external.py | 4 +++ src/sage/doctest/sources.py | 10 +++++++ src/sage/env.py | 4 +++ src/sage/features/meson_editable.py | 45 +++++++++++++++++++++++++++++ src/sage/misc/package_dir.py | 36 +++++++++++++++++++++-- 5 files changed, 97 insertions(+), 2 deletions(-) create mode 100644 src/sage/features/meson_editable.py diff --git a/src/sage/doctest/external.py b/src/sage/doctest/external.py index 45b3987de05..2cc374f0763 100644 --- a/src/sage/doctest/external.py +++ b/src/sage/doctest/external.py @@ -366,6 +366,10 @@ def external_features(): r""" Generate the features that are only to be tested if ``--optional=external`` is used. + .. SEEALSO:: + + :func:`sage.features.all.all_features` + EXAMPLES:: sage: from sage.doctest.external import external_features diff --git a/src/sage/doctest/sources.py b/src/sage/doctest/sources.py index 7589f62922b..01d24d67634 100644 --- a/src/sage/doctest/sources.py +++ b/src/sage/doctest/sources.py @@ -87,8 +87,18 @@ def get_basename(path): sage: import os sage: get_basename(sage.doctest.sources.__file__) 'sage.doctest.sources' + + :: + + sage: # optional - !meson_editable sage: get_basename(os.path.join(sage.structure.__path__[0], 'element.pxd')) 'sage.structure.element.pxd' + + TESTS:: + + sage: # optional - meson_editable + sage: get_basename(os.path.join(os.path.dirname(sage.structure.__file__), 'element.pxd')) + 'sage.structure.element.pxd' """ if path is None: return None diff --git a/src/sage/env.py b/src/sage/env.py index 060eb2209a9..826c0343ac8 100644 --- a/src/sage/env.py +++ b/src/sage/env.py @@ -319,6 +319,10 @@ def sage_include_directories(use_sources=False): sage: dirs = sage.env.sage_include_directories(use_sources=True) sage: any(os.path.isfile(os.path.join(d, file)) for d in dirs) True + + :: + + sage: # optional - !meson_editable (no need, see :issue:`39275`) sage: dirs = sage.env.sage_include_directories(use_sources=False) sage: any(os.path.isfile(os.path.join(d, file)) for d in dirs) True diff --git a/src/sage/features/meson_editable.py b/src/sage/features/meson_editable.py new file mode 100644 index 00000000000..a110648b873 --- /dev/null +++ b/src/sage/features/meson_editable.py @@ -0,0 +1,45 @@ +r""" +Feature for testing if Meson editable install is used. +""" + +import sys +from . import Feature, FeatureTestResult + + +class MesonEditable(Feature): + r""" + A :class:`~sage.features.Feature` describing if Meson editable install is used. + + EXAMPLES:: + + sage: from sage.features.meson_editable import MesonEditable + sage: MesonEditable() + Feature('meson_editable') + """ + def __init__(self): + r""" + TESTS:: + + sage: from sage.features.meson_editable import MesonEditable + sage: MesonEditable() is MesonEditable() + True + """ + Feature.__init__(self, 'meson_editable') + + def _is_present(self): + r""" + Test whether Meson editable install is used. + + EXAMPLES:: + + sage: from sage.features.meson_editable import MesonEditable + sage: MesonEditable()._is_present() # random + FeatureTestResult('meson_editable', True) + """ + import sage + result = type(sage.__loader__).__module__ == '_sagemath_editable_loader' + return FeatureTestResult(self, result) + + +def all_features(): + return [MesonEditable()] diff --git a/src/sage/misc/package_dir.py b/src/sage/misc/package_dir.py index 6b6ca12803f..b9742a6d1c2 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -261,6 +261,7 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): :mod:`sage.cpython` is an ordinary package:: + sage: # optional - !meson_editable sage: from sage.misc.package_dir import is_package_or_sage_namespace_package_dir sage: directory = sage.cpython.__path__[0]; directory '.../sage/cpython' @@ -270,24 +271,48 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): :mod:`sage.libs.mpfr` only has an ``__init__.pxd`` file, but we consider it a package directory for consistency with Cython:: + sage: # optional - !meson_editable sage: directory = os.path.join(sage.libs.__path__[0], 'mpfr'); directory '.../sage/libs/mpfr' - sage: is_package_or_sage_namespace_package_dir(directory) # known bug (seen in build.yml) + sage: is_package_or_sage_namespace_package_dir(directory) True :mod:`sage` is designated to become an implicit namespace package:: + sage: # optional - !meson_editable sage: directory = sage.__path__[0]; directory '.../sage' - sage: is_package_or_sage_namespace_package_dir(directory) # known bug (seen in build.yml) + sage: is_package_or_sage_namespace_package_dir(directory) True Not a package:: + sage: # optional - !meson_editable sage: directory = os.path.join(sage.symbolic.__path__[0], 'ginac'); directory # needs sage.symbolic '.../sage/symbolic/ginac' sage: is_package_or_sage_namespace_package_dir(directory) # needs sage.symbolic False + + TESTS:: + + sage: # optional - meson_editable + sage: from sage.misc.package_dir import is_package_or_sage_namespace_package_dir + sage: directory = os.path.dirname(sage.cpython.__file__); directory + '.../sage/cpython' + sage: is_package_or_sage_namespace_package_dir(directory) + True + + sage: # optional - meson_editable + sage: directory = os.path.join(os.path.dirname(sage.libs.__file__), 'mpfr'); directory + '.../sage/libs/mpfr' + sage: is_package_or_sage_namespace_package_dir(directory) + True + + sage: # optional - meson_editable, sage.symbolic + sage: directory = os.path.join(os.path.dirname(sage.symbolic.__file__), 'ginac'); directory + '.../sage/symbolic/ginac' + sage: is_package_or_sage_namespace_package_dir(directory) + False """ if os.path.exists(os.path.join(path, '__init__.py')): # ordinary package return True @@ -345,8 +370,15 @@ def walk_packages(path=None, prefix='', onerror=None): EXAMPLES:: + sage: # optional - !meson_editable sage: sorted(sage.misc.package_dir.walk_packages(sage.misc.__path__)) # a namespace package [..., ModuleInfo(module_finder=FileFinder('.../sage/misc'), name='package_dir', ispkg=False), ...] + + TESTS:: + + sage: # optional - meson_editable + sage: sorted(sage.misc.package_dir.walk_packages(sage.misc.__path__)) + [..., ModuleInfo(module_finder=<...MesonpyPathFinder object...>, name='package_dir', ispkg=False), ...] """ # Adapted from https://github.com/python/cpython/blob/3.11/Lib/pkgutil.py From b6cb2f4bbe85113348fc2899d06cbbd029663967 Mon Sep 17 00:00:00 2001 From: user202729 <25191436+user202729@users.noreply.github.com> Date: Wed, 12 Feb 2025 11:11:10 +0700 Subject: [PATCH 2/2] Workaround for test-new failure --- 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 b9742a6d1c2..e041167e945 100644 --- a/src/sage/misc/package_dir.py +++ b/src/sage/misc/package_dir.py @@ -274,7 +274,7 @@ def is_package_or_sage_namespace_package_dir(path, *, distribution_filter=None): sage: # optional - !meson_editable sage: directory = os.path.join(sage.libs.__path__[0], 'mpfr'); directory '.../sage/libs/mpfr' - sage: is_package_or_sage_namespace_package_dir(directory) + sage: is_package_or_sage_namespace_package_dir(directory) # known bug (seen in build.yml) True :mod:`sage` is designated to become an implicit namespace package::