Auto-import spack.build_systems._package_api_v1 (#50496)

When loading packages from a v1.0 repository, inject a line

from spack.build_systems._package_api import *

This allows removal of certain names in `spack.package` as part of api
v2 without breaking backward compatibility in Spack.
This commit is contained in:
Harmen Stoppels 2025-05-16 11:07:06 +02:00 committed by GitHub
parent 6e98f88c51
commit e7e37899f4
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 128 additions and 5 deletions

View File

@ -0,0 +1,99 @@
# Copyright Spack Project Developers. See COPYRIGHT file for details.
#
# SPDX-License-Identifier: (Apache-2.0 OR MIT)
"""This module re-exports symbols that are part of the v1.0 Package API, but were removed in the
v2.0 Package API after build systems were moved into the ``spack_repo.builtin`` package.
In older versions of Spack, these symbols were re-exported from ``spack.package``."""
from .aspell_dict import AspellDictPackage
from .autotools import AutotoolsPackage
from .bundle import BundlePackage
from .cached_cmake import (
CachedCMakePackage,
cmake_cache_filepath,
cmake_cache_option,
cmake_cache_path,
cmake_cache_string,
)
from .cargo import CargoPackage
from .cmake import CMakePackage, generator
from .compiler import CompilerPackage
from .cuda import CudaPackage
from .generic import Package
from .gnu import GNUMirrorPackage
from .go import GoPackage
from .intel import IntelPackage
from .lua import LuaPackage
from .makefile import MakefilePackage
from .maven import MavenPackage
from .meson import MesonPackage
from .msbuild import MSBuildPackage
from .nmake import NMakePackage
from .octave import OctavePackage
from .oneapi import (
INTEL_MATH_LIBRARIES,
IntelOneApiLibraryPackage,
IntelOneApiLibraryPackageWithSdk,
IntelOneApiPackage,
IntelOneApiStaticLibraryList,
)
from .perl import PerlPackage
from .python import PythonExtension, PythonPackage
from .qmake import QMakePackage
from .r import RPackage
from .racket import RacketPackage
from .rocm import ROCmPackage
from .ruby import RubyPackage
from .scons import SConsPackage
from .sip import SIPPackage
from .sourceforge import SourceforgePackage
from .sourceware import SourcewarePackage
from .waf import WafPackage
from .xorg import XorgPackage
__all__ = [
"AspellDictPackage",
"AutotoolsPackage",
"BundlePackage",
"CachedCMakePackage",
"cmake_cache_filepath",
"cmake_cache_option",
"cmake_cache_path",
"cmake_cache_string",
"CargoPackage",
"CMakePackage",
"generator",
"CompilerPackage",
"CudaPackage",
"Package",
"GNUMirrorPackage",
"GoPackage",
"IntelPackage",
"IntelOneApiLibraryPackageWithSdk",
"IntelOneApiLibraryPackage",
"IntelOneApiStaticLibraryList",
"IntelOneApiPackage",
"INTEL_MATH_LIBRARIES",
"LuaPackage",
"MakefilePackage",
"MavenPackage",
"MesonPackage",
"MSBuildPackage",
"NMakePackage",
"OctavePackage",
"PerlPackage",
"PythonExtension",
"PythonPackage",
"QMakePackage",
"RacketPackage",
"RPackage",
"ROCmPackage",
"RubyPackage",
"SConsPackage",
"SIPPackage",
"SourceforgePackage",
"SourcewarePackage",
"WafPackage",
"XorgPackage",
]

View File

@ -79,6 +79,25 @@ def namespace_from_fullname(fullname: str) -> str:
return fullname
class _PrependFileLoader(importlib.machinery.SourceFileLoader):
def __init__(self, fullname: str, repo: "Repo", package_name: str) -> None:
self.repo = repo
self.package_name = package_name
path = repo.filename_for_package_name(package_name)
self.fullname = fullname
self.prepend = b"from spack.build_systems._package_api_v1 import *\n"
super().__init__(self.fullname, path)
def path_stats(self, path):
stats = dict(super().path_stats(path))
stats["size"] += len(self.prepend)
return stats
def get_data(self, path):
data = super().get_data(path)
return self.prepend + data if path == self.path else data
class SpackNamespaceLoader:
def create_module(self, spec):
return SpackNamespace(spec.name)
@ -125,8 +144,7 @@ def compute_loader(self, fullname: str):
# With 2 nested conditionals we can call "repo.real_name" only once
package_name = repo.real_name(module_name)
if package_name:
module_path = repo.filename_for_package_name(package_name)
return importlib.machinery.SourceFileLoader(fullname, module_path)
return _PrependFileLoader(fullname, repo, package_name)
# We are importing a full namespace like 'spack.pkg.builtin'
if fullname == repo.full_namespace:

View File

@ -28,9 +28,15 @@
(["invalid-selfhosted-gitlab-patch-url"], ["PKG-DIRECTIVES", "PKG-PROPERTIES"]),
# This package has a stand-alone test method in build-time callbacks
(["fail-test-audit"], ["PKG-PROPERTIES"]),
# This package implements and uses several deprecated stand-alone
# test methods
(["fail-test-audit-deprecated"], ["PKG-DEPRECATED-ATTRIBUTES"]),
# This package implements and uses several deprecated stand-alone test methods
pytest.param(
["fail-test-audit-deprecated"],
["PKG-DEPRECATED-ATTRIBUTES"],
marks=pytest.mark.xfail(
reason="inspect.getsource() reads the source file, "
"which misses an injected import line"
),
),
# This package has stand-alone test methods without non-trivial docstrings
(["fail-test-audit-docstring"], ["PKG-PROPERTIES"]),
# This package has a stand-alone test method without an implementation