-
-
Notifications
You must be signed in to change notification settings - Fork 538
add stub files for Cython modules in pywt/_extensions #847
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from 1 commit
5333fd7
b14096a
75c3b54
2ab1dc5
36225b9
15f1bf4
148aa41
2a41dbc
e9967a6
10bd0ef
c321403
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,4 @@ | ||
| from _pywt import ContinuousWavelet, DataT | ||
| from numpy.typing import NDArray | ||
|
|
||
| def cwt_psi_single(data: NDArray[DataT], wavelet: ContinuousWavelet, output_len: int) -> NDArray[DataT] | tuple[NDArray[DataT], NDArray[DataT]]: ... | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,12 @@ | ||
| from numpy.typing import NDArray | ||
|
|
||
| from pywt import MODE, CDataT, Wavelet | ||
|
|
||
| def dwt_max_level(data_len: int, filter_len: int) -> int: ... | ||
| def dwt_coeff_len(size_t: int, filter_len: int, mode: MODE) -> int: ... | ||
| def dwt_single(data: NDArray[CDataT], wavelet: Wavelet, mode: MODE) -> tuple[NDArray[CDataT], NDArray[CDataT]]: ... | ||
| def dwt_axis(data: NDArray[CDataT], wavelet: Wavelet, mode: MODE, axis: int = ...) -> tuple[NDArray[CDataT], NDArray[CDataT]]: ... | ||
| def idwt_single(cA: NDArray[CDataT], cD: NDArray[CDataT], wavelet: Wavelet, mode: MODE) -> NDArray[CDataT]: ... | ||
| def idwt_axis(coefs_a: NDArray[CDataT], coefs_d: NDArray[CDataT], wavelet: Wavelet, mode: MODE, axis: int = ...) -> NDArray[CDataT]: ... | ||
| def upcoef(do_rec_a: bool, coeffs: NDArray[CDataT], wavelet: Wavelet, level: int, take: int) -> NDArray[CDataT]: ... | ||
| def downcoef(do_dec_a: bool, data: NDArray[CDataT], wavelet: Wavelet, mode: MODE, level: int) -> NDArray[CDataT]: ... | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for the suggestion. I would ideally want to accept both the enum keys and valid integers, so something like this could solve it: class MODE(IntEnum):
MODE_INVALID = -1
MODE_ZEROPAD = 0
MODE_SYMMETRIC = 1
MODE_CONSTANT_EDGE = 2
MODE_SMOOTH = 3
MODE_PERIODIC = 4
MODE_PERIODIZATION = 5
MODE_REFLECT = 6
MODE_ANTISYMMETRIC = 7
MODE_ANTIREFLECT = 8
MODE_MAX = 9
ModeInt = MODE | Literal[-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9]Unfortunately there seems to be no better way of accepting only the integer values that the enum maps to, but I think the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. That looks like a good solution.
In Python typing land code duplication is unavoidable I'm afraid... |
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,185 @@ | ||||||||||||||||||||||||
| from enum import IntEnum | ||||||||||||||||||||||||
| from typing import Any, Literal, Optional, TypeVar | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| import numpy as np | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _WaveletFamily = Literal[ | ||||||||||||||||||||||||
| "haar", | ||||||||||||||||||||||||
| "db", | ||||||||||||||||||||||||
| "sym", | ||||||||||||||||||||||||
| "coif", | ||||||||||||||||||||||||
| "bior", | ||||||||||||||||||||||||
| "rbio", | ||||||||||||||||||||||||
| "dmey", | ||||||||||||||||||||||||
| "gaus", | ||||||||||||||||||||||||
| "mexh", | ||||||||||||||||||||||||
| "morl", | ||||||||||||||||||||||||
| "cgau", | ||||||||||||||||||||||||
| "shan", | ||||||||||||||||||||||||
| "fbsp", | ||||||||||||||||||||||||
| "cmor", | ||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| DataT = TypeVar("DataT", np.float32, np.float64) | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's usually best to avoid using type variable constraints like this, and instead use upper bounds. One reason for that is that there's quite a lot of difference in how different type-checkers deal with constraints, because it's under-specified in the typing spec. Another is that typevars with constraints don't accept typevars with bounds, which can be annoying for downstream library maintainers as they'd be forced to also use constraints. The other way around is no problem.
Suggested change
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for this tip, I was not aware of that issue |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| CDataT = TypeVar( | ||||||||||||||||||||||||
| "CDataT", | ||||||||||||||||||||||||
| np.float32, | ||||||||||||||||||||||||
| np.float64, | ||||||||||||||||||||||||
| np.complex64, | ||||||||||||||||||||||||
| np.complex128, | ||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _Kind = Literal["all", "continuous", "discrete"] | ||||||||||||||||||||||||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Type-checkers like it if you help them a bit and explicitly mark it as type alias:
Suggested change
(you'll have to import |
||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| _Symmetry = Literal[ | ||||||||||||||||||||||||
| "asymmetric", | ||||||||||||||||||||||||
| "near symmetric", | ||||||||||||||||||||||||
| "symmetric", | ||||||||||||||||||||||||
| "anti-symmetric", | ||||||||||||||||||||||||
| "unknown", | ||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class MODE(IntEnum): | ||||||||||||||||||||||||
| MODE_INVALID = -1 | ||||||||||||||||||||||||
| MODE_ZEROPAD = 0 | ||||||||||||||||||||||||
| MODE_SYMMETRIC = 1 | ||||||||||||||||||||||||
| MODE_CONSTANT_EDGE = 2 | ||||||||||||||||||||||||
| MODE_SMOOTH = 3 | ||||||||||||||||||||||||
| MODE_PERIODIC = 4 | ||||||||||||||||||||||||
| MODE_PERIODIZATION = 5 | ||||||||||||||||||||||||
| MODE_REFLECT = 6 | ||||||||||||||||||||||||
| MODE_ANTISYMMETRIC = 7 | ||||||||||||||||||||||||
| MODE_ANTIREFLECT = 8 | ||||||||||||||||||||||||
| MODE_MAX = 9 | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| ModeName = Literal[ | ||||||||||||||||||||||||
| "zero", | ||||||||||||||||||||||||
| "constant", | ||||||||||||||||||||||||
| "symmetric", | ||||||||||||||||||||||||
| "reflect", | ||||||||||||||||||||||||
| "periodic", | ||||||||||||||||||||||||
| "smooth", | ||||||||||||||||||||||||
| "periodization", | ||||||||||||||||||||||||
| "antisymmetric", | ||||||||||||||||||||||||
| "antireflect", | ||||||||||||||||||||||||
| ] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Mode = MODE | ModeName | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class _Modes: | ||||||||||||||||||||||||
| zero: int | ||||||||||||||||||||||||
| constant: int | ||||||||||||||||||||||||
| symmetric: int | ||||||||||||||||||||||||
| reflect: int | ||||||||||||||||||||||||
| periodic: int | ||||||||||||||||||||||||
| smooth: int | ||||||||||||||||||||||||
| periodization: int | ||||||||||||||||||||||||
| antisymmetric: int | ||||||||||||||||||||||||
| antireflect: int | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| modes: list[ModeName] | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def from_object(self, mode: Mode) -> int: ... | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| Modes = _Modes() | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def wavelist(family: _WaveletFamily | None = ..., kind: _Kind = ...) -> list[str]: ... | ||||||||||||||||||||||||
| def families(short: bool = ...) -> list[str]: ... | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class Wavelet: | ||||||||||||||||||||||||
| def __init__(self, name: str = ..., filter_bank: Any = ...) -> None: ... | ||||||||||||||||||||||||
| def __len__(self) -> int: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def name(self) -> str: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def dec_lo(self) -> list[float]: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def dec_hi(self) -> list[float]: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def rec_lo(self) -> list[float]: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def rec_hi(self) -> list[float]: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def rec_len(self) -> int: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def dec_len(self) -> int: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def family_number(self) -> int: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def family_name(self) -> str: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def short_family_name(self) -> str: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def orthogonal(self) -> bool: ... | ||||||||||||||||||||||||
| @orthogonal.setter | ||||||||||||||||||||||||
| def orthogonal(self, value: bool) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def biorthogonal(self) -> bool: ... | ||||||||||||||||||||||||
| @biorthogonal.setter | ||||||||||||||||||||||||
| def biorthogonal(self, value: bool) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def symmetry(self) -> _Symmetry: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def vanishing_moments_psi(self) -> int | None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def vanishing_moments_phi(self) -> int | None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def filter_bank( | ||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||
| ) -> tuple[list[float], list[float], list[float], list[float]]: ... | ||||||||||||||||||||||||
| def get_filters_coeffs( | ||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||
| ) -> tuple[list[float], list[float], list[float], list[float]]: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def inverse_filter_bank( | ||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||
| ) -> tuple[list[float], list[float], list[float], list[float]]: ... | ||||||||||||||||||||||||
| def get_reverse_filters_coeffs( | ||||||||||||||||||||||||
| self, | ||||||||||||||||||||||||
| ) -> tuple[list[float], list[float], list[float], list[float]]: ... | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| class ContinuousWavelet: | ||||||||||||||||||||||||
| def __init__(self, name: str = ..., dtype: DataT = ...) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def family_number(self) -> int: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def family_name(self) -> str: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def short_family_name(self) -> str: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def orthogonal(self) -> bool: ... | ||||||||||||||||||||||||
| @orthogonal.setter | ||||||||||||||||||||||||
| def orthogonal(self, value: bool) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def biorthogonal(self) -> bool: ... | ||||||||||||||||||||||||
| @biorthogonal.setter | ||||||||||||||||||||||||
| def biorthogonal(self, value: bool) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def complex_cwt(self) -> bool: ... | ||||||||||||||||||||||||
| @complex_cwt.setter | ||||||||||||||||||||||||
| def complex_cwt(self, value: bool) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def lower_bound(self) -> float | None: ... | ||||||||||||||||||||||||
| @lower_bound.setter | ||||||||||||||||||||||||
| def lower_bound(self, value: float) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def upper_bound(self) -> float | None: ... | ||||||||||||||||||||||||
| @upper_bound.setter | ||||||||||||||||||||||||
| def upper_bound(self, value: float) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def center_frequency(self) -> float | None: ... | ||||||||||||||||||||||||
| @center_frequency.setter | ||||||||||||||||||||||||
| def center_frequency(self, value: float) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def bandwidth_frequency(self) -> float | None: ... | ||||||||||||||||||||||||
| @bandwidth_frequency.setter | ||||||||||||||||||||||||
| def bandwidth_frequency(self, value: float) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def fbsp_order(self) -> int | None: ... | ||||||||||||||||||||||||
| @fbsp_order.setter | ||||||||||||||||||||||||
| def fbsp_order(self, value: int) -> None: ... | ||||||||||||||||||||||||
| @property | ||||||||||||||||||||||||
| def symmetry(self) -> _Symmetry: ... | ||||||||||||||||||||||||
|
|
||||||||||||||||||||||||
| def DiscreteContinuousWavelet(name: str = ..., filter_bank: Any = ...) -> Wavelet | ContinuousWavelet : ... | ||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,7 @@ | ||
| from numpy.typing import NDArray | ||
|
|
||
| from pywt import CDataT, Wavelet | ||
|
|
||
| def swt_max_level(input_len: int) -> int: ... | ||
| def swt(data: NDArray[CDataT], wavelet: Wavelet, level: int, start_level: int, trim_approx: bool = ...) -> NDArray[CDataT]: ... | ||
| def swt_axis(data: NDArray[CDataT], wavelet: Wavelet, level: int, start_level: int, axis: int = ..., trim_approx: bool = ...) -> NDArray[CDataT]: ... | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For documentation purposes it can help to fill in the |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's usually better to avoid importing type variables like this, and to make them private (prefix them with
_). One reason is that it'll make it easier to switch to the new PEP 695 syntax once Python <3.12 support is dropped. There are also theoretical reasons I won't bore you with.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the hint, I corrected it in a new commit.