Skip to content

Commit

Permalink
refactor documentation structure
Browse files Browse the repository at this point in the history
  • Loading branch information
zhPavel committed Dec 30, 2023
1 parent dccbfed commit 665df11
Show file tree
Hide file tree
Showing 64 changed files with 85 additions and 65 deletions.
File renamed without changes.
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@
# directories to ignore when looking for source files.
# This pattern also affects html_static_path and html_extra_path.
exclude_patterns = [
'changelog/fragments/*'
'changelog/*'
]


Expand All @@ -87,7 +87,7 @@
autodoc_member_order = 'bysource'

apidoc_module_dir = '../src/adaptix'
apidoc_output_dir = 'api_reference'
apidoc_output_dir = 'reference/api'
apidoc_separate_modules = True
# apidoc_toc_file = False
apidoc_extra_args = ['--maxdepth', '1']
Expand Down
File renamed without changes.
File renamed without changes.
Empty file.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
20 changes: 12 additions & 8 deletions docs/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,20 +6,24 @@ Adaptix
:caption: Contents:

overview
tutorial

extended_usage
specific_types_behavior
benchmarks

.. toctree::
:maxdepth: 2
:caption: Loading & Dumping:

loading-and-dumping/tutorial
loading-and-dumping/extended-usage
loading-and-dumping/specific-types-behavior

.. toctree::
:maxdepth: 2
:caption: Reference:

examples
API Reference <api_reference/modules>
changelog
contributing
reference/examples
API <reference/api/modules>
reference/changelog
reference/contributing

.. toctree::
:maxdepth: 2
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ Generic classes

Generic classes are supported out of the box.

.. literalinclude:: examples/extended_usage/generic_classes_simple.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/generic_classes_simple.py

If a generic class is not parametrized, Python specification requires to assume ``Any`` for each position.
Adaptix acts slightly differently,
Expand Down Expand Up @@ -38,7 +38,7 @@ Recursive data types

These types could be loaded and dumped without additional configuration.

.. literalinclude:: examples/extended_usage/recursive_data_types.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/recursive_data_types.py

But it does not work with cyclic-referenced objects like

Expand Down Expand Up @@ -71,7 +71,7 @@ Sometimes you have JSON with keys that leave much to be desired.
For example, they might be invalid Python identifiers or just have unclear meanings.
The simplest way to fix it is to use :paramref:`.name_mapping.map` to rename it.

.. literalinclude:: examples/extended_usage/field_renaming.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/field_renaming.py

The keys of ``map`` refers to the field name at model definition,
and values contain a new field name.
Expand All @@ -86,7 +86,7 @@ Name style
Sometimes JSON keys are quite normal but do fit PEP8 recommendations of variable naming.
You can rename each field individually, but library can automatically translate such names.

.. literalinclude:: examples/extended_usage/name_style.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/name_style.py

See :class:`.NameStyle` for a list of all available target styles.

Expand All @@ -101,11 +101,11 @@ Sometimes API uses reserved Python keywords therefore it can not be used as a fi
Usually, it is solved by adding a trailing underscore to the field name (e.g. ``from_`` or ``import_``).
Retort trims trailing underscore automatically.

.. literalinclude:: examples/extended_usage/stripping_underscore.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/stripping_underscore.py

If this behavior is unwanted, you can disable this feature by setting ``trim_trailing_underscore=False``

.. literalinclude:: examples/extended_usage/stripping_underscore_disable.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/stripping_underscore_disable.py

:paramref:`.name_mapping.map` is prioritized over :paramref:`.name_mapping.trim_trailing_underscore`.

Expand All @@ -117,30 +117,30 @@ Fields filtering
You can select which fields will be loaded or dumped.
Two parameters that can be used for these: :paramref:`.name_mapping.skip` and :paramref:`.name_mapping.only`

.. literalinclude:: examples/extended_usage/fields_filtering_skip.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/fields_filtering_skip.py

.. dropdown:: Traceback of raised error

.. literalinclude:: examples/extended_usage/fields_filtering_skip.pytb
.. literalinclude:: /examples/loading-and-dumping/extended_usage/fields_filtering_skip.pytb

Excluding the required field makes it impossible to create a loader, but the dumper will work properly.

.. dropdown:: Same example but with using ``only``

.. literalinclude:: examples/extended_usage/fields_filtering_only.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/fields_filtering_only.py

.. literalinclude:: examples/extended_usage/fields_filtering_only.pytb
.. literalinclude:: /examples/loading-and-dumping/extended_usage/fields_filtering_only.pytb


.. dropdown:: Skipping optional field

.. literalinclude:: examples/extended_usage/fields_filtering_skip_optional.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/fields_filtering_skip_optional.py
:lines: 2-

Both parameters take predicate or iterable of predicates, so you can use all features of :ref:`predicate-system`.
For example, you can filter fields based on their type.

.. literalinclude:: examples/extended_usage/fields_filtering_type.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/fields_filtering_type.py
:lines: 2-


Expand All @@ -151,12 +151,12 @@ If you have defaults for some fields, it could be unnecessary to store them in d
You can omit them when serializing a :paramref:`.name_mapping.omit_default` parameter.
Values that are equal to default, will be stripped from the resulting dict.

.. literalinclude:: examples/extended_usage/omit_default.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/omit_default.py

By default, ``omit_default`` is disabled, you can set it to ``True`` which will affect all fields.
Also, you can pass any predicate or iterable of predicate to apply the rule only to selected fields.

.. literalinclude:: examples/extended_usage/omit_default_selective.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/omit_default_selective.py


Unknown fields processing
Expand All @@ -172,28 +172,34 @@ On loading

Parameter :paramref:`.name_mapping.extra_in` controls policy how extra data is saved.

.. _on-loading-extra-skip:

:obj:`.ExtraSkip`
"""""""""""""""""""""""

Default behaviour. All extra data is ignored.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_loading_extra_skip.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_loading_extra_skip.py

.. _on-loading-extra-forbid:

:obj:`.ExtraForbid`
"""""""""""""""""""""""

This policy raises :class:`.load_error.ExtraFieldsError` in case of any unknown field is found.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_loading_extra_forbid.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_loading_extra_forbid.py

Order of fields inside :class:`.load_error.ExtraFieldsError` is not guaranteed and can be unstable between runs.

.. _on-loading-extra-kwargs:

:obj:`.ExtraKwargs`
"""""""""""""""""""""""

Extra data are passed as additional keyword arguments.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_loading_extra_kwargs.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_loading_extra_kwargs.py

This policy has significant flaws by design and, generally, should not be used.

Expand All @@ -203,19 +209,23 @@ specified type of ``**kwargs`` is ignored.
If an unknown field collides with the original field name,
``TypeError`` will be raised, treated as an unexpected error.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_loading_extra_kwargs_renaming.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_loading_extra_kwargs_renaming.py

The following strategy one has no such problems.

.. _on-loading-field-id:

Field id
""""""""""""""

You can pass the string with field name. Loader of corresponding field will receive mapping with unknown data.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_loading_field_id.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_loading_field_id.py

Also you can pass ``Iterable[str]``. Each field loader will receive same mapping of unknown data.

.. _on-loading-saturator-function:

Saturator function
""""""""""""""""""""""

Expand All @@ -225,46 +235,52 @@ You can pass a callable taking created model and mapping of unknown data named '
Precise type hint is ``Callable[[T, Mapping[str, Any]], None]``).
This callable can mutate the model to inject unknown data as you want.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_loading_saturator.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_loading_saturator.py

On dumping
^^^^^^^^^^^^^

Parameter :paramref:`.name_mapping.extra_in` controls policy how extra data is extracted.

.. _on-dumping-extra-skip:

:obj:`.ExtraSkip`
"""""""""""""""""""""""

Default behaviour. All extra data is ignored.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_dumping_extra_skip.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_dumping_extra_skip.py

You can skip ``extra`` from dumping. See :ref:`fields-filtering` for detail.

.. _on-dumping-field-id:

Field id
""""""""""""""

You can pass the string with field name.
Dumper of this field must return a mapping that will be merged with dict of dumped representation.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_dumping_field_id.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_dumping_field_id.py

Output mapping keys have not collide with keys of dumped model. Otherwise the result is not guaranteed.

You can pass several field ids (``Iterable[str]``). The output mapping will be merged.

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_dumping_several_field_id.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_dumping_several_field_id.py

Priority of output mapping is not guaranteed.

.. _on-dumping-extractor-function:

Extractor function
""""""""""""""""""""""

There is way to take out extra data from via custom function called 'extractor'.
A callable must taking model and produce mapping of extra fields.
Precise type hint is ``Callable[[T], Mapping[str, Any]]``).

.. literalinclude:: examples/extended_usage/unknown_fields_processing/on_dumping_extractor.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/unknown_fields_processing/on_dumping_extractor.py

Output mapping keys have not collide with keys of dumped model. Otherwise the result is not guaranteed.

Expand All @@ -278,18 +294,18 @@ For example, Binance uses it to represent
There is :paramref:`.name_mapping.as_list` that converts the model to a list.
Position at the list is determined by order of field definition.

.. literalinclude:: examples/extended_usage/mapping_to_list.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/mapping_to_list.py

You can override the order of fields using :paramref:`.name_mapping.map` parameter.

.. literalinclude:: examples/extended_usage/mapping_to_list_map.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/mapping_to_list_map.py

Also, you can map the model to list via :paramref:`.name_mapping.map` without using :paramref:`.name_mapping.as_list`,
if you assign every field to their position on the list.

.. dropdown:: Mapping to list using only ``map``

.. literalinclude:: examples/extended_usage/mapping_to_list_only_map.py
.. literalinclude:: /examples/loading-and-dumping/extended_usage/mapping_to_list_only_map.py


Structure flattening
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -167,20 +167,20 @@ and returns a value of the first loader that does not raise :class:`~.load_error
Therefore, for the correct operation of a union loader,
there must be no value that would be accepted by several union case loaders.

.. literalinclude:: examples/specific_types_behavior/union_case_overlapping.py
.. literalinclude:: /examples/loading-and-dumping/specific_types_behavior/union_case_overlapping.py

The return value in this example is undefined, it can be either a Cat instance or a Dog instance.
This problem could be solved if the model will contain a designator (tag) that can uniquely determine the type.

.. literalinclude:: examples/specific_types_behavior/union_with_designator.py
.. literalinclude:: /examples/loading-and-dumping/specific_types_behavior/union_with_designator.py

This example shows how to add a type designator to the model.
Be careful, this example does not work if :paramref:`.name_mapping.omit_default` is applied to tag field.

Be careful if one model is a superset of another model.
By default, all unknown fields are skipped, this does not allow distinct such models.

.. literalinclude:: examples/specific_types_behavior/union_model_supersets.py
.. literalinclude:: /examples/loading-and-dumping/specific_types_behavior/union_model_supersets.py

This can be avoided by inserting a type designator like in the example above.
Processing of unknown fields could be customized via :paramref:`.name_mapping.extra_in`.
Expand Down
Loading

0 comments on commit 665df11

Please sign in to comment.