Skip to content

Commit 8ec8656

Browse files
committed
typing: Enhance support for type hints
1 parent 543319c commit 8ec8656

13 files changed

+608
-334
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ build/
22
dist/
33
*.egg-info/
44
__pycache__/
5+
.mypy_cache
56
.tox/
67
.coverage*
78
*.py[cod]

.mypy.ini

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
[mypy]
2+
warn_return_any = True
3+
warn_unreachable = True
4+
warn_unused_ignores = True
5+
warn_redundant_casts = True
6+
show_error_codes = True
7+
exclude = (?x)(
8+
^shmem4py/src/.*\.py$ |
9+
^demo/api/.*\.py$
10+
)
11+
12+
[mypy-shmem4py.shmem.*]
13+
warn_return_any = False

makefile

+2
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ test-%:
2121
.PHONY: lint
2222
lint:
2323
-pycodestyle shmem4py
24+
-flake8 shmem4py
2425
-pylint shmem4py
2526

2627
.PHONY: cover cover-html
@@ -38,6 +39,7 @@ clean:
3839
-$(RM) -r build shmem4py/*.so shmem4py.egg-info
3940
-$(RM) -r */__pycache__ */*/__pycache__
4041
-$(RM) -r .coverage* htmlcov/
42+
-$(RM) -r .mypy_cache
4143

4244
.PHONY: install uninstall
4345
install:

setup.cfg

+5-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
[metadata]
22
name = shmem4py
33
version = attr: shmem4py.__version__
4-
license = BSD
4+
license = BSD-2-Clause
55
description = Python bindings for OpenSHMEM
66
long_description = file: README.md
77
long_description_content_type = text/markdown
@@ -14,6 +14,10 @@ install_requires = cffi>=1.13,numpy>=1.12
1414
python_requires = >=3.7
1515

1616

17+
[flake8]
18+
exclude = shmem4py/src/*
19+
20+
1721
[coverage:run]
1822
parallel = True
1923
branch = True

setup.py

+3
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,9 @@ def run(self):
3333
packages = [
3434
'shmem4py',
3535
],
36+
package_data = {
37+
'shmem4py' : ['api.pyi'],
38+
},
3639
cffi_modules = [
3740
'shmem4py/src/api_build.py:ffibuilder',
3841
],

shmem4py/__init__.py

+10-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
# Author: Lisandro Dalcin
22
33
"""OpenSHMEM for Python."""
4+
from __future__ import annotations as _annotations
5+
import typing as _typing
6+
7+
if _typing.TYPE_CHECKING: # pragma: no cover
8+
from typing import Any, Optional
9+
410

511
__version__ = '0.1.0'
612
__author__ = 'Lisandro Dalcin'
@@ -26,17 +32,17 @@ class Rc:
2632
initialize: bool = True
2733
threads: bool = False
2834
thread_level: str = 'multiple'
29-
finalize: 'Optional[bool]' = None
35+
finalize: Optional[bool] = None
3036

31-
def __init__(self, **kwargs: 'Any') -> None:
37+
def __init__(self, **kwargs: Any) -> None:
3238
self(**kwargs)
3339

34-
def __setattr__(self, name: str, value: 'Any') -> None:
40+
def __setattr__(self, name: str, value: Any) -> None:
3541
if not hasattr(self, name):
3642
raise TypeError(f"object has no attribute '{name}'")
3743
super().__setattr__(name, value)
3844

39-
def __call__(self, **kwargs: 'Any') -> None:
45+
def __call__(self, **kwargs: Any) -> None:
4046
for key in kwargs:
4147
if not hasattr(self, key):
4248
raise TypeError(f"unexpected argument '{key}'")

shmem4py/__main__.py

+2-1
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
11
# Author: Lisandro Dalcin
22
33
"""Print shmem4py version."""
4+
from __future__ import annotations as _annotations
45

56

67
def main() -> None:
78
"""Entry-point for ``python -m shmem4py ...``."""
89
# pylint: disable=import-outside-toplevel
9-
package = __spec__.parent
10+
package = __spec__.parent # type: ignore[name-defined]
1011
from . import __version__
1112
print(f"{package} {__version__}")
1213

shmem4py/api.pyi

+152
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
from typing import (
2+
Any,
3+
List,
4+
Union,
5+
TypeVar,
6+
Callable,
7+
overload,
8+
)
9+
10+
_T = TypeVar('_T')
11+
_PyBuffer = Any
12+
13+
14+
class FFI:
15+
16+
class CType:
17+
cname: str
18+
kind: str
19+
item: ffi.CType
20+
21+
class CData:
22+
def __getitem__(self, item: int) -> Any: ...
23+
def __setitem__(self, item: int, value: Any) -> None: ...
24+
25+
class buffer:
26+
@overload
27+
def __init__(self, cdata: ffi.CData) -> None: ...
28+
@overload
29+
def __init__(self, cdata: ffi.CData, size: int) -> None: ...
30+
31+
class error(Exception):
32+
pass
33+
34+
NULL: CData
35+
36+
errno: int
37+
38+
@staticmethod
39+
def new(cdecl: Any, init: Any = ...) -> CData: ...
40+
41+
@overload
42+
@staticmethod
43+
def cast(ctype: str, value: Any) -> CData: ...
44+
@overload
45+
@staticmethod
46+
def cast(ctype: CType, value: Any) -> CData: ...
47+
48+
@overload
49+
@staticmethod
50+
def string(cdata: CData) -> bytes: ...
51+
@overload
52+
@staticmethod
53+
def string(cdata: CData, maxlen: int) -> bytes: ...
54+
55+
@staticmethod
56+
def unpack(cdata: CData, lenght: int) -> Union[bytes, str, List[Any]]: ...
57+
58+
@overload
59+
@staticmethod
60+
def from_buffer(cdecl: str, python_buffer: _PyBuffer, require_writable: bool = ...) -> CData: ...
61+
@overload
62+
@staticmethod
63+
def from_buffer(cdecl: CType, python_buffer: _PyBuffer, require_writable: bool = ...) -> CData: ...
64+
@overload
65+
@staticmethod
66+
def from_buffer(python_buffer: _PyBuffer, require_writable: bool = ...) -> CData: ...
67+
68+
@staticmethod
69+
def memmove(dest: CData, src: CData, n: int) -> None: ...
70+
71+
@overload
72+
@staticmethod
73+
def typeof(ctype: str) -> CType: ...
74+
@overload
75+
@staticmethod
76+
def typeof(cdata: CData) -> CType: ...
77+
78+
@overload
79+
@staticmethod
80+
def sizeof(ctype: str) -> int: ...
81+
@overload
82+
@staticmethod
83+
def sizeof(ctype: CType) -> int: ...
84+
@overload
85+
@staticmethod
86+
def sizeof(cdata: CData) -> int: ...
87+
88+
@overload
89+
@staticmethod
90+
def alignof(ctype: str) -> int: ...
91+
@overload
92+
@staticmethod
93+
def alignof(ctype: CType) -> int: ...
94+
@overload
95+
@staticmethod
96+
def alignof(cdata: CData) -> int: ...
97+
98+
@overload
99+
@staticmethod
100+
def offsetof(ctype: str, *args: Union[int, str]) -> int: ...
101+
@overload
102+
@staticmethod
103+
def offsetof(ctype: CType, *args: Union[int, str]) -> int: ...
104+
105+
@staticmethod
106+
def addressof(cdata: CData, *args: Union[int, str]) -> CData: ...
107+
108+
@staticmethod
109+
def gc(
110+
cdata: CData,
111+
destructor: Callable[[CData], None],
112+
size: int = ...
113+
) -> CData: ...
114+
115+
@staticmethod
116+
def new_handle(python_object: Any) -> CData: ...
117+
118+
@staticmethod
119+
def from_handle(cdata: CData) -> Any: ...
120+
121+
@staticmethod
122+
def new_allocator(
123+
malloc: Callable[[int], CData],
124+
free: Callable[[CData], None],
125+
should_clear_after_alloc: bool = ...,
126+
) -> Callable[..., CData]: ...
127+
128+
@overload
129+
@staticmethod
130+
def release(cdata: CData) -> None: ...
131+
@overload
132+
@staticmethod
133+
def release(cdata: ffi.buffer) -> None: ...
134+
135+
@staticmethod
136+
def init_once(function: Callable[[], _T], tag: str) -> _T: ...
137+
138+
@overload
139+
@staticmethod
140+
def getctype(ctype: str, extra: str = ...) -> str: ...
141+
@overload
142+
@staticmethod
143+
def getctype(ctype: CType, extra: str = ...) -> str: ...
144+
145+
146+
class Lib:
147+
def __getattr__(self, attr: str) -> Any: ...
148+
def __setattr__(self, attr: str, value: Any) -> None: ...
149+
150+
151+
ffi = FFI
152+
lib: Lib = ...

0 commit comments

Comments
 (0)