Skip to content

Commit

Permalink
improve documentation
Browse files Browse the repository at this point in the history
  • Loading branch information
hendrikboeck committed Jun 19, 2024
1 parent 608b517 commit c56d6e3
Show file tree
Hide file tree
Showing 26 changed files with 763 additions and 211 deletions.
2 changes: 1 addition & 1 deletion docs/source/apidocs/pkg_parasite/_root.rst
Original file line number Diff line number Diff line change
Expand Up @@ -9,4 +9,4 @@ Member Reference
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
:private-members: parasite._Namespace
3 changes: 1 addition & 2 deletions docs/source/apidocs/pkg_parasite/any.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ Member Reference
.. automodule:: parasite.any
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
:undoc-members:
3 changes: 1 addition & 2 deletions docs/source/apidocs/pkg_parasite/array.rst
Original file line number Diff line number Diff line change
Expand Up @@ -33,5 +33,4 @@ Member Reference
.. automodule:: parasite.array
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
:undoc-members:
3 changes: 1 addition & 2 deletions docs/source/apidocs/pkg_parasite/boolean.rst
Original file line number Diff line number Diff line change
Expand Up @@ -34,5 +34,4 @@ Member Reference
.. automodule:: parasite.boolean
:members:
:inherited-members:
:undoc-members:
:show-inheritance:
:undoc-members:
3 changes: 1 addition & 2 deletions docs/source/apidocs/pkg_parasite/errors.rst
Original file line number Diff line number Diff line change
Expand Up @@ -29,5 +29,4 @@ Member Reference
.. automodule:: parasite.errors
:members:
:undoc-members:
:inherited-members:
:show-inheritance:
:inherited-members:
1 change: 1 addition & 0 deletions docs/source/apidocs/pkg_parasite/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -21,3 +21,4 @@ Modules
boolean
never
object
variant
36 changes: 36 additions & 0 deletions docs/source/apidocs/pkg_parasite/variant.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
####################
``parasite.variant``
####################

Brief
=====

Reference for the ``variant`` submodule of the ``parasite`` package. This submodule
contains the :class:`Variant` class, which is a generic container for a union of various Python
objects.

Usage
=====

.. code-block:: python
from parasite import p
schema = p.variant([
p.string(),
p.number().integer(),
])
schema.parse("42") # -> "42"
schema.parse(42) # -> 42
...
Member Reference
================

.. automodule:: parasite.variant
:members:
:inherited-members:
:undoc-members:
:show-inheritance:

13 changes: 12 additions & 1 deletion docs/source/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
project = 'Parasite'
copyright = f'2024-{datetime.date.today().year}, Hendrik Boeck <hendrikboeck.dev@protonmail.com>'
author = 'Hendrik Boeck <hendrikboeck.dev@protonmail.com>'
release = 'v0.1.6'
release = 'v0.1.7'
html_title = f"{project} {release}"

# -- General configuration ---------------------------------------------------
Expand All @@ -24,12 +24,23 @@
"sphinx.ext.autodoc",
"sphinx.ext.viewcode",
"sphinx.ext.napoleon",
"sphinx.ext.inheritance_diagram",
"sphinx.ext.graphviz",
"sphinx.ext.intersphinx",
# 'sphinxcontrib.plantuml',
'qiskit_sphinx_theme',
]
# plantuml = "plantuml"

intersphinx_mapping = {
'python': ('https://docs.python.org/3', None),
'qiskit': ('https://qiskit.org/documentation/', None),
'rusttypes': ('https://hendrikboeck.github.io/rusttypes-py3/', None),
}
templates_path = ['_templates']
exclude_patterns = []

graphviz_output_format = 'svg'
pygments_style = "emacs"
pygments_dark_style = "one-dark"

Expand Down
2 changes: 1 addition & 1 deletion pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[tool.poetry]
name = "parasite"
version = "0.1.6"
version = "0.1.7"
description = "Data validation for Python 3"
authors = ["Hendrik Boeck <hendrikboeck.dev@protonmail.com>"]
packages = [{ include = "*", from = "src" }]
Expand Down
82 changes: 57 additions & 25 deletions src/parasite/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# -- STL Imports --
from abc import ABC as _Namespace
from typing import TypeAlias

# -- Package Imports --
Expand All @@ -14,31 +13,64 @@
from parasite.never import Never


class p(_Namespace):
class Namespace():
"""Abstract base class for all namespace implementations. This class tries to mimic the behavior
of a namespace in other programming languages.
Warning:
Do not instantiate this class directly. It is only meant to be used as a base class for
namespace implementations.
Inheritance:
.. inheritance-diagram:: parasite.Namespace
:parts: 1
"""

def __init__(self) -> None:
"""
Raises:
TypeError: Always, as this class is not meant to be instantiated.
"""
raise TypeError("cannot instantiate a namespace")


class p(Namespace):
"""
sudo-namespace for all parasite types. Makes it easier to import and call them. Tries to mimic
the behavior of the ``z`` object imported from ``zod`` library in JavaScript.
Example usage::
>>> from parasite import p
>>>
>>> schema = p.obj({
... "name": p.string().required(),
... "age": p.number().integer().min(0).optional(),
... }).strip()
>>>
>>> data = {
... "name": "John Doe",
... "age": 42,
... "extra": "This will be stripped",
... }
>>>
>>> schema.parse(data)
{'name': 'John Doe', 'age': 42}
>>>
>>> schema.parse({})
ValidationError: Missing required key: 'name'
sudo-namespace for all ``parasite`` types. Makes it easier to import and call them. Tries to
mimic the behavior of the ``z`` object imported from ``zod`` library in JavaScript.
Inheritance:
.. inheritance-diagram:: parasite.p
:parts: 1
Raises:
TypeError: Always, as this class is not meant to be instantiated.
Example usage:
Let's assume we have the following schema::
from parasite import p
schema = p.obj({
"name": p.string().required(),
"age": p.number().integer().min(0).optional(),
}).strip()
and the following data::
data = {
"name": "John Doe",
"age": 42,
"extra": "This will be stripped",
}
The schema will parse the following objects::
>>> schema.parse(data)
{ "name": "John Doe", "age": 42 }
>>> schema.parse({})
ValidationError: key "name" not found, but is required
"""
any: TypeAlias = Any_
null: TypeAlias = Null
Expand Down
68 changes: 49 additions & 19 deletions src/parasite/any.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@ class Any_(ParasiteType[Any]):
from parasite import p
schema = p.any()
...
Inheritance:
.. inheritance-diagram:: parasite.any.Any_
:parts: 1
"""
_f_optional: bool = False # Whether the value is optional

Expand All @@ -40,20 +44,31 @@ def optional(self) -> Any_:
Makes the value optional, when parsing with :func:`_find_and_parse`. Has no effect on
:func:`parse`. Inverse of :func:`required`.
Warning:
This function has no effect if the value is parsed as a standalone value.
Returns:
Any_: modified instance
Any_: The updated instance of the class.
Example usage::
Example usage:
Lets assume we have the following schemas::
from parasite import p
from parasite import p
schema = p.obj({ "name": p.any().optional() })
schema2 = p.obj({ "name": p.any() })
The resulting schemas will parse the following objects::
schema = p.obj({ "name": p.any() })
schema.parse({ "name": "John" }) # -> { "name": "John" }
schema.parse({ }) # -> ValidationError: key 'name' not found, but is required
>>> schema.parse({ "name": "John" })
{ "name": "John" }
>>> schema.parse({ })
{ }
schema = p.obj({ "name": p.any().optional() })
schema.parse({ "name": "John" }) # -> { "name": "John" }
schema.parse({ }) # -> { }
>>> schema2.parse({ "name": "John" })
{ "name": "John" }
>>> schema2.parse({ })
ValidationError: key 'name' not found, but is required
"""
self._f_optional = True
return self
Expand All @@ -63,20 +78,35 @@ def required(self) -> Any_:
Makes the value required, when parsing with :func:`_find_and_parse`. Has no effect on
:func:`parse`. Inverse of :func:`optional`. Default behavior.
Note:
This function is default behavior for the class and therefore only has an effect if the
function :func:`optional` may have been called before.
Warning:
This function has no effect if the value is parsed as a standalone value.
Returns:
Any_: modified instance
Any_: The updated instance of the class.
Example usage::
Example usage:
Lets assume we have the following schemas::
from parasite import p
from parasite import p
schema = p.obj({ "name": p.any().optional().required() })
schema2 = p.obj({ "name": p.any() })
The resulting schemas will parse the following objects::
schema = p.obj({ "name": p.any() })
schema.parse({ "name": "John" }) # -> { "name": "John" }
schema.parse({ }) # -> ValidationError: key 'name' not found, but is required
>>> schema.parse({ "name": "John" })
{ "name": "John" }
>>> schema.parse({ })
ValidationError: key 'name' not found, but is required
schema = p.obj({ "name": p.any().required() })
schema.parse({ "name": "John" }) # -> { "name": "John" }
schema.parse({ }) # -> ValidationError: key 'name' not found, but is required
>>> schema2.parse({ "name": "John" })
{ "name": "John" }
>>> schema2.parse({ })
ValidationError: key 'name' not found, but is required
"""
self._f_optional = False
return self
Expand All @@ -94,4 +124,4 @@ def _find_and_parse(self, parent: dict[K, Any], key: K) -> Option[Any]:
if self._f_optional:
return Nil

raise ValidationError(f"key '{key}' not found, but is required")
raise ValidationError(f"key {key!r} not found, but is required")
Loading

0 comments on commit c56d6e3

Please sign in to comment.