optionz 0.1.0__tar.gz

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.
@@ -0,0 +1,35 @@
1
+ # $schema=https://www.schemastore.org/github-workflow.json
2
+ on:
3
+ release:
4
+ types:
5
+ - created
6
+ push:
7
+ tags:
8
+ - "v*.*.*"
9
+
10
+ name: release
11
+
12
+ jobs:
13
+ pypi-publish:
14
+ name: upload release to PyPI
15
+ runs-on: ubuntu-latest
16
+ environment: pypi
17
+ permissions:
18
+ id-token: write
19
+ steps:
20
+ - name: Checkout code
21
+ uses: actions/checkout@v4
22
+
23
+ - name: Install uv
24
+ uses: astral-sh/setup-uv@v3
25
+ with:
26
+ enable-cache: true
27
+
28
+ - name: Set up Python
29
+ run: uv python install
30
+
31
+ - name: Build package distributions
32
+ run: uv build
33
+
34
+ - name: Publish to PyPI
35
+ run: uv publish
@@ -0,0 +1,11 @@
1
+ # Python-generated files
2
+ __pycache__/
3
+ *.py[oc]
4
+ build/
5
+ docs/build/
6
+ dist/
7
+ wheels/
8
+ *.egg-info
9
+
10
+ # Virtual environments
11
+ .venv
@@ -0,0 +1 @@
1
+ 3.13
optionz-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026, Fábio Macêdo Mendes
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
optionz-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,83 @@
1
+ Metadata-Version: 2.4
2
+ Name: optionz
3
+ Version: 0.1.0
4
+ Summary: Some utility functions for Optional values.
5
+ Project-URL: Homepage, http://github.com/fabiomacedomendes/optionz
6
+ Project-URL: Repository, http://github.com/fabiomacedomendes/optionz
7
+ Author-email: Fábio Macêdo Mendes <fabiomacedomendes@gmail.com>
8
+ Maintainer-email: Fábio Macêdo Mendes <fabiomacedomendes@gmail.com>
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3 :: Only
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Programming Language :: Python :: 3.14
18
+ Classifier: Topic :: Utilities
19
+ Requires-Python: >=3.13
20
+ Description-Content-Type: text/markdown
21
+
22
+ # Optionz
23
+
24
+ A nullable type is needed when there can be an absence of a value. Python uses
25
+ `None` to represent the empty value and `Optional[T]`, i.e., `T | None` to
26
+ represent a nullable `T`. The other option is to use exceptions, but they are
27
+ not expressed as values in the type system, which can be brittle and error-prone.
28
+
29
+ Python approach is a compromise between the "million dollar mistake",
30
+ in which `null` is a valid member of every type and the more structured
31
+ `Maybe[T]`, that models nullables as a tagged union of `Just[T]` and `Nothing`.
32
+
33
+ This library provides some utility functions for working with `Optional` values
34
+ in a more functional style, inspired by the `Maybe` monad in Haskell and Rust's
35
+ equivalent `Option` type.
36
+
37
+ The main philosophy is that we *do not* want to introduce a new type like
38
+ [returns](https://returns.readthedocs.io/) and other similar libraries.
39
+ Instead, we want to provide a similar functionality using plain `Optional` values
40
+ so that your code can adopt it incrementally without feeling like an alien in
41
+ the Python ecosystem.
42
+
43
+ As much as I like functional programming and the `Maybe` monad, I think Python's
44
+ approach is fine and offers most of the same static guarantees. The crucial
45
+ difference is that `Maybe` is a **tagged union** of two types and Python's
46
+ `Optional` is a **union of sets**. They behave mostly the same, but the latter do
47
+ not allow nesting: `Optional[Optional[T]]` flattens to `Optional[T]`, while
48
+ `Maybe[Maybe[T]]` is a whole new type. This is a difference that rarely
49
+ matters in practice, and I don't any anyone is clearly superior to the other.
50
+
51
+
52
+ ## Installation
53
+
54
+ Install Optionz using pip/uv/poetry whatever you like. For example:
55
+
56
+ ```bash
57
+ pip install optionz
58
+ ```
59
+
60
+ Optionz consists of a single file, so you can also just copy `opt.py` to your
61
+ project and import it from there. It do not define any new type so there is
62
+ no conflict with code that import vs ones that vendorize it.
63
+
64
+
65
+ ## Usage
66
+
67
+ Import `opt` and use the functions as needed.
68
+
69
+ ```python
70
+ import opt
71
+
72
+ opt.unwrap(42) # 42
73
+ opt.unwrap(None) # raises ValueError
74
+ ```
75
+
76
+ ## Documentation
77
+
78
+ The documentation is available at https://optionz.rtfd.io/ and includes more
79
+ examples and explanations of the functions provided by the library.
80
+
81
+ ## License
82
+
83
+ Optionz is licensed under the MIT License. See [LICENSE](LICENSE) for more details.
@@ -0,0 +1,62 @@
1
+ # Optionz
2
+
3
+ A nullable type is needed when there can be an absence of a value. Python uses
4
+ `None` to represent the empty value and `Optional[T]`, i.e., `T | None` to
5
+ represent a nullable `T`. The other option is to use exceptions, but they are
6
+ not expressed as values in the type system, which can be brittle and error-prone.
7
+
8
+ Python approach is a compromise between the "million dollar mistake",
9
+ in which `null` is a valid member of every type and the more structured
10
+ `Maybe[T]`, that models nullables as a tagged union of `Just[T]` and `Nothing`.
11
+
12
+ This library provides some utility functions for working with `Optional` values
13
+ in a more functional style, inspired by the `Maybe` monad in Haskell and Rust's
14
+ equivalent `Option` type.
15
+
16
+ The main philosophy is that we *do not* want to introduce a new type like
17
+ [returns](https://returns.readthedocs.io/) and other similar libraries.
18
+ Instead, we want to provide a similar functionality using plain `Optional` values
19
+ so that your code can adopt it incrementally without feeling like an alien in
20
+ the Python ecosystem.
21
+
22
+ As much as I like functional programming and the `Maybe` monad, I think Python's
23
+ approach is fine and offers most of the same static guarantees. The crucial
24
+ difference is that `Maybe` is a **tagged union** of two types and Python's
25
+ `Optional` is a **union of sets**. They behave mostly the same, but the latter do
26
+ not allow nesting: `Optional[Optional[T]]` flattens to `Optional[T]`, while
27
+ `Maybe[Maybe[T]]` is a whole new type. This is a difference that rarely
28
+ matters in practice, and I don't any anyone is clearly superior to the other.
29
+
30
+
31
+ ## Installation
32
+
33
+ Install Optionz using pip/uv/poetry whatever you like. For example:
34
+
35
+ ```bash
36
+ pip install optionz
37
+ ```
38
+
39
+ Optionz consists of a single file, so you can also just copy `opt.py` to your
40
+ project and import it from there. It do not define any new type so there is
41
+ no conflict with code that import vs ones that vendorize it.
42
+
43
+
44
+ ## Usage
45
+
46
+ Import `opt` and use the functions as needed.
47
+
48
+ ```python
49
+ import opt
50
+
51
+ opt.unwrap(42) # 42
52
+ opt.unwrap(None) # raises ValueError
53
+ ```
54
+
55
+ ## Documentation
56
+
57
+ The documentation is available at https://optionz.rtfd.io/ and includes more
58
+ examples and explanations of the functions provided by the library.
59
+
60
+ ## License
61
+
62
+ Optionz is licensed under the MIT License. See [LICENSE](LICENSE) for more details.
@@ -0,0 +1,20 @@
1
+ # Minimal makefile for Sphinx documentation
2
+ #
3
+
4
+ # You can set these variables from the command line, and also
5
+ # from the environment for the first two.
6
+ SPHINXOPTS ?=
7
+ SPHINXBUILD ?= uv run sphinx-build
8
+ SOURCEDIR = source
9
+ BUILDDIR = build
10
+
11
+ # Put it first so that "make" without argument is like "make help".
12
+ help:
13
+ @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
14
+
15
+ .PHONY: help Makefile
16
+
17
+ # Catch-all target: route all unknown targets to Sphinx using the new
18
+ # "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS).
19
+ %: Makefile
20
+ @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O)
@@ -0,0 +1,35 @@
1
+ @ECHO OFF
2
+
3
+ pushd %~dp0
4
+
5
+ REM Command file for Sphinx documentation
6
+
7
+ if "%SPHINXBUILD%" == "" (
8
+ set SPHINXBUILD=sphinx-build
9
+ )
10
+ set SOURCEDIR=source
11
+ set BUILDDIR=build
12
+
13
+ %SPHINXBUILD% >NUL 2>NUL
14
+ if errorlevel 9009 (
15
+ echo.
16
+ echo.The 'sphinx-build' command was not found. Make sure you have Sphinx
17
+ echo.installed, then set the SPHINXBUILD environment variable to point
18
+ echo.to the full path of the 'sphinx-build' executable. Alternatively you
19
+ echo.may add the Sphinx directory to PATH.
20
+ echo.
21
+ echo.If you don't have Sphinx installed, grab it from
22
+ echo.https://www.sphinx-doc.org/
23
+ exit /b 1
24
+ )
25
+
26
+ if "%1" == "" goto help
27
+
28
+ %SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
29
+ goto end
30
+
31
+ :help
32
+ %SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%
33
+
34
+ :end
35
+ popd
@@ -0,0 +1,40 @@
1
+ API Reference
2
+ =============
3
+
4
+ .. warning::
5
+
6
+ Sphinx autodoc is used to generate this documentation. It does not do a
7
+ particularly good job at rendering type annotations, so trust your API
8
+ or the code itself over the documentation shown here.
9
+
10
+ All functions are fully typed and the type annotations are mostly correct.
11
+
12
+ Unwrapping options
13
+ ------------------
14
+
15
+ .. autofunction:: opt.unwrap
16
+ .. autofunction:: opt.unwrap_or
17
+ .. autofunction:: opt.unwrap_or_else
18
+ .. autofunction:: opt.expect
19
+
20
+
21
+ Mapping over options
22
+ --------------------
23
+
24
+ .. autofunction:: opt.map
25
+ .. autofunction:: opt.call
26
+
27
+
28
+ Zipping and combining options
29
+ -----------------------------
30
+
31
+ .. autofunction:: opt.zip
32
+ .. autofunction:: opt.together
33
+
34
+
35
+ Iterating over options
36
+ ----------------------
37
+
38
+ .. autofunction:: opt.iter
39
+ .. autofunction:: opt.elements
40
+ .. autofunction:: opt.values
@@ -0,0 +1,37 @@
1
+ # Configuration file for the Sphinx documentation builder.
2
+ #
3
+ # For the full list of built-in configuration values, see the documentation:
4
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html
5
+
6
+ # -- Project information -----------------------------------------------------
7
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
8
+
9
+ project = "optionz"
10
+ copyright = "2026, Fábio Macêdo Mendes"
11
+ author = "Fábio Macêdo Mendes"
12
+ release = "0.1.0"
13
+
14
+ # -- General configuration ---------------------------------------------------
15
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#general-configuration
16
+
17
+ extensions = [
18
+ "sphinx_mdinclude",
19
+ "sphinx.ext.autodoc",
20
+ "sphinx.ext.napoleon",
21
+ "sphinx_autodoc_typehints",
22
+ ]
23
+
24
+ autodoc_typehints = "none"
25
+ napoleon_google_docstring = True
26
+ napoleon_numpy_docstring = False
27
+ typehints_document_overloads = False
28
+
29
+ templates_path = ["_templates"]
30
+ exclude_patterns = [] # type: ignore
31
+ source_suffix = [".rst", ".md"]
32
+
33
+ # -- Options for HTML output -------------------------------------------------
34
+ # https://www.sphinx-doc.org/en/master/usage/configuration.html#options-for-html-output
35
+
36
+ html_theme = "alabaster"
37
+ html_static_path = ["_static"]
@@ -0,0 +1,59 @@
1
+ Development
2
+ ===========
3
+
4
+ Local setup
5
+ -----------
6
+
7
+ You must have `uv` installed and everything else follows seamlessly. From project root:
8
+
9
+ .. code-block:: bash
10
+
11
+ uv sync --group dev
12
+
13
+
14
+ Pull requests and contributing
15
+ ------------------------------
16
+
17
+ This library is simple enough that you can vendorize and implement your own
18
+ changes to it. If you want to contribute, please open a pull request with your
19
+ changes and we can discuss them there.
20
+
21
+ We have a strict **NO CODING AGENT** policy. If it looks like you are Claude
22
+ or any other agent, we will ignore your PR.
23
+
24
+
25
+ Routine tasks and commands
26
+ --------------------------
27
+
28
+ We use `uv` + `taskipy` to define and run common tasks.
29
+
30
+ **Build documentation**
31
+
32
+ .. code-block:: bash
33
+
34
+ uv run task docs
35
+
36
+ **Run tests**
37
+
38
+ .. code-block:: bash
39
+
40
+ uv run task test
41
+
42
+ **Linter**
43
+
44
+ .. code-block:: bash
45
+
46
+ uv run task lint
47
+
48
+ **Build the package**
49
+
50
+ .. code-block:: bash
51
+
52
+ uv run task build
53
+
54
+ **List tasks**
55
+
56
+ .. code-block:: bash
57
+
58
+ uv run task -l
59
+
@@ -0,0 +1,21 @@
1
+ .. optionz documentation master file, created by
2
+ sphinx-quickstart on Sat Jun 13 14:26:03 2026.
3
+ You can adapt this file completely to your liking, but it should at least
4
+ contain the root `toctree` directive.
5
+
6
+ Optionz documentation
7
+ =====================
8
+
9
+ .. toctree::
10
+ :maxdepth: 1
11
+ :caption: Contents:
12
+
13
+ api
14
+ development
15
+
16
+
17
+ Introduction
18
+ ------------
19
+
20
+ .. mdinclude:: ../../README.md
21
+ :start-line: 2