rust-result


Namerust-result JSON
Version 0.2.1 PyPI version JSON
download
home_pageNone
SummaryNone
upload_time2024-09-23 09:43:33
maintainerNone
docs_urlNone
authorOle Kliemann
requires_python>=3.10
licenseMIT
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            # rust-result

More radical approach to Rust's `std::result` in Python.

## Motivation

I do not want exceptions in my code.
Rust has this figured out quite neatly
by essentially revolving around two pathways for errors:
A possible error condition is either one that has no prospect of being handled
-- then the program should terminate -- or it is one that could be handled --
then it has to be handled or explicitly ignored.

This concept is replicated here by using `AssertionError` to emulate Rust's `panic!`,
mapping all unhandled exceptions to `AssertionError`
and providing a Rust-like `result` type to signal error conditions that do not need to terminate
the program.

## Documentation

```python
from rust_result import Ok, Err, returns_result

@returns_result()
def read_file():
    with open('/this/path/is/invalid') as f:
        return Ok(f.read())

result = func()
```
This will raise an `AssertionError` due to an unhandled exception.

But if you specify the exceptions you expect, you can handle the error:
```python
@returns_result(FileNotFoundError)
def read_file():
    with open('/this/path/is/invalid') as f:
        return Ok(f.read())

result = func()
if result.is_ok():
    print(f'File content: {result.unwrap()}')
else:
    print(f'Error: {result.unwrap_err()}')
```

Or -- if you are feeling fancy -- you can do pattern matching:
```python
@returns_result(FileNotFoundError)
def read_file():
    with open('/this/path/is/invalid') as f:
        return f.read()

result = read_file()
match result:
    case Ok(v):
        print(f'File content: {v}')
    case Err(e):
        print(f'Error: {e}')
```

And even fancier:
```python
data = [
    { 'foo': 'value-1' },
    { 'bar': 'value-2' }
]

@returns_result(IndexError, KeyError)
def retrieve_record_entry_backend(index, key):
    return Ok(data[index][key])

def retrieve_record_entry(index, key):
    match retrieve_record_entry_backend(index, key):
        case Ok(v):
            print(f'Retrieved: {v}')
        case Err(IndexError()):
            print(f'No such record: {index}')
        case Err(KeyError()):
            print(f'No entry `{key}` in record {index}')

retrieve_record_entry(2, 'foo')    # No such record: 2
retrieve_record_entry(1, 'foo')    # No entry `foo` in record 1
retrieve_record_entry(1, 'bar')    # Retrieved: value-2
```

## Similar Projects

For a less extreme approach on Rust's result type, see:

* [https://github.com/rustedpy/result](https://github.com/rustedpy/result)
* [https://github.com/felixhammerl/resultify](https://github.com/felixhammerl/resultify)

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "rust-result",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.10",
    "maintainer_email": null,
    "keywords": null,
    "author": "Ole Kliemann",
    "author_email": "mail@olekliemann.de",
    "download_url": "https://files.pythonhosted.org/packages/2f/55/2593c81761ba46186bfa5828031a5e47eeb59a17492825f7ec10bc8ead0a/rust_result-0.2.1.tar.gz",
    "platform": null,
    "description": "# rust-result\n\nMore radical approach to Rust's `std::result` in Python.\n\n## Motivation\n\nI do not want exceptions in my code.\nRust has this figured out quite neatly\nby essentially revolving around two pathways for errors:\nA possible error condition is either one that has no prospect of being handled\n-- then the program should terminate -- or it is one that could be handled --\nthen it has to be handled or explicitly ignored.\n\nThis concept is replicated here by using `AssertionError` to emulate Rust's `panic!`,\nmapping all unhandled exceptions to `AssertionError`\nand providing a Rust-like `result` type to signal error conditions that do not need to terminate\nthe program.\n\n## Documentation\n\n```python\nfrom rust_result import Ok, Err, returns_result\n\n@returns_result()\ndef read_file():\n    with open('/this/path/is/invalid') as f:\n        return Ok(f.read())\n\nresult = func()\n```\nThis will raise an `AssertionError` due to an unhandled exception.\n\nBut if you specify the exceptions you expect, you can handle the error:\n```python\n@returns_result(FileNotFoundError)\ndef read_file():\n    with open('/this/path/is/invalid') as f:\n        return Ok(f.read())\n\nresult = func()\nif result.is_ok():\n    print(f'File content: {result.unwrap()}')\nelse:\n    print(f'Error: {result.unwrap_err()}')\n```\n\nOr -- if you are feeling fancy -- you can do pattern matching:\n```python\n@returns_result(FileNotFoundError)\ndef read_file():\n    with open('/this/path/is/invalid') as f:\n        return f.read()\n\nresult = read_file()\nmatch result:\n    case Ok(v):\n        print(f'File content: {v}')\n    case Err(e):\n        print(f'Error: {e}')\n```\n\nAnd even fancier:\n```python\ndata = [\n    { 'foo': 'value-1' },\n    { 'bar': 'value-2' }\n]\n\n@returns_result(IndexError, KeyError)\ndef retrieve_record_entry_backend(index, key):\n    return Ok(data[index][key])\n\ndef retrieve_record_entry(index, key):\n    match retrieve_record_entry_backend(index, key):\n        case Ok(v):\n            print(f'Retrieved: {v}')\n        case Err(IndexError()):\n            print(f'No such record: {index}')\n        case Err(KeyError()):\n            print(f'No entry `{key}` in record {index}')\n\nretrieve_record_entry(2, 'foo')    # No such record: 2\nretrieve_record_entry(1, 'foo')    # No entry `foo` in record 1\nretrieve_record_entry(1, 'bar')    # Retrieved: value-2\n```\n\n## Similar Projects\n\nFor a less extreme approach on Rust's result type, see:\n\n* [https://github.com/rustedpy/result](https://github.com/rustedpy/result)\n* [https://github.com/felixhammerl/resultify](https://github.com/felixhammerl/resultify)\n",
    "bugtrack_url": null,
    "license": "MIT",
    "summary": null,
    "version": "0.2.1",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "1430af630ee6f06c34b6b40b2966173dca8c011b09449e8adefe9c97ce2340a5",
                "md5": "d92fa215162a35a2202e83180cd21e10",
                "sha256": "0d428de9f54c0fe512631e150201b5165bf08f9128ca35c5de2c3ac96436c422"
            },
            "downloads": -1,
            "filename": "rust_result-0.2.1-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "d92fa215162a35a2202e83180cd21e10",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.10",
            "size": 3871,
            "upload_time": "2024-09-23T09:43:31",
            "upload_time_iso_8601": "2024-09-23T09:43:31.669182Z",
            "url": "https://files.pythonhosted.org/packages/14/30/af630ee6f06c34b6b40b2966173dca8c011b09449e8adefe9c97ce2340a5/rust_result-0.2.1-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "2f552593c81761ba46186bfa5828031a5e47eeb59a17492825f7ec10bc8ead0a",
                "md5": "091811736def8a96778db48ce81a8695",
                "sha256": "db91371538ae870a4d552ce59e6c3deba9110094ee8bcd6a46dce44464d1c11b"
            },
            "downloads": -1,
            "filename": "rust_result-0.2.1.tar.gz",
            "has_sig": false,
            "md5_digest": "091811736def8a96778db48ce81a8695",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.10",
            "size": 3200,
            "upload_time": "2024-09-23T09:43:33",
            "upload_time_iso_8601": "2024-09-23T09:43:33.373835Z",
            "url": "https://files.pythonhosted.org/packages/2f/55/2593c81761ba46186bfa5828031a5e47eeb59a17492825f7ec10bc8ead0a/rust_result-0.2.1.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2024-09-23 09:43:33",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "rust-result"
}
        
Elapsed time: 0.33292s