PythonPackage: type hints (#40539)
* PythonPackage: nested config_settings, type hints * No need to quote PythonPackage * Use narrower types for now until needed
This commit is contained in:
parent
9e0720207a
commit
40d12ed7e2
@ -6,13 +6,14 @@
|
|||||||
import os
|
import os
|
||||||
import re
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
from typing import Optional
|
from typing import Iterable, List, Mapping, Optional
|
||||||
|
|
||||||
import archspec
|
import archspec
|
||||||
|
|
||||||
import llnl.util.filesystem as fs
|
import llnl.util.filesystem as fs
|
||||||
import llnl.util.lang as lang
|
import llnl.util.lang as lang
|
||||||
import llnl.util.tty as tty
|
import llnl.util.tty as tty
|
||||||
|
from llnl.util.filesystem import HeaderList, LibraryList
|
||||||
|
|
||||||
import spack.builder
|
import spack.builder
|
||||||
import spack.config
|
import spack.config
|
||||||
@ -25,14 +26,18 @@
|
|||||||
from spack.directives import build_system, depends_on, extends, maintainers
|
from spack.directives import build_system, depends_on, extends, maintainers
|
||||||
from spack.error import NoHeadersError, NoLibrariesError
|
from spack.error import NoHeadersError, NoLibrariesError
|
||||||
from spack.install_test import test_part
|
from spack.install_test import test_part
|
||||||
|
from spack.spec import Spec
|
||||||
|
from spack.util.prefix import Prefix
|
||||||
|
|
||||||
from ._checks import BaseBuilder, execute_install_time_tests
|
from ._checks import BaseBuilder, execute_install_time_tests
|
||||||
|
|
||||||
|
|
||||||
def _flatten_dict(dictionary):
|
def _flatten_dict(dictionary: Mapping[str, object]) -> Iterable[str]:
|
||||||
"""Iterable that yields KEY=VALUE paths through a dictionary.
|
"""Iterable that yields KEY=VALUE paths through a dictionary.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
dictionary: Possibly nested dictionary of arbitrary keys and values.
|
dictionary: Possibly nested dictionary of arbitrary keys and values.
|
||||||
|
|
||||||
Yields:
|
Yields:
|
||||||
A single path through the dictionary.
|
A single path through the dictionary.
|
||||||
"""
|
"""
|
||||||
@ -50,7 +55,7 @@ class PythonExtension(spack.package_base.PackageBase):
|
|||||||
maintainers("adamjstewart")
|
maintainers("adamjstewart")
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def import_modules(self):
|
def import_modules(self) -> Iterable[str]:
|
||||||
"""Names of modules that the Python package provides.
|
"""Names of modules that the Python package provides.
|
||||||
|
|
||||||
These are used to test whether or not the installation succeeded.
|
These are used to test whether or not the installation succeeded.
|
||||||
@ -65,7 +70,7 @@ def import_modules(self):
|
|||||||
detected, this property can be overridden by the package.
|
detected, this property can be overridden by the package.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of strings of module names
|
List of strings of module names.
|
||||||
"""
|
"""
|
||||||
modules = []
|
modules = []
|
||||||
pkg = self.spec["python"].package
|
pkg = self.spec["python"].package
|
||||||
@ -102,14 +107,14 @@ def import_modules(self):
|
|||||||
return modules
|
return modules
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def skip_modules(self):
|
def skip_modules(self) -> Iterable[str]:
|
||||||
"""Names of modules that should be skipped when running tests.
|
"""Names of modules that should be skipped when running tests.
|
||||||
|
|
||||||
These are a subset of import_modules. If a module has submodules,
|
These are a subset of import_modules. If a module has submodules,
|
||||||
they are skipped as well (meaning a.b is skipped if a is contained).
|
they are skipped as well (meaning a.b is skipped if a is contained).
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of strings of module names
|
List of strings of module names.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
@ -185,12 +190,12 @@ def remove_files_from_view(self, view, merge_map):
|
|||||||
|
|
||||||
view.remove_files(to_remove)
|
view.remove_files(to_remove)
|
||||||
|
|
||||||
def test_imports(self):
|
def test_imports(self) -> None:
|
||||||
"""Attempts to import modules of the installed package."""
|
"""Attempts to import modules of the installed package."""
|
||||||
|
|
||||||
# Make sure we are importing the installed modules,
|
# Make sure we are importing the installed modules,
|
||||||
# not the ones in the source directory
|
# not the ones in the source directory
|
||||||
python = inspect.getmodule(self).python
|
python = inspect.getmodule(self).python # type: ignore[union-attr]
|
||||||
for module in self.import_modules:
|
for module in self.import_modules:
|
||||||
with test_part(
|
with test_part(
|
||||||
self,
|
self,
|
||||||
@ -315,24 +320,27 @@ class PythonPackage(PythonExtension):
|
|||||||
py_namespace: Optional[str] = None
|
py_namespace: Optional[str] = None
|
||||||
|
|
||||||
@lang.classproperty
|
@lang.classproperty
|
||||||
def homepage(cls):
|
def homepage(cls) -> Optional[str]: # type: ignore[override]
|
||||||
if cls.pypi:
|
if cls.pypi:
|
||||||
name = cls.pypi.split("/")[0]
|
name = cls.pypi.split("/")[0]
|
||||||
return "https://pypi.org/project/" + name + "/"
|
return f"https://pypi.org/project/{name}/"
|
||||||
|
return None
|
||||||
|
|
||||||
@lang.classproperty
|
@lang.classproperty
|
||||||
def url(cls):
|
def url(cls) -> Optional[str]:
|
||||||
if cls.pypi:
|
if cls.pypi:
|
||||||
return "https://files.pythonhosted.org/packages/source/" + cls.pypi[0] + "/" + cls.pypi
|
return f"https://files.pythonhosted.org/packages/source/{cls.pypi[0]}/{cls.pypi}"
|
||||||
|
return None
|
||||||
|
|
||||||
@lang.classproperty
|
@lang.classproperty
|
||||||
def list_url(cls):
|
def list_url(cls) -> Optional[str]: # type: ignore[override]
|
||||||
if cls.pypi:
|
if cls.pypi:
|
||||||
name = cls.pypi.split("/")[0]
|
name = cls.pypi.split("/")[0]
|
||||||
return "https://pypi.org/simple/" + name + "/"
|
return f"https://pypi.org/simple/{name}/"
|
||||||
|
return None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def headers(self):
|
def headers(self) -> HeaderList:
|
||||||
"""Discover header files in platlib."""
|
"""Discover header files in platlib."""
|
||||||
|
|
||||||
# Remove py- prefix in package name
|
# Remove py- prefix in package name
|
||||||
@ -350,7 +358,7 @@ def headers(self):
|
|||||||
raise NoHeadersError(msg.format(self.spec.name, include, platlib))
|
raise NoHeadersError(msg.format(self.spec.name, include, platlib))
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def libs(self):
|
def libs(self) -> LibraryList:
|
||||||
"""Discover libraries in platlib."""
|
"""Discover libraries in platlib."""
|
||||||
|
|
||||||
# Remove py- prefix in package name
|
# Remove py- prefix in package name
|
||||||
@ -384,7 +392,7 @@ class PythonPipBuilder(BaseBuilder):
|
|||||||
install_time_test_callbacks = ["test"]
|
install_time_test_callbacks = ["test"]
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def std_args(cls):
|
def std_args(cls) -> List[str]:
|
||||||
return [
|
return [
|
||||||
# Verbose
|
# Verbose
|
||||||
"-vvv",
|
"-vvv",
|
||||||
@ -409,7 +417,7 @@ def std_args(cls):
|
|||||||
]
|
]
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def build_directory(self):
|
def build_directory(self) -> str:
|
||||||
"""The root directory of the Python package.
|
"""The root directory of the Python package.
|
||||||
|
|
||||||
This is usually the directory containing one of the following files:
|
This is usually the directory containing one of the following files:
|
||||||
@ -420,51 +428,51 @@ def build_directory(self):
|
|||||||
"""
|
"""
|
||||||
return self.pkg.stage.source_path
|
return self.pkg.stage.source_path
|
||||||
|
|
||||||
def config_settings(self, spec, prefix):
|
def config_settings(self, spec: Spec, prefix: Prefix) -> Mapping[str, object]:
|
||||||
"""Configuration settings to be passed to the PEP 517 build backend.
|
"""Configuration settings to be passed to the PEP 517 build backend.
|
||||||
|
|
||||||
Requires pip 22.1 or newer for keys that appear only a single time,
|
Requires pip 22.1 or newer for keys that appear only a single time,
|
||||||
or pip 23.1 or newer if the same key appears multiple times.
|
or pip 23.1 or newer if the same key appears multiple times.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec (spack.spec.Spec): build spec
|
spec: Build spec.
|
||||||
prefix (spack.util.prefix.Prefix): installation prefix
|
prefix: Installation prefix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
dict: Possibly nested dictionary of KEY, VALUE settings
|
Possibly nested dictionary of KEY, VALUE settings.
|
||||||
"""
|
"""
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def install_options(self, spec, prefix):
|
def install_options(self, spec: Spec, prefix: Prefix) -> Iterable[str]:
|
||||||
"""Extra arguments to be supplied to the setup.py install command.
|
"""Extra arguments to be supplied to the setup.py install command.
|
||||||
|
|
||||||
Requires pip 23.0 or older.
|
Requires pip 23.0 or older.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec (spack.spec.Spec): build spec
|
spec: Build spec.
|
||||||
prefix (spack.util.prefix.Prefix): installation prefix
|
prefix: Installation prefix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of options
|
List of options.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def global_options(self, spec, prefix):
|
def global_options(self, spec: Spec, prefix: Prefix) -> Iterable[str]:
|
||||||
"""Extra global options to be supplied to the setup.py call before the install
|
"""Extra global options to be supplied to the setup.py call before the install
|
||||||
or bdist_wheel command.
|
or bdist_wheel command.
|
||||||
|
|
||||||
Deprecated in pip 23.1.
|
Deprecated in pip 23.1.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
spec (spack.spec.Spec): build spec
|
spec: Build spec.
|
||||||
prefix (spack.util.prefix.Prefix): installation prefix
|
prefix: Installation prefix.
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
list: list of options
|
List of options.
|
||||||
"""
|
"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def install(self, pkg, spec, prefix):
|
def install(self, pkg: PythonPackage, spec: Spec, prefix: Prefix) -> None:
|
||||||
"""Install everything from build directory."""
|
"""Install everything from build directory."""
|
||||||
|
|
||||||
args = PythonPipBuilder.std_args(pkg) + [f"--prefix={prefix}"]
|
args = PythonPipBuilder.std_args(pkg) + [f"--prefix={prefix}"]
|
||||||
|
Loading…
Reference in New Issue
Block a user