Security News
Introducing the Socket Python SDK
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Code generators for immutable structured data, including algebraic data types, and functions to destructure them.
Code generators for immutable structured data, including algebraic data types, and functions to destructure them.
Structured Data provides three public modules: structured_data.adt
, structured_data.match
, and structured_data.data
.
The adt
module provides base classes and an annotation type for converting a class into algebraic data types.
The match
module provides a Pattern
class that can be used to build match structures, and a Matchable
class that wraps a value, and attempts to apply match structures to it.
If the match succeeds, the bindings can be extracted and used.
It includes some special support for adt
subclasses.
The match architecture allows you tell pull values out of a nested structure:
.. code-block:: python3
structure = (match.pat.a, match.pat.b[match.pat.c, match.pat.d], 5)
my_value = (('abc', 'xyz'), ('def', 'ghi'), 5)
matchable = match.Matchable(my_value)
if matchable(structure):
# The format of the matches is not final.
print(matchable['a']) # ('abc', 'xyz')
print(matchable['b']) # ('def', 'ghi')
print(matchable['c']) # 'def'
print(matchable['d']) # 'ghi'
The subscript operator allows binding both the outside and the inside of a structure.
Indexing a Matchable
is forwarded to a matches
attribute, which is None
if the last match was not successful, and otherwise contains an instance of a custom mapping type, which allows building the matched values back up into simple structures.
The Sum
base class exists to create classes that do not necessarily have a single fixed format, but do have a fixed set of possible formats.
This lowers the maintenance burden of writing functions that operate on values of a Sum
class, because the full list of cases to handle is directly in the class definition.
Here are implementations of common algebraic data types in other languages:
.. code-block:: python3
class Maybe(adt.Sum, typing.Generic[T]):
Just: adt.Ctor[T]
Nothing: adt.Ctor
class Either(adt.Sum, typing.Generic[E, R]):
Left: adt.Ctor[E]
Right: adt.Ctor[R]
The data
module provides classes based on these examples.
Currently, this project has somewhat high quality metrics, though some of them have been higher. I am highly skeptical of this, because I've repeatedly given in to the temptation to code to the metrics. I can't trust the metrics, and I know the code well enough that I can't trust my own judgment to figure out which bits need to be improved and how. I need someone to review the code and identify problem spots based on what doesn't make sense to them. The issues are open.
Until there's a major version out, probably not.
There are several alternatives in the standard library that may be better suited to particular use-cases:
namedtuple
factory creates tuple classes with a single structure; the typing.NamedTuple
class offers the ability to include type information. The interface is slightly awkward, and the values expose their tuple-nature easily. (NOTE: In Python 3.8, the fast access to namedtuple members means that they bypass user-defined __getitem__
methods, thereby allowing factory consumers to customize indexing without breaking attribute access. It looks like it does still rely on iteration behavior for various convenience methods.)enum
module provides base classes to create finite enumerations. Unlike NamedTuple, the ability to convert values into an underlying type must be opted into in the class definition.dataclasses
module provides a class decorator that converts a class into one with a single structure, similar to a namedtuple, but with more customization: instances are mutable by default, and it's possible to generate implementations of common protocols.adt
decorator is inspired by the design of dataclasses
. (A previous attempt used metaclasses inspired by the enum
module, and was a nightmare.) Unlike enum
, it doesn't require all instances to be defined up front; instead each class defines constructors using a sequence of types, which ultimately determines the number of arguments the constructor takes. Unlike namedtuple
and dataclasses
, it allows instances to have multiple shapes with their own type signatures. Unlike using regular classes, the set of shapes is specified up front.dataclasses
.::
pip install structured-data
https://python-structured-data.readthedocs.io/
To run the all tests run::
tox
Added
- ``match.function`` and ``match.Property`` decorators for Haskell-style function definitions.
Fixed
Sum
and Product
instances.Added
- Product classes can make use of custom ``__new__``.
0.12.0 (2019-09-03)
-------------------
Added
Changed
- Improved documentation of some match constructors.
- Exposed ``MatchDict`` type, so it gets documented.
- Converted the ``adt`` decorator to a ``Sum`` base class.
Removed
Guard
type removed in favor of user-defined validation functions.Changed
- Restore proper behavior of ``__new__`` overrides.
0.11.0 (2019-03-23)
-------------------
Changed
Added
- A non-ergonomic but simple wrapper class for use by the typing plugin. It's not available to runtime code.
0.10.0 (2019-03-21)
-------------------
Changed
Changed
- Removed the facade.
- Added stability guarantee to Ctor.
0.8.0 (2019-03-19)
------------------
Changed
Changed
- Tried to put up a facade for type analysis. It didn't work.
0.6.1 (2019-03-18)
------------------
Added
~~~~~
- ``Bind`` class for attaching extra data to a match structure.
- PEP 561 support.
Changed
@
operator.AttrPattern
and DictPattern
now take keyword arguments instead of a dict
argument, and form new versions of themselves with an alter
method.DictPattern
back, stop trying to keep these things in synch.Added
- ``AttrPattern`` and ``DictPattern`` classes that take a ``dict`` argument and perform destructuring match against arbitrary objects, and mappings, respectively.
Changed
Added
- ``Matchable`` class is now callable and indexable. Calling is forwarded to the ``match`` method, and indexing forwards to the ``matches`` attribute, if it exists, and raises an error otherwise.
- ``Matchable`` class now has custom coercion to bool: ``False`` if the last match attempt failed, ``True`` otherwise.
Changed
enum
to adt
to avoid confusion.ValueMatcher
to Matchable
.Matchable.match
now returns the Matchable
instance, which can then be coerced to bool
, or indexed directly.Added
- Mapping class especially for match values. It's capable of quickly and concisely pulling out groups of variables, but it also properly supports extracting just a single value.
- Mapping class can now index from a ``dict`` to a ``dict``, in order to support ``**kwargs`` unpacking.
Fixed
Removed
- Unpublished the ``MatchFailure`` exception type, and the ``desugar`` function.
0.3.0 (2018-07-15)
------------------
Added
~~~~~
- Simpler way to create match bindings.
- Dependency on the ``astor`` library.
- First attempt at populating the annotations and signature of the generated constructors.
- ``data`` module containing some generic algebraic data types.
- Attempts at monad implementations for ``data`` classes.
Changed
WeakKeyDictionary
instead.object
semantics, rather than failing comparison and hashing with a TypeError
.NotImplemented
.Removed
- Ctor metaclass.
0.2.1 (2018-07-13)
------------------
Fixed
~~~~~
- Removed an incorrect classifier. This code cannot run on pypy.
0.2.0 (2018-07-13)
------------------
Added
~~~~~
- Explicit ``__bool__`` implementation, to consider all constructor instances as truthy, unless defined otherwise.
- Python 3.7 support.
Changed
EnumConstructor
-> _EnumConstructor
)Removed
- Support for Python 3.6 and earlier.
- Incidental functionality required by supported Python 3.6 versions. (Hooks to enable restricted subclassing.)
0.1.0 (2018-06-10)
------------------
- First release on PyPI.
FAQs
Code generators for immutable structured data, including algebraic data types, and functions to destructure them.
We found that structured-data demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago.Ā It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The initial version of the Socket Python SDK is now on PyPI, enabling developers to more easily interact with the Socket REST API in Python projects.
Security News
Floating dependency ranges in npm can introduce instability and security risks into your project by allowing unverified or incompatible versions to be installed automatically, leading to unpredictable behavior and potential conflicts.
Security News
A new Rust RFC proposes "Trusted Publishing" for Crates.io, introducing short-lived access tokens via OIDC to improve security and reduce risks associated with long-lived API tokens.