Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
27 changes: 13 additions & 14 deletions src/hatch_nativelib/config.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import dataclasses
import pathlib
import typing as T


@dataclasses.dataclass
Expand All @@ -14,46 +13,46 @@ class PcFileConfig:
File to write pkgconf file to (relative to pyproject.toml)
"""

description: T.Optional[str] = None
description: str | None = None
"""Description of this package. If not specified, uses the first line of the package description."""

name: T.Optional[str] = None
name: str | None = None
"""Name of this package. If not specified, is basename of pcfile without extension"""

version: T.Optional[str] = None
version: str | None = None
"""If not specified, set to package version"""

includedir: T.Optional[str] = None
includedir: str | None = None
"""Where include files can be found (relative to pyproject.toml)"""

libdir: T.Optional[str] = None
libdir: str | None = None
"""Where the library is located. If not specified, it is next to pcfile"""

shared_libraries: T.Optional[T.List[str]] = None
shared_libraries: list[str] | None = None
"""Name of shared libraries located in libdir (without extension)"""

libs_private: T.Optional[str] = None
libs_private: str | None = None
"""The link flags for private libraries not exposed to applications"""

requires: T.Optional[T.List[str]] = None
requires: list[str] | None = None
"""
Names of other packages this package requires. They must be installed
at build time.
"""

requires_private: T.Optional[T.List[str]] = None
requires_private: list[str] | None = None
"""
Names of private packages this package requires. They must be installed
at build time.
"""

extra_cflags: T.Optional[str] = None
extra_cflags: str | None = None
"""A list of extra compiler flags to be added to Cflags after header search path"""

extra_link_flags: T.Optional[str] = None
extra_link_flags: str | None = None
"""A list of extra link flags to be added to Libs"""

variables: T.Optional[T.Dict[str, str]] = None
variables: dict[str, str] | None = None
"""
Custom variables to add to the generated file. Prefix, libdir, includedir must not be specified."""

Expand All @@ -63,7 +62,7 @@ class PcFileConfig:
the .pc file which will load the shared_libraries
"""

enable_if: T.Optional[str] = None
enable_if: str | None = None
"""
This is a PEP 508 environment marker specification.

Expand Down
19 changes: 9 additions & 10 deletions src/hatch_nativelib/plugin.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,9 @@
import platform
import typing as T

import pkgconf
from hatchling.builders.hooks.plugin.interface import BuildHookInterface

from packaging.markers import Marker
import pkgconf

from .config import PcFileConfig
from .util import maybe_write_file
Expand All @@ -23,7 +22,7 @@
class NativelibHook(BuildHookInterface):
PLUGIN_NAME = "nativelib"

def initialize(self, version: str, build_data: T.Dict[str, T.Any]) -> None:
def initialize(self, version: str, build_data: dict[str, T.Any]) -> None:

# Don't need to generate files when creating an sdist
if self.target_name != "wheel":
Expand Down Expand Up @@ -53,7 +52,7 @@ def _add_pkg_config_path(self, *paths: str) -> None:
if entries:
os.environ["PKG_CONFIG_PATH"] = os.pathsep.join(entries)

def clean(self, versions: T.List[str]) -> None:
def clean(self, versions: list[str]) -> None:
root = pathlib.Path(self.root)
for pcfg in self._pcfiles:
for relname in (pcfg.get_pc_path(), pcfg.get_init_module_path()):
Expand All @@ -68,7 +67,7 @@ def _get_pkg_from_path(self, path: pathlib.Path) -> str:
return ".".join(dist_pth.split(os.sep))

def _generate_pcfile(
self, pcfg: PcFileConfig, build_data: T.Dict[str, T.Any]
self, pcfg: PcFileConfig, build_data: dict[str, T.Any]
) -> pathlib.Path:

pcfile_rel = pcfg.get_pc_path()
Expand Down Expand Up @@ -174,7 +173,7 @@ def _generate_init_py(
self,
pcfg: PcFileConfig,
prefix_path: pathlib.Path,
build_data: T.Dict[str, T.Any],
build_data: dict[str, T.Any],
):
libinit_py_rel = pcfg.get_init_module_path()
libinit_py = self.root_pth / libinit_py_rel
Expand Down Expand Up @@ -209,7 +208,7 @@ def _make_shared_lib_fname(self, lib: str):
return f"lib{lib}.so"

@functools.cached_property
def _pcfiles(self) -> T.List[PcFileConfig]:
def _pcfiles(self) -> list[PcFileConfig]:
pcfiles = []
for i, raw_pc in enumerate(self.config.get("pcfile", [])):
pcfile = parse_input(
Expand All @@ -233,8 +232,8 @@ def _pcfiles(self) -> T.List[PcFileConfig]:
# TODO: this belongs in a separate script/api that can be used from multiple tools
def _write_libinit_py(
init_py: pathlib.Path,
libs: T.List[pathlib.Path],
requires: T.List[str],
libs: list[pathlib.Path],
requires: list[str],
):
"""
:param init_py: the _init module for the library(ies) that is written out
Expand Down Expand Up @@ -303,7 +302,7 @@ def _write_libinit_py(

contents += [
" except FileNotFoundError:",
f" if not exists(lib_path):",
" if not exists(lib_path):",
f' raise FileNotFoundError("{lib.name} was not found on your system. Is this package correctly installed?")',
]

Expand Down
4 changes: 1 addition & 3 deletions src/hatch_nativelib/util.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import os.path
import pathlib
import typing as T


def maybe_write_file(
path: pathlib.Path, content: str, *, encoding: T.Optional[str] = None
path: pathlib.Path, content: str, *, encoding: str | None = None
) -> bool:
# returns True if new content written
if path.exists():
Expand Down
9 changes: 4 additions & 5 deletions src/hatch_nativelib/validate.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import typing

from validobj import errors
import validobj.validation
from validobj import errors

T = typing.TypeVar("T")

Expand All @@ -16,7 +16,7 @@ def _convert_validation_error(
locs = []
msgs = []

e: typing.Optional[BaseException] = ve
e: BaseException | None = ve
while e is not None:

if isinstance(e, errors.WrongFieldError):
Expand All @@ -29,14 +29,13 @@ def _convert_validation_error(
e = e.__cause__

loc = "".join(locs)
if loc.startswith("."):
loc = loc[1:]
loc = loc.removeprefix(".")
msg = "\n ".join(msgs)
vmsg = f"{fname}: {prefix}{loc}:\n {msg}"
return ValidationError(vmsg)


def parse_input(value: typing.Any, spec: typing.Type[T], fname, prefix: str) -> T:
def parse_input(value: typing.Any, spec: type[T], fname, prefix: str) -> T:
try:
return validobj.validation.parse_input(value, spec)
except errors.ValidationError as ve:
Expand Down
2 changes: 1 addition & 1 deletion tests/conftest.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
from __future__ import annotations

import os
import pathlib
import shutil
import subprocess
Expand Down Expand Up @@ -63,6 +62,7 @@ def run(
env=dict(self.env.env),
text=True,
capture_output=True,
check=False,
)

def install_current_project(self) -> None:
Expand Down
1 change: 1 addition & 0 deletions tests/packages/consumer-pkg/src/consumer_pkg/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
import consumer_pkg._init_consumer

from ._consumer_ext import consumer_twice_plus_one
Loading