Skip to content

Commit

Permalink
EncodableType alias is now recursive
Browse files Browse the repository at this point in the history
Closes #7
  • Loading branch information
sg495 committed Feb 5, 2023
1 parent f218427 commit db3a9c6
Show file tree
Hide file tree
Showing 8 changed files with 32 additions and 25 deletions.
11 changes: 5 additions & 6 deletions dag_cbor/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,12 @@
Python implementation of the `DAG-CBOR codec <https://ipld.io/specs/codecs/dag-cbor/spec/>`_ specification.
"""

__version__ = "0.2.3"
from __future__ import annotations # See https://peps.python.org/pep-0563/

from .encoding import encode
__version__ = "0.2.4"

from .encoding import encode, EncodableType
from .decoding import decode

# explicit re-exports
__all__ = [
"encode",
"decode"
]
__all__ = ["encode", "EncodableType", "decode"]
14 changes: 7 additions & 7 deletions dag_cbor/encoding.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
Encoding functions for DAG-CBOR codec.
"""

from __future__ import annotations # See https://peps.python.org/pep-0563/

from io import BufferedIOBase, BytesIO
import math
import struct
from typing import Any, Dict, List, Optional, overload, Union
from typing_validation import validate
from typing_validation import validate, validation_aliases

from multiformats import varint, multicodec, CID

Expand All @@ -17,12 +19,9 @@
Union of non-container Python types that can be encoded by this implementation of the DAG-CBOR codec.
"""

EncodableType = Union[FlatEncodableType, List[Any], Dict[str, Any]]
EncodableType = Union[FlatEncodableType, List["EncodableType"], Dict[str, "EncodableType"]]
"""
Union of Python types that can be encoded (at top level) by this implementation of the DAG-CBOR codec.
Because of limited support for recursive types (see `Mypy issue #731 <https://github.com/python/mypy/issues/731>`_),
the list items and dictionary values are not recursively typechecked.
Union of Python types that can be encoded by this implementation of the DAG-CBOR codec.
"""

_dag_cbor_multicodec = multicodec.get("dag-cbor")
Expand Down Expand Up @@ -85,7 +84,8 @@ def encode(data: EncodableType, stream: BufferedIOBase) -> int:
:raises ~dag_cbor.utils.DAGCBOREncodingError: if a key of a dictionary is not a string
"""
validate(data, EncodableType)
with validation_aliases(EncodableType=EncodableType):
validate(data, EncodableType)
validate(stream, Optional[BufferedIOBase])
validate(include_multicodec, bool)
if stream is None:
Expand Down
1 change: 1 addition & 0 deletions dag_cbor/random.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
"""
# pylint: disable = global-statement

from __future__ import annotations # See https://peps.python.org/pep-0563/

from contextlib import contextmanager
import math
Expand Down
2 changes: 2 additions & 0 deletions dag_cbor/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
of the corresponding UTF-8 bytestrings (according to DAG-CBOR specification)
"""

from __future__ import annotations # See https://peps.python.org/pep-0563/

from typing import Any, Dict
from typing_validation import validate

Expand Down
1 change: 1 addition & 0 deletions docs/api/dag_cbor.rst
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,6 @@ dag_cbor.__all__

The following members were explicitly reexported using ``__all__``:

- :py:obj:`typing.EncodableType`
- :py:func:`dag_cbor.decoding.decode`
- :py:func:`dag_cbor.encoding.encode`
4 changes: 2 additions & 2 deletions docs/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@
# built documents.
#
# The full version, including alpha/beta/rc tags.
release = "0.2.0"
release = "0.2.4"
# The short X.Y version.
version = "0.2.0"
version = "0.2.4"


# -- General configuration ---------------------------------------------------
Expand Down
22 changes: 13 additions & 9 deletions docs/getting-started.rst
Original file line number Diff line number Diff line change
Expand Up @@ -30,15 +30,6 @@ b'\xa2aa\x0cabfhello!'
The :mod:`~dag_cbor.random` module contains functions to generate random data compatible with DAG-CBOR encoding.
The :mod:`~dag_cbor.utils` module contains errors and utility functions.

Please note that :mod:`dag_cbor` internally imports `multiformats <https://github.com/hashberg-io/multiformats>`_: if you'd like to initialise multiformats
with a custom selection of multicodecs/multihashes, you should call ``multiformats_config.enable()`` **before** you import :mod:`dag_cbor` (see the `multiformats docs <https://multiformats.readthedocs.io/en/latest/getting-started.html>`_ for further details):

.. code-block:: python
import multiformats_config
multiformats_config.enable(codecs=["sha1", 0x29], bases=["base64url", "9"])
import dag_cbor # internally imports multiformats

The DAG-CBOR codec
------------------
Expand All @@ -61,3 +52,16 @@ The `DAG-CBOR codec <https://ipld.io/specs/codecs/dag-cbor/spec/>`_ is a restric
are not allowed.

Because the CBOR codec can encode/decode all data handled by the DAG-CBOR codec, we use an established CBOR implementation as the reference when testing, namely the `cbor2 <https://github.com/agronholm/cbor2>`_ package (with the exception of CID data, which is not natively handled by cbor2).


Multiformats Config
-------------------

Please note that :mod:`dag_cbor` internally imports `multiformats <https://github.com/hashberg-io/multiformats>`_: if you'd like to initialise multiformats
with a custom selection of multicodecs/multihashes, you should call ``multiformats_config.enable()`` **before** you import :mod:`dag_cbor` (see the `multiformats docs <https://multiformats.readthedocs.io/en/latest/getting-started.html>`_ for further details):

.. code-block:: python
import multiformats_config
multiformats_config.enable(codecs=["sha1", 0x29], bases=["base64url", "9"])
import dag_cbor # internally imports multiformats
2 changes: 1 addition & 1 deletion test_decode_error_messages.py
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,4 @@ def print_decode_error(test_case: str) -> bool:
print("==== Deep test cases ====")
print()
for idx, test_case in enumerate(deep_test_cases):
assert print_decode_error(test_case), f"Decoding of deep test case {idx} should have raised error."
assert print_decode_error(test_case), f"Decoding of deep test case {idx} should have raised error."

0 comments on commit db3a9c6

Please sign in to comment.