# -*- coding: utf-8 -*-
from setuptools import setup

packages = \
['thresult']

package_data = \
{'': ['*']}

setup_kwargs = {
    'name': 'thresult',
    'version': '0.9.6',
    'description': 'TangledHub Result',
    'long_description': "[![Build][build-image]]()\n[![Status][status-image]][pypi-project-url]\n[![Stable Version][stable-ver-image]][pypi-project-url]\n[![Coverage][coverage-image]]()\n[![Python][python-ver-image]][pypi-project-url]\n[![License][bsd3-image]][bsd3-url]\n\n\n# thresult\n\n## Overview\nTangledHub library for handling returned values from functions/methods and handling errors.\n\n## Licencing\nthresult is licensed under the BSD license. Check the [LICENSE](https://opensource.org/licenses/BSD-3-Clause) for details\n\n## Installation\n```bash\npip install thresult\n```\n\n## Testing\n```bash\ndocker-compose build thresult-test ; docker-compose run --rm thresult-test\n```\n\n## Building\n```bash\ndocker-compose build thresult-build ; docker-compose run --rm thresult-build\n```\n\n## Publish\n```bash\ndocker-compose build thresult-publish ; docker-compose run --rm -e PYPI_USERNAME=__token__ -e PYPI_PASSWORD=__SECRET__ thresult-publish\n```\n\n### Run examples from Docker\n```bash\ndocker run -it -v $PWD/examples:/code -v $PWD:/deps/thresult -e PYTHONPATH=/deps python:3.10 /bin/bash\ncd /code\npython -B traceback_0.py\npython -B traceback_1.py\npython -B traceback_2.py\npython -B traceback_3.py\n```\n\n\n## Usage\nthresult provides type system for handling values and exceptions in Python.\nExpressions can return value of type Result and variables can hold value of type Result.\nResult can be Ok or Err. Ok type has attribute v and Err type has attribute e.\nIf some expression doesn't rise exception, it will return Ok type where v attribute will be result of expression.\nIf error occurs, Err type will be returned, and e attribute of that type will contain error message.\nCustom types can be created, and they must extend Result, Ok or Err type.\n\nExample when returned value is Ok type\n```python\nfrom thresult import Result, Ok, Err\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\nr: Result = f(1.0, 20.0) # r is Ok[<class 'float'>] object\n```\n\nExample when returned value is Err type\n```python\nfrom thresult import Result, Ok, Err\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n\n    return res\n\n# divide with 0.0 will not rise exception,\n# object type Err[<class 'Exception'>] is returned\nr: Result = f(1.0, 0.0) # r is Err[<class 'Exception'>] object\n```\n\nTo obtain a value from Ok or Err type\n- structural pattern matching\n- unwrap()\n- unwrap_value()\n- unwrap_or(v: Any)\n\nThere are different ways to handle exceptions\n\nObtain a value from Ok or Err type \nwith structural pattern matching\n```python\nfrom thresult import Result, Ok, Err\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nr: Result = f(1.0, 0.0)\n\nmatch r:\n    case Ok(v):\n        print('Ok, value: ', v)\n    case Err(e):\n        print('Err, error: ', e) # float division by zero\n```\n\nUsing structural pattern matching to handle exceptions.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nmatch f(1.0, 0.0):\n    case Ok(v):\n        print('Ok, value: ', v)\n    case Err(e):\n        print('Err, error: ', e) # float division by zero\n```\n\nUsing *unwrap* to handle exceptions.\nIn case of error, exception is thrown.\n```python\nfrom thresult import Result, Ok, Err\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\nr: Result = f(1.0, 0.0)\nz: float = r.unwrap() # ZeroDivisionError: float division by zero\n```\n\nUsing *unwrap_value* to handle exceptions.\nIn case of error, unwrap_value returns error message and doesn't terminate program.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nr: Result = f(1.0, 0.0)\nv: str = r.unwrap_value()\n# v will contain error message, float division by zero\n```\n\nUsing *unwrap_or* to handle exceptions.\nIn case of error, unwrap_or returns value passed as argument and doesn't terminate program.\nIn this example it is 0.0.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nr: Result = f(1.0, 0.0)\nv: float = r.unwrap_or(0.0)\n# v will contain value 0.0\n```\n\nObtain a value from Ok type using structural pattern matching.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nr: Result = f(1.0, 10.0)\n\nmatch r:\n    case Ok(v):\n        # v holds value of division operation - 0.1\n        print('Ok, value: ', v)\n    case Err(e):\n        print('Err, error: ', e)\n```\n\nObtain a value from Ok type using structural pattern matching.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nmatch f(1.0, 10.0):\n    case Ok(v):\n        # v holds value of division operation - 0.1\n        print('Ok, value: ', v)\n    case Err(e):\n        print('Err, error: ', e) \n```\n\nObtain a value from Ok type using *unwrap* method on variable.\nVariable holds a value of Ok type.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nr: Result = f(1.0, 10.0)\nv: float = r.unwrap() # v is 0.1\n```\n\nObtain a value from Ok type using *unwrap* method on expression. \nExpression returns a value of Ok type.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nv: float = (f(1.0, 10.0)).unwrap() # v is 0.1\n```\n\n\nObtain a value from Ok type using *unwrap_value* method on variable.\nVariable holds a value of Ok type. If value is Ok type, *unwrap_value* has no effects, \nit is same as *unwrap* method.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n    \nr: Result = f(1.0, 10.0)\nv: float = r.unwrap_value() # v is 0.1\n```\n\nObtain a value from Ok type using *unwrap* method on expression. \nExpression returns a value of Ok type. If value is Ok type, *unwrap_value* has no effects, \nit is same as *unwrap* method.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nv: float = (f(1.0, 10.0)).unwrap_value() # v is 0.1\n```\n\nObtain a value from Ok type using *unwrap_or* method on variable.\nVariable holds a value of Ok type. If value is Ok type, *unwrap_or* has no effects, \nit is same as *unwrap* or *unwrap_value* method.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nr: Result = f(1.0, 10.0)\nv: float = r.unwrap_or(10.1) # v is 0.1\n```\n\nObtain a value from Ok type using *unwrap_or* method on expression.\nExpression returns a value of Ok type. If value is Ok type, *unwrap_or* has no effects, \nit is same as *unwrap* or *unwrap_value* method.\n```python\nfrom thresult import Result, Ok, Err\n\n\ndef f(a: float, b: float) -> Result[float, Exception]:\n    try:\n        r: float = a / b\n        res = Ok[float](r)\n    except Exception as e:\n        res = Err[Exception](e)\n    \n    return res\n\n\nv: float = (f(1.0, 10.0)).unwrap_or(10.1) # v is 0.1\n```\n\nthresult provides type checking\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass A:\n    pass\n\n    \na = A()\nat: Ok[A] = Ok[A](a) \nat: Ok[A] = Ok[A](4) # TypeError: Got <class 'int'> but expected <class 'A'>\n```\n\ncreate custom types by extending Ok and Err\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass AOk(Ok):\n    pass\n\n\nclass AErr(Err):\n    pass\n\n\nCustomResult: type = AOk[float] | AErr[str]\n\n\nr: CustomResult = AOk[int](5)\nv: int = r.unwrap_value() # v holds value of 5\n```\n\nUsing decorators to obtain Ok type\n```python\nfrom thresult import Result, Ok, Err\n\n\n@Result[float, str]\ndef f(n: float):\n    return 1/n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nf: float = v.unwrap() # 0.1\n```\n\nUsing decorators to obtain Err type\n```python\nfrom thresult import Result, Ok, Err\n\n\n@Result[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0)\nm: str = v.unwrap_value() # float division by zero\n```\n\nUsing decorators to obtain Ok \nCustom result type\n```python\nfrom thresult import Result, Ok, Err\n\n\n# custom result type\nCustomResult: type = Ok[float] | Err[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nf: float = v.unwrap() # 0.1\n```\n\nUsing decorators to obtain Ok \nCustom result type\nUsing unwrap_value\n```python\nfrom thresult import Result, Ok, Err\n\n\n# custom result type\nCustomResult: type = Ok[float] | Err[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nf: float = v.unwrap_value() # 0.1\n```\n\nUsing decorators to obtain Ok \nCustom result type\nUsing unwrap_or\n```python\nfrom thresult import Result, Ok, Err\n\n\n# custom result type\nCustomResult: type = Ok[float] | Err[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nf: float = v.unwrap_or(10.1) # 0.1\n```\n\nUsing decorators to obtain Err \nCustom result type\n```python\nfrom thresult import Result, Ok, Err\n\n\nCustomResult: type = Ok[float] | Err[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0) # Err[<class 'str'>]\n# panic: raising exception\nf: float = v.unwrap() # ZeroDivisionError: float division by zero\n```\n\nUsing decorators to obtain Err \nCustom result type\n```python\nfrom thresult import Result, Ok, Err\n\n\nCustomResult: type = Ok[float] | Err[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0) # Err[<class 'str'>]\n\n# doesn't panic, returns exception's message as string\nf: float = v.unwrap_value() # string value: float division by zero\n```\n\nUsing decorators to obtain Err. \nCustom result type\nUsing unwrap_or()\n```python\nfrom thresult import Result, Ok, Err\n\n\nCustomResult: type = Ok[float] | Err[str] \n\n\n@CustomResult[float, 'str']\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0) # Err[<class 'str'>]\n\n# doesn't panic, returns custom exception's message as string\nf: float = v.unwrap_or('Zero division: Custom message') # string value: Zero division: Custom message \n```\n\nUsing decorators to obtain Ok.\nCustom result type and custom Ok type\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\n```\n\nUsing decorators to obtain Ok.\nCustom result type and custom Ok type.\nObtain value with *unwrap*\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nr: float = v.unwrap() # 0.1\n```\n\nUsing decorators to obtain Ok.\nCustom result type and custom Ok type.\nObtain value with *unwrap_value*\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nr: float = v.unwrap_value() # 0.1\n```\n\nUsing decorators to obtain Ok.\nCustom result type and custom Ok type.\nObtain value with *unwrap_or*\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(10.0) # Ok[<class 'float'>]\nr: float = v.unwrap_or(10.1) # 0.1\n```\n\nUsing decorators to obtain Err.\nCustom result type and custom Err type\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\nv = f(0.0) # Err[<class 'str'>]\n```\n\nUsing decorators to obtain Err.\nCustom result type and custom Err type. \nHandling exceptions using *unwrap*\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0) # Err[<class 'str'>]\n\ntry:\n    v.unwrap()\nexcept ZeroDivisionError as e:\n    pass\n```\n\nUsing decorators to obtain Err.\nCustom result type and custom Err type.\nHandling exceptions using *unwrap_value*\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0) # Err[<class 'str'>]\nmessage: str = v.unwrap_value() # float division by zero\n```\n\nUsing decorators to obtain Err.\nCustom result type and custom Err type.\nHandling exceptions using *unwrap_or*\n```python\nfrom thresult import Result, Ok, Err\n\n\nclass CustomOk(Ok):\n    pass\n\n\nclass CustomErr(Err):\n    pass\n\n\nCustomResult: type = CustomOk[float] | CustomErr[str] \n\n\n@CustomResult[float, str]\ndef f(n: float):\n    return 1 / n\n\n\nv = f(0.0) # Err[<class 'str'>]\nmessage: str = v.unwrap_or('Custom message') # Custom message\n```\n\nUsing *wrap_result* decorator.\n*wrap_result* decorator can be used on non-asynchronous and asynchronous functions.\nThose functions will return Ok or Err type.\n\nUsing *wrap_result* on non-asynchronous functions which returns Ok type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\ndef f(n: float):\n    return 1.0 / n\n\nr: Result = f(2.1) # Ok object\n\n```\n\nUsing *unwrap*, *unwrap_value* and *unwrap_or* with *wrap_result* on \nnon-asynchronous functions which returns Ok type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\ndef f(n: float):\n    return 1.0 / n\n\n# handling exceptions when using unwrap\nv:float\ntry:\n    v = (f(2.0)).unwrap() # v is 0.5\nexcept ZeroDivisionError as e:\n    v = 0.0 \n\ns:str = (f(2.0)).unwrap_value() # s is 0.5\n\nr:float = (f(2.0)).unwrap_or('custom error message') # r is 0.5\n\no:float = (f(2.0)).unwrap_or(0.0) # o is 0.5\n\n```\n\nUsing *wrap_result* on non-asynchronous functions which returns Err type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\ndef f(n: float):\n    return 1.0 / n\n\nr: Result = f(0.0) # Err object\n\n```\n\nUsing *unwrap*, *unwrap_value* and *unwrap_or* with *wrap_result* on \nnon-asynchronous functions which returns Err type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\ndef f(n: float):\n    return 1.0 / n\n\n# handling exceptions when using unwrap\nv:float\ntry:\n    v = (f(0.0)).unwrap()\nexcept ZeroDivisionError as e:\n    v = 0.0 # v is 0.0\n\ns:str = (f(0.0)).unwrap_value() # s is float division by zero\n\nr:str = (f(0.0)).unwrap_or('custom error message') # r has value custom error message\n\no:float = (f(0.0)).unwrap_or(0.0) # o has value 0.0\n\n```\n\nUsing *wrap_result* on asynchronous functions which returns Ok type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\nasync def f(n: float):\n    return 1.0 / n\n\nr: Result = await f(2.1) # Ok object\n\n```\n\nUsing *unwrap*, *unwrap_value* and *unwrap_or* with *wrap_result* on \nasynchronous functions which returns Ok type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\nasync def f(n: float):\n    return 1.0 / n\n\n# handling exceptions when using unwrap\nv:float\ntry:\n    v = (await f(2.0)).unwrap() # v is 0.5\nexcept ZeroDivisionError as e:\n    v = 0.0 \n\ns:str = (await f(2.0)).unwrap_value() # s is 0.5\n\nr:float = (await f(2.0)).unwrap_or('custom error message') # r is 0.5\n\no:float = (await f(2.0)).unwrap_or(0.0) # o is 0.5\n\n```\n\nUsing *wrap_result* on asynchronous functions which returns Err type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\nasync def f(n: float):\n    return 1.0 / n\n\nr: Result = await f(0.0) # Err object\n\n```\n\nUsing *unwrap*, *unwrap_value* and *unwrap_or* with *wrap_result* on \nasynchronous functions which returns Err type.\n```python\nfrom thresult import Result, wrap_result\n\n@wrap_result(Result[int, Exception])\nasync def f(n: float):\n    return 1.0 / n\n\n# handling exceptions when using unwrap\nv:float\ntry:\n    v = (await f(0.0)).unwrap()\nexcept ZeroDivisionError as e:\n    v = 0.0 # v is 0.0\n\ns:str = (await f(0.0)).unwrap_value() # s is float division by zero\n\nr:str = (await f(0.0)).unwrap_or('custom error message') # r has value custom error message\n\no:float = (await f(0.0)).unwrap_or(0.0) # o has value 0.0\n\n```\n\n\n<!-- Links -->\n\n<!-- Badges -->\n[bsd3-image]: https://img.shields.io/badge/License-BSD_3--Clause-blue.svg\n[bsd3-url]: https://opensource.org/licenses/BSD-3-Clause\n[build-image]: https://img.shields.io/badge/build-success-brightgreen\n[coverage-image]: https://img.shields.io/badge/Coverage-100%25-green\n\n[pypi-project-url]: https://pypi.org/project/thresult/\n[stable-ver-image]: https://img.shields.io/pypi/v/thresult?label=stable\n[python-ver-image]: https://img.shields.io/pypi/pyversions/thresult.svg?logo=python&logoColor=FBE072\n[status-image]: https://img.shields.io/pypi/status/thresult.svg\n\n",
    'author': 'TangledHub',
    'author_email': 'info@tangledgroup.com',
    'maintainer': None,
    'maintainer_email': None,
    'url': 'https://gitlab.com/tangledlabs/thresult',
    'packages': packages,
    'package_data': package_data,
    'python_requires': '>=3.10,<4.0',
}


setup(**setup_kwargs)
