diff --git a/README.md b/README.md index d5da6ba2..fbed8164 100644 --- a/README.md +++ b/README.md @@ -108,7 +108,7 @@ So if you're a 10x developer that wants to hack Python's f-strings, but only if your type hints are spot-on; `optype` is you friend. | Type | Signature | Expression | -| -------------------------- | ------------------------------| -------------- | +| -------------------------- | ----------------------------- | -------------- | | `CanRepr[Y: str]` | `__repr__(self) -> T` | `repr(_)` | | `CanFormat[X: str, Y: str]`| `__format__(self, x: X) -> Y` | `format(_, x)` | @@ -139,22 +139,34 @@ be returned. CanGetattr[K: str, V] __getattr__(self, k: K) -> V - v = self.k or v = getattr(self, k) + + v = self.k or
+ v = getattr(self, k) + CanGetattribute[K: str, V] __getattribute__(self, k: K) -> V - v = self.k or v = getattr(self, k) + + v = self.k or
+ v = getattr(self, k) + CanSetattr[K: str, V] __setattr__(self, k: K, v: V) - self.k = v or setattr(self, k, v) + + self.k = v or
+ setattr(self, k, v) + CanDelattr[K: str] __delattr__(self, k: K) - del self.k or delattr(self, k) + + del self.k or
+ delattr(self, k) + CanDir[Vs: CanIter[Any]] @@ -199,7 +211,6 @@ from the abracadabra collections. This is how they are defined: ### Containers - | Type | Signature | Expression | | --------------------- | ---------------------------------- | -------------- | | `CanLen` | `__len__(self) -> int` | `len(self)` | @@ -211,7 +222,6 @@ from the abracadabra collections. This is how they are defined: | `CanReversed[Y]` [^4] | `__reversed__(self) -> Y` |`reversed(self)`| | `CanContains[K]` | `__contains__(self, k: K) -> bool` | `x in self` | - For indexing or locating container values, the following special methods are relevant: @@ -220,7 +230,6 @@ relevant: | `CanHash` | `__hash__(self) -> int` | `hash(self)` | | `CanIndex` | `__index__(self) -> int` | [docs](IX) | - [^4]: Although not strictly required, `Y@CanReversed` should be a `CanNext`. [LH]: https://docs.python.org/3/reference/datamodel.html#object.__length_hint__ [GM]: https://docs.python.org/3/reference/datamodel.html#object.__missing__ @@ -259,10 +268,6 @@ Interfaces for [descriptors](https://docs.python.org/3/howto/descriptor.html). - - -... - ### Callable objects @@ -356,23 +361,43 @@ Similarly, the augmented assignment operators are described by the following Additionally, there are the unary arithmetic operators: -| Type | Signature | Expression | -| ------------------- | ------------------------------- | ------------------ | -| `CanPos[Y]` | `__pos__(self) -> Y` | `+self` | -| `CanNeg[Y]` | `__neg__(self) -> Y` | `-self` | -| `CanInvert[Y]` | `__invert__(self) -> Y` | `~self` | -| `CanAbs[Y]` | `__abs__(self) -> Y` | `abs(self)` | +| Type | Signature | Expression | +| ------------------ | ----------------------------- | ----------------- | +| `CanPos[Y]` | `__pos__(self) -> Y` | `+self` | +| `CanNeg[Y]` | `__neg__(self) -> Y` | `-self` | +| `CanInvert[Y]` | `__invert__(self) -> Y` | `~self` | +| `CanAbs[Y]` | `__abs__(self) -> Y` | `abs(self)` | -The `round` function comes in two flavors: +The `round` function comes in two flavors, and their overloaded intersection: -| Type | Signature | Expression | -| ------------------ | ----------------------------- | --------------------- | -| `CanRound1[Y1]` | `__round__(self) -> Y1` | `round(self)` | -| `CanRound2[N, Y2]` | `__round__(self, n: N) -> Y2` | `round(self, n: N)` | + + + + + + + + + + + + + + + + + + + + + +
TypeSignatureExpression
CanRound1[Y1]__round__(self) -> Y1round(self)
CanRound2[N, Y2]__round__(self, n: N) -> Y2round(self, n)
CanRound[N, Y1, Y2] + __round__(self) -> Y1
+ __round__(self, n: N) -> Y2 +
round(self[, n: N])
+ +The last "double" signature denotes overloading. -For convenience, `optype` also provides their intersection type -`CanRound[N, Y1, Y2] =: CanRound1[Y1] & CanRound2[N, Y2]`, whose signature -overloads those of the `CanRound1` and `CanRound2`. To illustrate; `float` is a `CanRound[int, int, float]` and `int` a `CanRound[int, int, int]`. @@ -418,6 +443,12 @@ class CanWith[V, R](CanEnter[V], CanExit[R]): ``` +### Buffer types + + +... + + ### Async objects The `optype` variant of `collections.abc.Awaitable[V]`. The only difference @@ -441,7 +472,6 @@ But fret not, the `optype` alternatives are right here: | `CanAnext[V]` | `__anext__(self) -> V` | `anext(self)` | | `CanAiter[Vs: CanAnext]` | `__aiter__(self) -> Y` | `aiter(self)` | - But wait, shouldn't `V` be a `CanAwait`? Well, only if you don't want to get fired... Technically speaking, `__anext__` can return any type, and `anext` will pass @@ -467,9 +497,14 @@ type. ## Future plans -- Build a drop-in replacement for the `operator` standard library, with +- Support for Python versions before 3.12. +- A drop-in replacement for the `operator` standard library, with runtime-accessible type annotations, and more operators. - More standard library protocols, e.g. `copy`, `dataclasses`, `pickle`. +- Typed mixins for DRY implementation of operator, e.g. for comparison ops + `GeFromLt`, `GtFromLe`, etc as a typed alternative for + `functools.total_ordering`. Similarly for numeric types, with e.g. `__add__` + and `__neg__` a mixin could generate `__pos__` and `__sub__`, or with + `__mod__` and `__truediv__` a mixin could generate `__` - Dependency-free third-party type support, e.g. protocols for `numpy`'s array interface. -- Support for Python versions before 3.12.