Skip to main content

Lenses from python expressions.

Project description

Python Expression Lenses

Python expressions to/from lenses. This library focuses on constructing lenses from python expressions, targeting function bindings as the primary container to get/set from/to. Such lenses can be serialized into strings which are valid python expressions (and thus can be deserialized using the python expression parser).

Alternatives

This package has very specific goals which are not considerations in the theory of lenses. Consider these alternatives for more general lens usage:

  • lenses - more general and feature rich lenses implementation based on lenses in Haskell.
  • pylens - simpler
  • simplelens - unknown functionality

Basic usage

from exprlens import arg

# Lens for getting the first item in the first argument from a call:
first = arg[0]  

# Getter can be accessed using the `get` method or by calling (`__call__`):
assert first.get([0, 1, 2, 3]) == first([0, 1, 2, 3]) == 0

# Setter can be accessed using the `set` method.
assert first.set([0, 1, 2, 3], val=42) == [42, 1, 2, 3]

Expressions

from exprlens import arg

# Lens that first grabs the first two items in the first argument and adds them:
plusfirsts = arg[0] + arg[1]  

# Note that once expression lenses are constructed, `set` can no longer be used on them.
# plusfirsts.set([1, 2, 3, 4], val=42)  # Raises an exception.

assert plusfirsts([1, 2, 3, 4]) == 3

# Literals/constants: Expression lenses can involve literals/constants.
plusone = arg + 1
assert list(map(plusone, [1, 2, 3])) == [2, 3, 4]

Validation

from exprlens import args, kwargs

# Lenses can be validate on construction:
args[0] # ok
# args["something"] # error

kwargs["something"] # ok
# kwargs[0] # error

# Lenses can be validated on use:

# Lens that gets a key from the first argument, thus the first argument must be a mapping:
firstkey = arg["something"]
firstkey.get({"something": 42}) # ok

# Will fail if the first argument is not a mapping:
# firstkey.get([1,2,3]) # error

Boolean expressions (TODO)

Python does not allow overriding boolean operators (and, or, not) (see relevant rejected PEP) so lenses corresponding to expressions with boolean operators cannot be created by writing python directly, i.e. lens[0] and lens[1]. Instead you can make use of Expr.conjunction, Expr.disjunction, and Expr.negation static methods to construct these. Alternatively you can use Expr.of_string static method to construct it from python code, e.g. Expr.of_string("lens[0] and lens[1]").

from exprlens import Expr, lens

assert Expr.conjunction(lens[0], lens[1]) == Expr.of_string("lens[0] and lens[1]")

Serialization (TODO)

from exprlens import Expr
from ast import parse

assert repr(plusone) == "(args[0] + 1)"

assert plusone.pyast == parse(repr(plusone), mode="eval")
assert plusone == Expr.of_string(repr(plusone))

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

exprlens-0.0.2.tar.gz (9.6 kB view hashes)

Uploaded Source

Built Distribution

exprlens-0.0.2-py3-none-any.whl (10.2 kB view hashes)

Uploaded Python 3

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page