API reference

Value generators

Value generation for factories.

Gen class

class arv.factory.generators.Gen(iterable)

Base class for value generators.

Consider the following example:

>>> factory = Factory(data=[1, 2, 3])

What does that mean? the list [1, 2, 3] is a literal value for data or enumerates the individual values for the attribute on successive calls to the factory? In order to avoid this ambiguity we need some mean to distinguish when an iterable should be used as a literal value for the attribute or as providing individual values.

Gen is just a class to mark iterables as value generators. It implements the iterator protocol and defines a thin wrapper that delegates the calls to the underlying iterable.

With that in mind the list in the previous example is interpreted as a literal value. In order to use it as a value generator we must do:

>>> from arv.factory.api import gen
>>> factory = Factory(data=gen.Gen([1, 2, 3]))

Note

Gen instances are themselves iterables, but wrapping a Gen instance within another Gen instance does nothing apart from introducing some extra calls due to additional levels of nesting.

In order to avoid that inefficiency instantiating a Gen from a Gen object returns the original Gen. The magic is done in the __new__ and __init__ methods.

lazy class

class arv.factory.generators.lazy(f, *args, **kwargs)

Lazy callable.

Marker class for callables and its arguments. The Factory class recognizes instances of this class and calls them at factory creation time.

mkgen function

arv.factory.generators.mkgen(f, *args, **kwargs)

Create a generator from a function.

Returns a value generator (an instance of the Gen class) wich will call the function f with the given arguments each time it’s consumed. The return value from the call will be the value produced by the generator.

>>> import random
>>> from arv.factory.api import gen
>>> g = gen.mkgen(random.randint, 1, 100)

mkconstructor function

arv.factory.generators.mkconstructor(iterable, *args, **kwargs)

Create a lazy constructor from an iterable.

Given an iterable or a callable that returns an iterable, creates a constructor that will be evaluated at factory construction time.

In other words, given an iterable or a callable that returns an iterable, return an object than can safely be used in metafactory definitions.

>>> import itertools
>>> from arv.factory.api import gen
>>> Count = gen.mkconstructor(itertools.count)
>>> Cycle = gen.mkconstructor(itertools.cycle, (1, 2, 3))