# Serox
_Rusty abstractions for Python_
`serox` provides a suite of commonly-used Rust abstractions in a manner that is near-fully
static-type-checker compliant, the exceptions being cases involving higher-kinded types (HKTs; e.g.
`Iterator.collect`) as these are not currently supported by Python's type system.
The subset of abstractions most broadly-applicable are importable from `serox.prelude`.
## Features
1. `Iterator` combinators that allow for the seamless chaining of operations over data with
[rayon]-inspired functionality for effortless parallelism.
2. A `Result` pseudo-`enum` comprising `Some` and `Null` pseudo-variants. We say 'pseudo' as the
Python analogue to Rust's tagged union is the union (`A | B`) type; since this type is not a data
structure, we cannot implement methods on it directly and instead have to resort to some
legerdemain.
3. An `Option` pseudo-`enum`. The `T | None` pattern is ubiquitous in Python yet, frustratingly, is
not treated as a first-class citizen within the language; `Option` is a drop-in replacement that
redresses this.
4. The `qmark` decorator emulates the '?' (error/null short-circuiting) operator, allowing for
propagation of error and null values without disrupting the control flow. Without this, one has
to resort to awkward pattern-matching to perform common operations such as `unwrap_or` (setting
`Null` to a default value) or `map` (applying a function to the contained value if `Some`).
## Example
Early exiting (in the fashion of Rust's `?` operator) an Option/Result-returning function is enabled
by the `qmark` ('question mark') decorator:
```python
from serox.prelude import *
@qmark
def some_function(value: Option[int]) -> Option[float]:
squared: int = value.map(lambda x: x ** 2).q
# The above expands to the rather verbose:
# match value:
# case Null():
# return Null[float]()
# case Some(x):
# squared = value ** 2
return Some(1.0 / squared)
```
## Requirements
Python version `>=3.12.3` is required for typing purposes.
## Installation
`serox` is available on PyPI and thus the latest version can be installed via `pip` with
```sh
pip install serox
```
or via [uv] with
```sh
uv add serox
```
## Acknowledgements
Credit to [result](https://github.com/rustedpy/result) and
[rustshed](https://github.com/pawelrubin/rustshed/) for laying the groundwork for the `Result` and
`qmark` implementations.
[rayon]: https://github.com/rayon-rs/rayon
[uv]: https://docs.astral.sh/uv/
Raw data
{
"_id": null,
"home_page": null,
"name": "serox",
"maintainer": null,
"docs_url": null,
"requires_python": ">=3.12",
"maintainer_email": null,
"keywords": "iterators, monads, option, protocols, python, result, rust, structural-typing, traits, types, typing",
"author": "Myles Bartlett",
"author_email": null,
"download_url": "https://files.pythonhosted.org/packages/bf/ec/c0ee8f2ef9f69a1781b95a6020f5b46b089e8582d5dee8c7a6d7ae47a525/serox-0.1.3.tar.gz",
"platform": null,
"description": "# Serox\n\n_Rusty abstractions for Python_\n\n`serox` provides a suite of commonly-used Rust abstractions in a manner that is near-fully\nstatic-type-checker compliant, the exceptions being cases involving higher-kinded types (HKTs; e.g.\n`Iterator.collect`) as these are not currently supported by Python's type system.\n\nThe subset of abstractions most broadly-applicable are importable from `serox.prelude`.\n\n## Features\n\n1. `Iterator` combinators that allow for the seamless chaining of operations over data with\n [rayon]-inspired functionality for effortless parallelism.\n2. A `Result` pseudo-`enum` comprising `Some` and `Null` pseudo-variants. We say 'pseudo' as the\n Python analogue to Rust's tagged union is the union (`A | B`) type; since this type is not a data\n structure, we cannot implement methods on it directly and instead have to resort to some\n legerdemain.\n\n3. An `Option` pseudo-`enum`. The `T | None` pattern is ubiquitous in Python yet, frustratingly, is\n not treated as a first-class citizen within the language; `Option` is a drop-in replacement that\n redresses this.\n\n4. The `qmark` decorator emulates the '?' (error/null short-circuiting) operator, allowing for\n propagation of error and null values without disrupting the control flow. Without this, one has\n to resort to awkward pattern-matching to perform common operations such as `unwrap_or` (setting\n `Null` to a default value) or `map` (applying a function to the contained value if `Some`).\n\n## Example\n\nEarly exiting (in the fashion of Rust's `?` operator) an Option/Result-returning function is enabled\nby the `qmark` ('question mark') decorator:\n\n```python\nfrom serox.prelude import *\n\n@qmark\ndef some_function(value: Option[int]) -> Option[float]:\n squared: int = value.map(lambda x: x ** 2).q\n # The above expands to the rather verbose:\n # match value:\n # case Null():\n # return Null[float]()\n # case Some(x):\n # squared = value ** 2\n\n return Some(1.0 / squared)\n```\n\n## Requirements\n\nPython version `>=3.12.3` is required for typing purposes.\n\n## Installation\n\n`serox` is available on PyPI and thus the latest version can be installed via `pip` with\n\n```sh\npip install serox\n```\n\nor via [uv] with\n\n```sh\nuv add serox\n```\n\n## Acknowledgements\n\nCredit to [result](https://github.com/rustedpy/result) and\n[rustshed](https://github.com/pawelrubin/rustshed/) for laying the groundwork for the `Result` and\n`qmark` implementations.\n\n[rayon]: https://github.com/rayon-rs/rayon\n[uv]: https://docs.astral.sh/uv/\n",
"bugtrack_url": null,
"license": "MIT",
"summary": "Serpentine Oxidation: Rusty abstractions for Python.",
"version": "0.1.3",
"project_urls": null,
"split_keywords": [
"iterators",
" monads",
" option",
" protocols",
" python",
" result",
" rust",
" structural-typing",
" traits",
" types",
" typing"
],
"urls": [
{
"comment_text": "",
"digests": {
"blake2b_256": "80ae808f4575a181c4a2ab2b58b3d552f04ace9eab8d596a907b4df0f3576616",
"md5": "da5769c0dd578f306fd024b2b3e7f5b5",
"sha256": "f77081b3d4d2580963d2d1521edab712d9bc0172d285f09664a86247ae1b3da3"
},
"downloads": -1,
"filename": "serox-0.1.3-py3-none-any.whl",
"has_sig": false,
"md5_digest": "da5769c0dd578f306fd024b2b3e7f5b5",
"packagetype": "bdist_wheel",
"python_version": "py3",
"requires_python": ">=3.12",
"size": 27268,
"upload_time": "2024-12-03T23:31:29",
"upload_time_iso_8601": "2024-12-03T23:31:29.075827Z",
"url": "https://files.pythonhosted.org/packages/80/ae/808f4575a181c4a2ab2b58b3d552f04ace9eab8d596a907b4df0f3576616/serox-0.1.3-py3-none-any.whl",
"yanked": false,
"yanked_reason": null
},
{
"comment_text": "",
"digests": {
"blake2b_256": "bfecc0ee8f2ef9f69a1781b95a6020f5b46b089e8582d5dee8c7a6d7ae47a525",
"md5": "29affa86fb63907f24ad4debe5091799",
"sha256": "7752217deada6b59fd3d95391219e87703a6fd813aeb460cbc7653566b9bda89"
},
"downloads": -1,
"filename": "serox-0.1.3.tar.gz",
"has_sig": false,
"md5_digest": "29affa86fb63907f24ad4debe5091799",
"packagetype": "sdist",
"python_version": "source",
"requires_python": ">=3.12",
"size": 44362,
"upload_time": "2024-12-03T23:31:31",
"upload_time_iso_8601": "2024-12-03T23:31:31.228606Z",
"url": "https://files.pythonhosted.org/packages/bf/ec/c0ee8f2ef9f69a1781b95a6020f5b46b089e8582d5dee8c7a6d7ae47a525/serox-0.1.3.tar.gz",
"yanked": false,
"yanked_reason": null
}
],
"upload_time": "2024-12-03 23:31:31",
"github": false,
"gitlab": false,
"bitbucket": false,
"codeberg": false,
"lcname": "serox"
}