5.2. spy.decorators

This module contains various function decorators for use in spy fragments.

@spy.decorators.accumulate[source]
--accumulate, -a

Accumulate values into an iterator by calling spy.collect(), and pass that to the fragment.

This can be used to write a fragment which executes at most once while passing data through:

-ma 'x = y;'

@spy.decorators.callable[source]
--callable, -c

Call the result of the decorated fragment

@spy.decorators.filter[source]
--filter, -f

Use the decorated fragment as a predicate—only elements for which the fragment returns a true value will be passed through.

@spy.decorators.keywords[source]
--keywords, -k

On fragments generated by the CLI, sets the local scope to the input value before each invocation. Normal Python functions cannot do this—trying to decorate them will raise ValueError.

@spy.decorators.many[source]
--many, -m

Call spy.many() with the result of the fragment.

@spy.decorators.focus(ITEM)[source]
--focus=ITEM, -o ITEM

Operate on pipe[ITEM]. The result will be assigned to the same position in a shallow copy of the input, which will need to be mutable despite not normally being modified.

On the CLI, if ITEM is a decimal integer, it will be interpreted as an integer index. If instead it starts with a dot ., everything after the dot will be taken as a literal string key.

If you have lenses installed, some more forms are available. Two or three decimal integers separated by : will focus on each element of a slice of the input:

$ spy '[1,2,3,4,5,6]' -o 1::2 'pipe * 7'
[1, 14, 3, 28, 5, 42]

And a string starting with _ will be evaluated as a Python expression with _ bound to lens, allowing you to focus with arbitrary lenses:

$ spy '["abc", "def"]' -o '_.Each()[1]' -c str.upper
['aBc', 'dEf']

Natively-understood focuses will be turned into lenses too, allowing them to operate on any immutable object that lenses can handle.

@spy.decorators.magnify(ITEM)[source]
--magnify=ITEM, -O ITEM

As focus(), except that the result is returned as-is, rather than spliced into a copy of the input. The portion of the input that was not magnified is thus discarded.

Magnifying with a lens that has multiple foci will simply use the first one. Further work on this area is aspired to.

@spy.decorators.try_except[source]
--try, -t

Filter out input that causes the fragment to raise an exception. This is the equivalent of a try: except:-block in the fragment.

5.2.1. Literal decorators

On the CLI, these decorators take a literal string rather than Python code. In Python-land, they expect to decorate a function that returns (scope, string). They’re especially pointless for non-CLI uses, and this documentation is written with CLI usage in mind.

@spy.decorators.interpolate
--interpolate, -i

Interpolate the literal argument as a str.format() format string.

Keyword substitutions ({foo}) look up variable names. Positional substitutions ({2}) are indexes into the value being processed.

@spy.decorators.regex[source]
--regex, --regexp, -R

Match a regexp against the input using re.match().

5.2.2. Defining decorators

For integration with spy’s CLI and exception handling, decorators should be created using decorator().

@spy.decorators.decorator(name, *aliases[, doc=None][, prep=None][, takes_string=False][, dec_args=()])[source]

Turns a wrapper function into a spy decorator.

name and aliases are the CLI options that should refer to this decorator; doc is the help output to be printed next to it by --help.

If prep is passed, it must be a callable taking one argument, the callable we are about to decorate, and the wrapper will be called as:

wrapper(fn, v, context, opaque)

where opaque is whatever prep returns. Otherwise, the wrapper will be called with the first three arguments only.

If takes_string is True, the command-line option will consume a literal string instead of Python code, and fn will return a tuple of its local scope and the literal string value.

If dec_args is nonempty, it must be a sequence of callables with usage_name attributes. Each such callable consumes an extra argument after the decorator’s name, and its return value is passed as an additional argument to prep.

If you pass dec_args without prep, one will be invented for you that simply returns its argument (or its arguments as a tuple, if there are more than one).

For usage examples, see Adding decorators.