Skip to content

Commit 19231fc

Browse files
authored
Merge branch 'main' into big-endian-ci
2 parents 2d42806 + 0397aa2 commit 19231fc

File tree

7 files changed

+282
-9
lines changed

7 files changed

+282
-9
lines changed

.github/workflows/typecheck.yml

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
name: Validate static types in quaddtype
2+
permissions: read-all
3+
4+
on:
5+
pull_request:
6+
paths:
7+
- .github/workflows/typecheck.yml
8+
- quaddtype/numpy_quaddtype/*
9+
- quaddtype/meson.build
10+
- quaddtype/pyproject.toml
11+
workflow_dispatch:
12+
13+
concurrency:
14+
group: ${{ github.workflow }}-${{ github.head_ref || github.run_id }}
15+
cancel-in-progress: true
16+
17+
jobs:
18+
typecheck_quaddtype:
19+
runs-on: ubuntu-latest
20+
timeout-minutes: 2
21+
22+
steps:
23+
- uses: actions/[email protected]
24+
25+
- uses: astral-sh/[email protected]
26+
with:
27+
activate-environment: true
28+
python-version: "3.10"
29+
30+
- name: install
31+
working-directory: quaddtype
32+
run: uv pip install mypy pyright .
33+
34+
- name: pyright
35+
working-directory: quaddtype
36+
run: pyright
37+
38+
- name: pyright --verifytypes
39+
working-directory: quaddtype
40+
run: pyright --ignoreexternal --verifytypes numpy_quaddtype
41+
42+
- name: mypy
43+
working-directory: quaddtype
44+
run: mypy --no-incremental --cache-dir=/dev/null .
45+
46+
- name: stubtest
47+
working-directory: quaddtype
48+
run: stubtest --mypy-config-file pyproject.toml numpy_quaddtype

quaddtype/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Numpy-QuadDType
1+
# NumPy-QuadDType
22

33
A cross-platform Quad (128-bit) float Data-Type for NumPy.
44

quaddtype/meson.build

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ if openmp_dep.found()
3535
dependencies += openmp_dep
3636
endif
3737

38-
# compiler flags for QBLAS compatibility
38+
# compiler flags for QBLAS compatibility
3939
if not is_windows
4040
# QBLAS requires extended numeric literals for Q suffix support
4141
# if compiler supports (usually gcc)
@@ -61,14 +61,14 @@ foreach optional_attr: optional_variable_attributes
6161
code = '''
6262
#pragma GCC diagnostic error "-Wattributes"
6363
#pragma clang diagnostic error "-Wattributes"
64-
64+
6565
int @0@ foo;
66-
66+
6767
int main() {
6868
return 0;
6969
}
7070
'''.format(attr)
71-
71+
7272
if c.compiles(code, name: optional_attr[0])
7373
cdata.set10(optional_attr[1], true)
7474
message('Thread-local storage support found: @0@'.format(attr))
@@ -122,6 +122,9 @@ srcs = [
122122
py.install_sources(
123123
[
124124
'numpy_quaddtype/__init__.py',
125+
'numpy_quaddtype/__init__.pyi',
126+
'numpy_quaddtype/_quaddtype_main.pyi',
127+
'numpy_quaddtype/py.typed',
125128
],
126129
subdir: 'numpy_quaddtype',
127130
pure: false
@@ -134,4 +137,4 @@ py.extension_module('_quaddtype_main',
134137
install: true,
135138
subdir: 'numpy_quaddtype',
136139
include_directories: [includes, build_includes],
137-
)
140+
)
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
from typing import Final
2+
3+
from ._quaddtype_main import (
4+
QuadPrecDType,
5+
QuadPrecision,
6+
_IntoQuad, # type-check only # pyright: ignore[reportPrivateUsage]
7+
get_num_threads,
8+
get_quadblas_version,
9+
is_longdouble_128,
10+
set_num_threads,
11+
)
12+
13+
__all__ = [
14+
"QuadPrecision",
15+
"QuadPrecDType",
16+
"SleefQuadPrecision",
17+
"LongDoubleQuadPrecision",
18+
"SleefQuadPrecDType",
19+
"LongDoubleQuadPrecDType",
20+
"is_longdouble_128",
21+
"pi",
22+
"e",
23+
"log2e",
24+
"log10e",
25+
"ln2",
26+
"ln10",
27+
"max_value",
28+
"epsilon",
29+
"smallest_normal",
30+
"smallest_subnormal",
31+
"bits",
32+
"precision",
33+
"resolution",
34+
"set_num_threads",
35+
"get_num_threads",
36+
"get_quadblas_version",
37+
]
38+
39+
def SleefQuadPrecision(value: _IntoQuad) -> QuadPrecision: ...
40+
def LongDoubleQuadPrecision(value: _IntoQuad) -> QuadPrecision: ...
41+
def SleefQuadPrecDType() -> QuadPrecDType: ...
42+
def LongDoubleQuadPrecDType() -> QuadPrecDType: ...
43+
44+
pi: Final[QuadPrecision] = ...
45+
e: Final[QuadPrecision] = ...
46+
log2e: Final[QuadPrecision] = ...
47+
log10e: Final[QuadPrecision] = ...
48+
ln2: Final[QuadPrecision] = ...
49+
ln10: Final[QuadPrecision] = ...
50+
max_value: Final[QuadPrecision] = ...
51+
epsilon: Final[QuadPrecision] = ...
52+
smallest_normal: Final[QuadPrecision] = ...
53+
smallest_subnormal: Final[QuadPrecision] = ...
54+
resolution: Final[QuadPrecision] = ...
55+
bits: Final = 128
56+
precision: Final = 33
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
from typing import Any, Literal, TypeAlias, final, overload
2+
3+
import numpy as np
4+
from typing_extensions import Never, Self, override
5+
6+
_Backend: TypeAlias = Literal["sleef", "longdouble"]
7+
_IntoQuad: TypeAlias = QuadPrecision | float | str
8+
_CastsQuad: TypeAlias = _IntoQuad | np.floating[Any] | np.integer[Any] | np.bool_
9+
10+
@final
11+
class QuadPrecDType(np.dtype[QuadPrecision]): # type: ignore[misc, type-var] # pyright: ignore[reportGeneralTypeIssues, reportInvalidTypeArguments]
12+
def __new__(cls, /, backend: _Backend = "sleef") -> Self: ...
13+
14+
# `numpy.dtype` overrides
15+
names: None # pyright: ignore[reportIncompatibleVariableOverride]
16+
@property
17+
@override
18+
def alignment(self) -> Literal[16]: ...
19+
@property
20+
@override
21+
def itemsize(self) -> Literal[16]: ...
22+
@property
23+
@override
24+
def name(self) -> Literal["QuadPrecDType128"]: ...
25+
@property
26+
@override
27+
def byteorder(self) -> Literal["|"]: ...
28+
@property
29+
@override
30+
def char(self) -> Literal["\x00"]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
31+
@property
32+
@override
33+
def kind(self) -> Literal["\x00"]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
34+
@property
35+
@override
36+
def num(self) -> Literal[-1]: ... # type: ignore[override] # pyright: ignore[reportIncompatibleMethodOverride]
37+
@property
38+
@override
39+
def shape(self) -> tuple[()]: ...
40+
@property
41+
@override
42+
def ndim(self) -> Literal[0]: ...
43+
@property
44+
@override
45+
def fields(self) -> None: ...
46+
@property
47+
@override
48+
def base(self) -> Self: ...
49+
@property
50+
@override
51+
def subdtype(self) -> None: ...
52+
@property
53+
@override
54+
def hasobject(self) -> Literal[False]: ...
55+
@property
56+
@override
57+
def isbuiltin(self) -> Literal[0]: ...
58+
@property
59+
@override
60+
def isnative(self) -> Literal[True]: ...
61+
@property
62+
@override
63+
def isalignedstruct(self) -> Literal[False]: ...
64+
@override
65+
def __getitem__(self, key: Never, /) -> Self: ... # type: ignore[override]
66+
67+
@final
68+
class QuadPrecision: # NOTE: It doesn't inherit from `np.generic` which is type-unsafe
69+
def __new__(cls, /, value: _IntoQuad, backend: _Backend = "sleef") -> Self: ...
70+
71+
# Rich comparison operators
72+
# NOTE: Unlike other numpy scalars, these return `builtins.bool`, not `np.bool`.
73+
@override
74+
def __eq__(self, other: object, /) -> bool: ...
75+
@override
76+
def __ne__(self, other: object, /) -> bool: ...
77+
def __lt__(self, other: _IntoQuad, /) -> bool: ...
78+
def __le__(self, other: _IntoQuad, /) -> bool: ...
79+
def __gt__(self, other: _IntoQuad, /) -> bool: ...
80+
def __ge__(self, other: _IntoQuad, /) -> bool: ...
81+
82+
# Binary operators
83+
def __add__(self, other: _CastsQuad, /) -> Self: ...
84+
def __radd__(self, other: _CastsQuad, /) -> Self: ... # type: ignore[misc]
85+
def __sub__(self, other: _CastsQuad, /) -> Self: ...
86+
def __rsub__(self, other: _CastsQuad, /) -> Self: ...
87+
def __mul__(self, other: _CastsQuad, /) -> Self: ...
88+
def __rmul__(self, other: _CastsQuad, /) -> Self: ... # type: ignore[misc]
89+
def __pow__(self, other: _CastsQuad, mod: None = None, /) -> Self: ...
90+
def __rpow__(self, other: _CastsQuad, mod: None = None, /) -> Self: ...
91+
def __truediv__(self, other: _CastsQuad, /) -> Self: ...
92+
def __rtruediv__(self, other: _CastsQuad, /) -> Self: ...
93+
94+
# Unary operators
95+
def __neg__(self, /) -> Self: ...
96+
def __pos__(self, /) -> Self: ...
97+
def __abs__(self, /) -> Self: ...
98+
99+
# Conversion methods
100+
def __bool__(self, /) -> bool: ...
101+
def __int__(self, /) -> int: ...
102+
def __float__(self, /) -> float: ...
103+
104+
# String representation
105+
@override
106+
def __repr__(self, /) -> str: ...
107+
@override
108+
def __str__(self, /) -> str: ...
109+
110+
#
111+
def is_longdouble_128() -> bool: ...
112+
113+
@overload
114+
def get_sleef_constant(constant_name: Literal["bits", "precision"], /) -> int: ...
115+
@overload
116+
def get_sleef_constant(
117+
constant_name: Literal[
118+
"pi",
119+
"e",
120+
"log2e",
121+
"log10e",
122+
"ln2",
123+
"ln10",
124+
"max_value",
125+
"epsilon",
126+
"smallest_normal",
127+
"smallest_subnormal",
128+
"resolution",
129+
],
130+
/,
131+
) -> QuadPrecision: ...
132+
133+
def set_num_threads(num_threads: int, /) -> None: ...
134+
def get_num_threads() -> int: ...
135+
def get_quadblas_version() -> str: ...

quaddtype/numpy_quaddtype/py.typed

Whitespace-only changes.

quaddtype/pyproject.toml

Lines changed: 34 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[build-system]
22
requires = [
33
"meson>=1.3.2",
4-
"meson-python",
4+
"meson-python>=0.18.0",
55
"wheel",
66
"numpy"
77
]
@@ -12,8 +12,20 @@ name = "numpy_quaddtype"
1212
description = "Quad (128-bit) float dtype for numpy"
1313
version = "0.2.0"
1414
readme = 'README.md'
15-
license = { file = "LICENSE" }
15+
license = "BSD-3-Clause"
16+
license-files = ["LICENSE"]
1617
authors = [{name = "Swayam Singh", email = "[email protected]"}]
18+
classifiers = [
19+
"Development Status :: 4 - Beta",
20+
"Programming Language :: Python :: 3",
21+
"Programming Language :: Python :: 3.10",
22+
"Programming Language :: Python :: 3.11",
23+
"Programming Language :: Python :: 3.12",
24+
"Programming Language :: Python :: 3.13",
25+
"Programming Language :: Python :: 3.14",
26+
"Programming Language :: Python :: Free Threading",
27+
"Typing :: Typed",
28+
]
1729
requires-python = ">=3.10.0"
1830
dependencies = [
1931
"numpy"
@@ -23,4 +35,23 @@ dependencies = [
2335
test = [
2436
"pytest",
2537
"pytest-run-parallel"
26-
]
38+
]
39+
40+
[project.urls]
41+
Repository = "https://github.com/numpy/numpy-user-dtypes"
42+
Documentation = "https://github.com/numpy/numpy-user-dtypes/tree/main/quaddtype"
43+
Issues = "https://github.com/numpy/numpy-user-dtypes/issues"
44+
45+
[tool.pyright]
46+
include = ["numpy_quaddtype/*.pyi"]
47+
typeCheckingMode = "strict"
48+
enableTypeIgnoreComments = false
49+
reportImplicitOverride = true
50+
reportUnnecessaryTypeIgnoreComment = true
51+
52+
[tool.mypy]
53+
strict = true
54+
strict_equality_for_none = true
55+
exclude = ["build", "numpy_quaddtype/src", "subprojects", "tests"]
56+
enable_error_code = ["ignore-without-code", "redundant-expr", "truthy-bool"]
57+
warn_unreachable = false

0 commit comments

Comments
 (0)