oprattr 0.2.0__py3-none-any.whl → 0.3.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of oprattr might be problematic. Click here for more details.
- oprattr/__init__.py +6 -5
- oprattr/_operations.py +20 -22
- oprattr/abstract.py +13 -101
- oprattr/mixins.py +12 -11
- oprattr/operators.py +2 -2
- oprattr/typeface.py +42 -0
- oprattr/typeface.pyi +5 -0
- {oprattr-0.2.0.dist-info → oprattr-0.3.0.dist-info}/METADATA +3 -1
- oprattr-0.3.0.dist-info/RECORD +12 -0
- oprattr-0.3.0.dist-info/licenses/LICENSE +32 -0
- oprattr-0.2.0.dist-info/RECORD +0 -9
- {oprattr-0.2.0.dist-info → oprattr-0.3.0.dist-info}/WHEEL +0 -0
oprattr/__init__.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import collections.abc
|
|
1
2
|
import functools
|
|
2
3
|
import numbers
|
|
3
|
-
import typing
|
|
4
4
|
|
|
5
5
|
import numpy
|
|
6
6
|
|
|
7
|
+
from . import abstract
|
|
7
8
|
from . import mixins
|
|
8
9
|
from . import operators
|
|
9
|
-
from . import
|
|
10
|
+
from . import typeface
|
|
10
11
|
from ._operations import (
|
|
11
12
|
unary,
|
|
12
13
|
equality,
|
|
@@ -16,7 +17,7 @@ from ._operations import (
|
|
|
16
17
|
)
|
|
17
18
|
|
|
18
19
|
|
|
19
|
-
T =
|
|
20
|
+
T = typeface.TypeVar('T')
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
class Operand(abstract.Object[T], mixins.Numpy):
|
|
@@ -114,7 +115,7 @@ class Operand(abstract.Object[T], mixins.Numpy):
|
|
|
114
115
|
|
|
115
116
|
def __rpow__(self, other):
|
|
116
117
|
"""Called for other ** self."""
|
|
117
|
-
return
|
|
118
|
+
return NotImplemented
|
|
118
119
|
|
|
119
120
|
def __array__(self, *args, **kwargs):
|
|
120
121
|
"""Called for numpy.array(self)."""
|
|
@@ -155,7 +156,7 @@ def gradient(x: Operand[T], *args, **kwargs):
|
|
|
155
156
|
return type(x)(data, **meta)
|
|
156
157
|
|
|
157
158
|
|
|
158
|
-
def wrapnumpy(f:
|
|
159
|
+
def wrapnumpy(f: collections.abc.Callable):
|
|
159
160
|
"""Implement a numpy function for objects with metadata."""
|
|
160
161
|
@functools.wraps(f)
|
|
161
162
|
def method(x: Operand[T], **kwargs):
|
oprattr/_operations.py
CHANGED
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import typing
|
|
2
|
-
|
|
3
1
|
from . import operators
|
|
4
|
-
from .abstract import
|
|
2
|
+
from .abstract import Quantity
|
|
5
3
|
|
|
6
4
|
|
|
7
5
|
class MetadataError(TypeError):
|
|
@@ -11,8 +9,8 @@ class MetadataError(TypeError):
|
|
|
11
9
|
self,
|
|
12
10
|
f: operators.Operator,
|
|
13
11
|
*args,
|
|
14
|
-
error:
|
|
15
|
-
key:
|
|
12
|
+
error: str | None = None,
|
|
13
|
+
key: str | None = None,
|
|
16
14
|
) -> None:
|
|
17
15
|
super().__init__(*args)
|
|
18
16
|
self._f = f
|
|
@@ -33,8 +31,8 @@ class MetadataError(TypeError):
|
|
|
33
31
|
def _build_error_message(
|
|
34
32
|
f: operators.Operator,
|
|
35
33
|
*types: type,
|
|
36
|
-
error:
|
|
37
|
-
key:
|
|
34
|
+
error: str | None = None,
|
|
35
|
+
key: str | None = None,
|
|
38
36
|
) -> str:
|
|
39
37
|
"""Helper for `_raise_metadata_exception`.
|
|
40
38
|
|
|
@@ -50,9 +48,9 @@ def _build_error_message(
|
|
|
50
48
|
if len(types) == 2:
|
|
51
49
|
a, b = types
|
|
52
50
|
endstr = "because {} has metadata"
|
|
53
|
-
if issubclass(a,
|
|
51
|
+
if issubclass(a, Quantity):
|
|
54
52
|
return f"{errmsg} between {a} and {b} {endstr.format(str(a))}"
|
|
55
|
-
if issubclass(b,
|
|
53
|
+
if issubclass(b, Quantity):
|
|
56
54
|
return f"{errmsg} between {a} and {b} {endstr.format(str(b))}"
|
|
57
55
|
if errstr == 'type':
|
|
58
56
|
if key is None:
|
|
@@ -71,7 +69,7 @@ def _build_error_message(
|
|
|
71
69
|
|
|
72
70
|
def unary(f: operators.Operator, a):
|
|
73
71
|
"""Compute the unary operation f(a)."""
|
|
74
|
-
if isinstance(a,
|
|
72
|
+
if isinstance(a, Quantity):
|
|
75
73
|
meta = {}
|
|
76
74
|
for key, value in a._meta.items():
|
|
77
75
|
try:
|
|
@@ -86,15 +84,15 @@ def unary(f: operators.Operator, a):
|
|
|
86
84
|
|
|
87
85
|
def equality(f: operators.Operator, a, b):
|
|
88
86
|
"""Compute the equality operation f(a, b)."""
|
|
89
|
-
if isinstance(a,
|
|
87
|
+
if isinstance(a, Quantity) and isinstance(b, Quantity):
|
|
90
88
|
if a._meta != b._meta:
|
|
91
89
|
return f is operators.ne
|
|
92
90
|
return f(a._data, b._data)
|
|
93
|
-
if isinstance(a,
|
|
91
|
+
if isinstance(a, Quantity):
|
|
94
92
|
if not a._meta:
|
|
95
93
|
return f(a._data, b)
|
|
96
94
|
return f is operators.ne
|
|
97
|
-
if isinstance(b,
|
|
95
|
+
if isinstance(b, Quantity):
|
|
98
96
|
if not b._meta:
|
|
99
97
|
return f(a, b._data)
|
|
100
98
|
return f is operators.ne
|
|
@@ -103,15 +101,15 @@ def equality(f: operators.Operator, a, b):
|
|
|
103
101
|
|
|
104
102
|
def ordering(f: operators.Operator, a, b):
|
|
105
103
|
"""Compute the ordering operation f(a, b)."""
|
|
106
|
-
if isinstance(a,
|
|
104
|
+
if isinstance(a, Quantity) and isinstance(b, Quantity):
|
|
107
105
|
if a._meta == b._meta:
|
|
108
106
|
return f(a._data, b._data)
|
|
109
107
|
raise MetadataError(f, a, b, error='unequal') from None
|
|
110
|
-
if isinstance(a,
|
|
108
|
+
if isinstance(a, Quantity):
|
|
111
109
|
if not a._meta:
|
|
112
110
|
return f(a._data, b)
|
|
113
111
|
raise MetadataError(f, a, b, error='non-empty') from None
|
|
114
|
-
if isinstance(b,
|
|
112
|
+
if isinstance(b, Quantity):
|
|
115
113
|
if not b._meta:
|
|
116
114
|
return f(a, b._data)
|
|
117
115
|
raise MetadataError(f, a, b, error='non-empty') from None
|
|
@@ -120,15 +118,15 @@ def ordering(f: operators.Operator, a, b):
|
|
|
120
118
|
|
|
121
119
|
def additive(f: operators.Operator, a, b):
|
|
122
120
|
"""Compute the additive operation f(a, b)."""
|
|
123
|
-
if isinstance(a,
|
|
121
|
+
if isinstance(a, Quantity) and isinstance(b, Quantity):
|
|
124
122
|
if a._meta == b._meta:
|
|
125
123
|
return type(a)(f(a._data, b._data), **a._meta)
|
|
126
124
|
raise MetadataError(f, a, b, error='unequal') from None
|
|
127
|
-
if isinstance(a,
|
|
125
|
+
if isinstance(a, Quantity):
|
|
128
126
|
if not a._meta:
|
|
129
127
|
return type(a)(f(a._data, b))
|
|
130
128
|
raise MetadataError(f, a, b, error='non-empty') from None
|
|
131
|
-
if isinstance(b,
|
|
129
|
+
if isinstance(b, Quantity):
|
|
132
130
|
if not b._meta:
|
|
133
131
|
return type(b)(f(a, b._data))
|
|
134
132
|
raise MetadataError(f, a, b, error='non-empty') from None
|
|
@@ -137,7 +135,7 @@ def additive(f: operators.Operator, a, b):
|
|
|
137
135
|
|
|
138
136
|
def multiplicative(f: operators.Operator, a, b):
|
|
139
137
|
"""Compute the multiplicative operation f(a, b)."""
|
|
140
|
-
if isinstance(a,
|
|
138
|
+
if isinstance(a, Quantity) and isinstance(b, Quantity):
|
|
141
139
|
keys = set(a._meta) & set(b._meta)
|
|
142
140
|
meta = {}
|
|
143
141
|
for key in keys:
|
|
@@ -154,7 +152,7 @@ def multiplicative(f: operators.Operator, a, b):
|
|
|
154
152
|
if key not in keys:
|
|
155
153
|
meta[key] = value
|
|
156
154
|
return type(a)(f(a._data, b._data), **meta)
|
|
157
|
-
if isinstance(a,
|
|
155
|
+
if isinstance(a, Quantity):
|
|
158
156
|
meta = {}
|
|
159
157
|
for key, value in a._meta.items():
|
|
160
158
|
try:
|
|
@@ -164,7 +162,7 @@ def multiplicative(f: operators.Operator, a, b):
|
|
|
164
162
|
else:
|
|
165
163
|
meta[key] = v
|
|
166
164
|
return type(a)(f(a._data, b), **meta)
|
|
167
|
-
if isinstance(b,
|
|
165
|
+
if isinstance(b, Quantity):
|
|
168
166
|
meta = {}
|
|
169
167
|
for key, value in b._meta.items():
|
|
170
168
|
try:
|
oprattr/abstract.py
CHANGED
|
@@ -1,108 +1,13 @@
|
|
|
1
|
-
import abc
|
|
1
|
+
import collections.abc
|
|
2
2
|
import numbers
|
|
3
|
-
import typing
|
|
4
3
|
|
|
4
|
+
import numerical
|
|
5
5
|
import numpy.typing
|
|
6
6
|
|
|
7
|
+
from . import typeface
|
|
7
8
|
|
|
8
|
-
@typing.runtime_checkable
|
|
9
|
-
class Real(typing.Protocol):
|
|
10
|
-
"""Abstract protocol for real-valued objects."""
|
|
11
9
|
|
|
12
|
-
|
|
13
|
-
def __abs__(self):
|
|
14
|
-
return NotImplemented
|
|
15
|
-
|
|
16
|
-
@abc.abstractmethod
|
|
17
|
-
def __pos__(self):
|
|
18
|
-
return NotImplemented
|
|
19
|
-
|
|
20
|
-
@abc.abstractmethod
|
|
21
|
-
def __neg__(self):
|
|
22
|
-
return NotImplemented
|
|
23
|
-
|
|
24
|
-
@abc.abstractmethod
|
|
25
|
-
def __eq__(self, other):
|
|
26
|
-
return False
|
|
27
|
-
|
|
28
|
-
@abc.abstractmethod
|
|
29
|
-
def __ne__(self, other):
|
|
30
|
-
return True
|
|
31
|
-
|
|
32
|
-
@abc.abstractmethod
|
|
33
|
-
def __le__(self, other):
|
|
34
|
-
return NotImplemented
|
|
35
|
-
|
|
36
|
-
@abc.abstractmethod
|
|
37
|
-
def __lt__(self, other):
|
|
38
|
-
return NotImplemented
|
|
39
|
-
|
|
40
|
-
@abc.abstractmethod
|
|
41
|
-
def __ge__(self, other):
|
|
42
|
-
return NotImplemented
|
|
43
|
-
|
|
44
|
-
@abc.abstractmethod
|
|
45
|
-
def __gt__(self, other):
|
|
46
|
-
return NotImplemented
|
|
47
|
-
|
|
48
|
-
@abc.abstractmethod
|
|
49
|
-
def __add__(self, other):
|
|
50
|
-
return NotImplemented
|
|
51
|
-
|
|
52
|
-
@abc.abstractmethod
|
|
53
|
-
def __radd__(self, other):
|
|
54
|
-
return NotImplemented
|
|
55
|
-
|
|
56
|
-
@abc.abstractmethod
|
|
57
|
-
def __sub__(self, other):
|
|
58
|
-
return NotImplemented
|
|
59
|
-
|
|
60
|
-
@abc.abstractmethod
|
|
61
|
-
def __rsub__(self, other):
|
|
62
|
-
return NotImplemented
|
|
63
|
-
|
|
64
|
-
@abc.abstractmethod
|
|
65
|
-
def __mul__(self, other):
|
|
66
|
-
return NotImplemented
|
|
67
|
-
|
|
68
|
-
@abc.abstractmethod
|
|
69
|
-
def __rmul__(self, other):
|
|
70
|
-
return NotImplemented
|
|
71
|
-
|
|
72
|
-
@abc.abstractmethod
|
|
73
|
-
def __truediv__(self, other):
|
|
74
|
-
return NotImplemented
|
|
75
|
-
|
|
76
|
-
@abc.abstractmethod
|
|
77
|
-
def __rtruediv__(self, other):
|
|
78
|
-
return NotImplemented
|
|
79
|
-
|
|
80
|
-
@abc.abstractmethod
|
|
81
|
-
def __floordiv__(self, other):
|
|
82
|
-
return NotImplemented
|
|
83
|
-
|
|
84
|
-
@abc.abstractmethod
|
|
85
|
-
def __rfloordiv__(self, other):
|
|
86
|
-
return NotImplemented
|
|
87
|
-
|
|
88
|
-
@abc.abstractmethod
|
|
89
|
-
def __mod__(self, other):
|
|
90
|
-
return NotImplemented
|
|
91
|
-
|
|
92
|
-
@abc.abstractmethod
|
|
93
|
-
def __rmod__(self, other):
|
|
94
|
-
return NotImplemented
|
|
95
|
-
|
|
96
|
-
@abc.abstractmethod
|
|
97
|
-
def __pow__(self, other):
|
|
98
|
-
return NotImplemented
|
|
99
|
-
|
|
100
|
-
@abc.abstractmethod
|
|
101
|
-
def __rpow__(self, other):
|
|
102
|
-
return NotImplemented
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
DataType = typing.TypeVar(
|
|
10
|
+
DataType = typeface.TypeVar(
|
|
106
11
|
'DataType',
|
|
107
12
|
int,
|
|
108
13
|
float,
|
|
@@ -113,7 +18,14 @@ DataType = typing.TypeVar(
|
|
|
113
18
|
)
|
|
114
19
|
|
|
115
20
|
|
|
116
|
-
|
|
21
|
+
@typeface.runtime_checkable
|
|
22
|
+
class Quantity(numerical.Quantity[DataType], typeface.Protocol):
|
|
23
|
+
"""Protocol for numerical objects with metadata."""
|
|
24
|
+
|
|
25
|
+
_meta: collections.abc.Mapping[str, typeface.Any]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class Object(numerical.Real, typeface.Generic[DataType]):
|
|
117
29
|
"""A real-valued object with metadata attributes."""
|
|
118
30
|
|
|
119
31
|
def __init__(
|
|
@@ -121,7 +33,7 @@ class Object(Real, typing.Generic[DataType]):
|
|
|
121
33
|
__data: DataType,
|
|
122
34
|
**metadata,
|
|
123
35
|
) -> None:
|
|
124
|
-
if not isinstance(__data, Real):
|
|
36
|
+
if not isinstance(__data, numerical.Real):
|
|
125
37
|
raise TypeError("Data input to Object must be real-valued")
|
|
126
38
|
self._data = __data
|
|
127
39
|
self._meta = metadata
|
oprattr/mixins.py
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import collections.abc
|
|
1
2
|
import numbers
|
|
2
|
-
import typing
|
|
3
3
|
|
|
4
4
|
import numpy
|
|
5
5
|
|
|
6
6
|
from . import abstract
|
|
7
|
+
from . import typeface
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
T =
|
|
10
|
+
T = typeface.TypeVar('T')
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
class Real:
|
|
@@ -82,7 +83,7 @@ class Real:
|
|
|
82
83
|
return self
|
|
83
84
|
|
|
84
85
|
|
|
85
|
-
UserFunction =
|
|
86
|
+
UserFunction = collections.abc.Callable[..., T]
|
|
86
87
|
|
|
87
88
|
|
|
88
89
|
class Numpy:
|
|
@@ -127,7 +128,7 @@ class Numpy:
|
|
|
127
128
|
numpy.ndarray,
|
|
128
129
|
numbers.Number,
|
|
129
130
|
list,
|
|
130
|
-
abstract.
|
|
131
|
+
abstract.Quantity,
|
|
131
132
|
}
|
|
132
133
|
|
|
133
134
|
def __array_ufunc__(self, ufunc, method, *args, **kwargs):
|
|
@@ -162,7 +163,7 @@ class Numpy:
|
|
|
162
163
|
return NotImplemented
|
|
163
164
|
if out:
|
|
164
165
|
kwargs['out'] = tuple(
|
|
165
|
-
x._data if isinstance(x, abstract.
|
|
166
|
+
x._data if isinstance(x, abstract.Quantity)
|
|
166
167
|
else x for x in out
|
|
167
168
|
)
|
|
168
169
|
if self._implements(ufunc):
|
|
@@ -285,7 +286,7 @@ class Numpy:
|
|
|
285
286
|
types = self._get_numpy_types(types)
|
|
286
287
|
return array.__array_function__(func, types, args, kwargs)
|
|
287
288
|
|
|
288
|
-
def _get_numpy_array(self) ->
|
|
289
|
+
def _get_numpy_array(self) -> numpy.typing.NDArray | None:
|
|
289
290
|
"""Convert the data interface to an array for `numpy` mixin methods.
|
|
290
291
|
|
|
291
292
|
Notes
|
|
@@ -324,7 +325,7 @@ class Numpy:
|
|
|
324
325
|
`arg` if `arg` is an instance of the base object class; otherwise, it
|
|
325
326
|
will return the unmodified argument.
|
|
326
327
|
"""
|
|
327
|
-
if isinstance(arg, abstract.
|
|
328
|
+
if isinstance(arg, abstract.Quantity):
|
|
328
329
|
return arg._data
|
|
329
330
|
return arg
|
|
330
331
|
|
|
@@ -344,7 +345,7 @@ class Numpy:
|
|
|
344
345
|
)
|
|
345
346
|
|
|
346
347
|
@classmethod
|
|
347
|
-
def _implements(cls, operation:
|
|
348
|
+
def _implements(cls, operation: collections.abc.Callable):
|
|
348
349
|
"""True if this class defines a custom implementation for `operation`.
|
|
349
350
|
|
|
350
351
|
This is a helper methods that gracefully handles the case in which a
|
|
@@ -356,11 +357,11 @@ class Numpy:
|
|
|
356
357
|
return False
|
|
357
358
|
return result
|
|
358
359
|
|
|
359
|
-
_FUNCTIONS:
|
|
360
|
+
_FUNCTIONS: dict[str, collections.abc.Callable]=None
|
|
360
361
|
"""Internal collection of custom `numpy` function implementations."""
|
|
361
362
|
|
|
362
363
|
@classmethod
|
|
363
|
-
def implementation(cls, numpy_function:
|
|
364
|
+
def implementation(cls, numpy_function: collections.abc.Callable, /):
|
|
364
365
|
"""Register a custom implementation of this `numpy` function.
|
|
365
366
|
|
|
366
367
|
Parameters
|
|
@@ -424,7 +425,7 @@ class Numpy:
|
|
|
424
425
|
@classmethod
|
|
425
426
|
def implement(
|
|
426
427
|
cls,
|
|
427
|
-
numpy_function:
|
|
428
|
+
numpy_function: collections.abc.Callable,
|
|
428
429
|
user_function: UserFunction,
|
|
429
430
|
/,
|
|
430
431
|
) -> None:
|
oprattr/operators.py
CHANGED
|
@@ -2,14 +2,14 @@
|
|
|
2
2
|
A namespace for operators used by this package's `Object` class.
|
|
3
3
|
"""
|
|
4
4
|
|
|
5
|
+
import collections.abc
|
|
5
6
|
import builtins
|
|
6
7
|
import operator
|
|
7
|
-
import typing
|
|
8
8
|
|
|
9
9
|
|
|
10
10
|
class Operator:
|
|
11
11
|
"""Base class for enhanced operators."""
|
|
12
|
-
def __init__(self, __f:
|
|
12
|
+
def __init__(self, __f: collections.abc.Callable, operation: str):
|
|
13
13
|
self._f = __f
|
|
14
14
|
self._operation = operation
|
|
15
15
|
|
oprattr/typeface.py
ADDED
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Support for type annotations.
|
|
3
|
+
|
|
4
|
+
This module provides a single interface to type annotations, including those
|
|
5
|
+
that are not defined by the operative Python version and those that this package
|
|
6
|
+
prefers to use from future versions.
|
|
7
|
+
|
|
8
|
+
Examples
|
|
9
|
+
--------
|
|
10
|
+
* Suppose `BestType` is available in the `typing` module starting with Python
|
|
11
|
+
version 3.X and is available in the `typing_extensions` module for earlier
|
|
12
|
+
versions. If the user is running with Python version <3.X, this module will
|
|
13
|
+
import `BestType` from `typing_extensions`. Otherwise, it will import
|
|
14
|
+
`BestType` from `typing`.
|
|
15
|
+
* Support `UpdatedType` is available in the `typing` module for the user's
|
|
16
|
+
version of Python, but this package wishes to take advantage of updates since
|
|
17
|
+
that version. This module will automatically import the version from
|
|
18
|
+
`typing_extensions`.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import typing
|
|
22
|
+
import typing_extensions
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
__all__ = ()
|
|
26
|
+
|
|
27
|
+
EXTENDED = [
|
|
28
|
+
'Protocol',
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
def __getattr__(name: str) -> type:
|
|
32
|
+
"""Get a built-in type annotation."""
|
|
33
|
+
if name in EXTENDED:
|
|
34
|
+
return getattr(typing_extensions, name)
|
|
35
|
+
try:
|
|
36
|
+
attr = getattr(typing, name)
|
|
37
|
+
except AttributeError:
|
|
38
|
+
attr = getattr(typing_extensions, name)
|
|
39
|
+
return attr
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
|
oprattr/typeface.pyi
ADDED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: oprattr
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.3.0
|
|
4
4
|
Summary: Add your description here
|
|
5
5
|
Author-email: Matthew Young <myoung.space.science@gmail.com>
|
|
6
|
+
License-File: LICENSE
|
|
6
7
|
Requires-Python: >=3.10
|
|
8
|
+
Requires-Dist: numerical
|
|
7
9
|
Requires-Dist: numpy>=2.2.1
|
|
8
10
|
Requires-Dist: scipy>=1.15.0
|
|
9
11
|
Description-Content-Type: text/markdown
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
oprattr/__init__.py,sha256=eo0zjBDcrDG-Ymeqm-k6lfq18aqCLvgi9ipHNu7wkQg,5591
|
|
2
|
+
oprattr/_operations.py,sha256=GwoZjjs-rcX70SuNBAiu-ja9P5dBRAJ0NTfMLQWY6yY,5824
|
|
3
|
+
oprattr/abstract.py,sha256=I3AYc8F79IMgH2esaKSvCTFelV_jFxWRuvXDuTZ8E94,1407
|
|
4
|
+
oprattr/mixins.py,sha256=_qqhReZu9Ta83irVihUrhggcObEj4lyp-3_S9K2hEog,16875
|
|
5
|
+
oprattr/operators.py,sha256=0ix9xHYujJZoUp4mBy1Oar_z17nUlZ8EoKU9KqpaAe0,1172
|
|
6
|
+
oprattr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
+
oprattr/typeface.py,sha256=FPGAdTZUmS_jd56PcZ5tCcUE_rXNubINBpVMQLRenvg,1214
|
|
8
|
+
oprattr/typeface.pyi,sha256=6gVdlDXtwl6Qyv07JWuRhM78VTGzds0pJ2KZUAAGcXs,113
|
|
9
|
+
oprattr-0.3.0.dist-info/METADATA,sha256=a-xInHgyeHOBNhKU1tnnftszWZ8vLumwgeLCYA_Z6-Y,375
|
|
10
|
+
oprattr-0.3.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
11
|
+
oprattr-0.3.0.dist-info/licenses/LICENSE,sha256=m2oXG0JDq5RzaKTS57TvGyNq5cWcV4_nfmLZjzLdYTg,1513
|
|
12
|
+
oprattr-0.3.0.dist-info/RECORD,,
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
|
|
2
|
+
|
|
3
|
+
BSD 3-Clause License
|
|
4
|
+
|
|
5
|
+
Copyright (c) 2025, Matt Young
|
|
6
|
+
All rights reserved.
|
|
7
|
+
|
|
8
|
+
Redistribution and use in source and binary forms, with or without
|
|
9
|
+
modification, are permitted provided that the following conditions are met:
|
|
10
|
+
|
|
11
|
+
* Redistributions of source code must retain the above copyright notice, this
|
|
12
|
+
list of conditions and the following disclaimer.
|
|
13
|
+
|
|
14
|
+
* Redistributions in binary form must reproduce the above copyright notice,
|
|
15
|
+
this list of conditions and the following disclaimer in the documentation
|
|
16
|
+
and/or other materials provided with the distribution.
|
|
17
|
+
|
|
18
|
+
* Neither the name of the copyright holder nor the names of its
|
|
19
|
+
contributors may be used to endorse or promote products derived from
|
|
20
|
+
this software without specific prior written permission.
|
|
21
|
+
|
|
22
|
+
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
23
|
+
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
24
|
+
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
|
25
|
+
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
|
|
26
|
+
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
|
27
|
+
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
|
28
|
+
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
|
29
|
+
CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
|
30
|
+
OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
|
31
|
+
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
32
|
+
|
oprattr-0.2.0.dist-info/RECORD
DELETED
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
oprattr/__init__.py,sha256=RSJjoTQWRT-C_OYYKHKlzHVQgvnA7yM1aDTs1k4XtjM,5557
|
|
2
|
-
oprattr/_operations.py,sha256=DiWIXLaTFQfI_IKHB89DqEgDLgxzeWpyY1CrbxLtQqI,5831
|
|
3
|
-
oprattr/abstract.py,sha256=TzTt9GkQ5KZc5kqajdLnn8EcvxzMj3SALSI5iJrB6Vk,3182
|
|
4
|
-
oprattr/mixins.py,sha256=KLgCsqIbE3WglZ3psrdRGb-agmVwBEqrASIpkGkDL54,16807
|
|
5
|
-
oprattr/operators.py,sha256=skqQpIezGSDbsmB2h-UNnxG_7aDGT6PsnvUkondpwOg,1154
|
|
6
|
-
oprattr/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
7
|
-
oprattr-0.2.0.dist-info/METADATA,sha256=PwniUyhE28lVnnRoAcZCNAEgVF50AdxbqqND9Jdil_s,328
|
|
8
|
-
oprattr-0.2.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
9
|
-
oprattr-0.2.0.dist-info/RECORD,,
|
|
File without changes
|