parametrize_from_file.Namespace

class parametrize_from_file.Namespace(*args, **kwargs)

Bases: Mapping

Evaluate and/or execute snippets of python code, with powerful control over the names available to those snippets.

Note

It is conventional to:

  • Name your namespaces: with_{short description}

  • Create any namespaces you will need in a single helper file (e.g. param_helpers.py) to be imported in test scripts as necessary. Note that namespaces are immutable, so it’s safe for them to be global variables.

Examples

The first step when using a namespace is to specify which names it should include. This can be done using…

…strings (which will be exec’d):

>>> with_math = Namespace('import math')
>>> with_math.eval('math.sqrt(4)')
2.0

…dictionaries:

>>> import math
>>> with_math = Namespace(globals())
>>> with_math.eval('math.sqrt(4)')
2.0

…modules:

>>> with_math = Namespace(math)
>>> with_math.eval('math.sqrt(4)')
2.0

…other namespaces (via the constructor):

>>> with_np = Namespace(with_math, 'import numpy as np')
>>> with_np.eval('np.arange(3) * math.sqrt(4)')
array([0., 2., 4.])

…other namespaces (via the fork method):

>>> with_np = with_math.fork('import numpy as np')
>>> with_np.eval('np.arange(3) * math.sqrt(4)')
array([0., 2., 4.])

…keyword arguments:

>>> with_math = Namespace(math=math)
>>> with_math.eval('math.sqrt(4)')
2.0

…the star function:

>>> with_math = Namespace(star(math))
>>> with_math.eval('sqrt(4)')
2.0

Once you have an initialized namespace, you can use it to…

…evaluate expressions:

>>> with_math.eval('sqrt(4)')
2.0

…execute blocks of code:

>>> ns = with_math.exec('''
... a = sqrt(4)
... b = sqrt(9)
... ''')
>>> ns['a']
2.0
>>> ns['b']
3.0
>>> ns.eval('a + b')
5.0

…make error-detecting context managers:

>>> class MyError(Exception):
...     pass
...
>>> with_err = Namespace(MyError=MyError)
>>> err_cm = with_err.error({'type': 'MyError', 'pattern': r'\d+'})
>>> with err_cm:
...    raise MyError('404')

Public Methods:

__init__(*args, **kwargs)

Construct a namespace containing the given names.

__repr__()

Return repr(self).

__getitem__(key)

__iter__()

__len__()

copy()

Create a shallow copy of this namespace.

fork(*args, **kwargs)

Create a shallow copy of this namespace.

eval(*src[, keys, defer])

Evaluate the given expression within this namespace.

exec([src, get, defer])

Execute the given python snippet within this namespace.

error(exc_spec)

Make an exception-checking context manager in the context of this namespace.

error_or(*expected, **kwargs)

Make an exception-checking schema function in the context of this namespace.

Inherited from Mapping

__getitem__(key)

get(k[,d])

__contains__(key)

keys()

items()

values()

__eq__(other)

Return self==value.

Inherited from Collection

__subclasshook__(C)

Abstract classes can override this to customize issubclass().

Inherited from Sized

__len__()

__subclasshook__(C)

Abstract classes can override this to customize issubclass().

Inherited from Iterable

__iter__()

__subclasshook__(C)

Abstract classes can override this to customize issubclass().

Inherited from Container

__contains__(x)

__subclasshook__(C)

Abstract classes can override this to customize issubclass().

Private Data Attributes:

_abc_impl

Inherited from Mapping

_abc_impl

Inherited from Collection

_abc_impl

Inherited from Sized

_abc_impl

Inherited from Iterable

_abc_impl

Inherited from Container

_abc_impl


__abstractmethods__ = frozenset({})
__contains__(key)
__eq__(other)

Return self==value.

__getitem__(key)[source]
__hash__ = None
__init__(*args, **kwargs)[source]

Construct a namespace containing the given names.

Parameters:
  • args (str,dict,types.ModuleType) –

    If string: The string will be executed as python code and any names that are defined by that code will be added to the namespace. Any names added by previous arguments will be available to the code.

    If dict: The items in the dictionary will the directly added to the namespace. All of the dictionary keys must be strings.

    If module: The module will be added to the namespace, with its name as the key.

    The args are processed in order, so later args may overwrite earlier args.

  • kwargs – Each key/value pair will be added to the namespace. The kwargs are processed after the args, so if the same key is defined by both, the kwargs definition will be used.

__iter__()[source]
__len__()[source]
__repr__()[source]

Return repr(self).

__reversed__ = None
__slots__ = ()
classmethod __subclasshook__(C)

Abstract classes can override this to customize issubclass().

This is invoked early on by abc.ABCMeta.__subclasscheck__(). It should return True, False or NotImplemented. If it returns NotImplemented, the normal algorithm is used. Otherwise, it overrides the normal algorithm (and the outcome is cached).

_abc_impl = <_abc_data object>
copy()[source]

Create a shallow copy of this namespace.

This is an alias for fork() with no arguments, for compatibility with the dict API.

error(exc_spec)[source]

Make an exception-checking context manager in the context of this namespace.

See the error documentation for more information. This method simply calls error with the globals argument set to this namespace.

error_or(*expected, **kwargs)[source]

Make an exception-checking schema function in the context of this namespace.

See the error_or documentation for more information. This method simply calls error_or with the globals argument set to this namespace.

eval(*src, keys=False, defer=False)[source]

Evaluate the given expression within this namespace.

Parameters:
  • src (str,list,dict) – The expression (or expressions) to evaluate. Strings are directly evaluated. List items and dict values are recursively evaluated. Dict keys are not evaluated unless keys is true. This allows you to switch freely between structured text and python syntax, depending on which makes most sense for each particular input.

  • keys (bool) – If true, evaluate dictionary keys. Disabled by default because most dictionary keys are strings, and it’s annoying to have to quote them.

  • defer (bool) – If true, instead of actually evaluating the given expressions, return a no-argument callable that will evaluate them when called. The purpose of this is to make it possible to specify that a test parameter should be evaluated in a schema, but to defer actually evaluating it until inside the test function.

Returns:

If no src expressions were given: A functools.partial version of this function that will remember any specified keyword arguments.

If any src expressions were given and the defer argument was True: A functools.partial version of this function that will remember the expressions and keyword arguments given to it. The return value will also have an eval attribute that aliases the deferred function.

If any src expressions were given and the defer argument was False: The result(s) of evaluating the given expression(s).

Return type:

Any

Examples

Basic usage:

>>> with_a = Namespace(a=1)
>>> with_a.eval('a + 1')
2

Control whether or not dictionary keys are evaluated:

>>> with_a.eval({'a': '2'})
{'a': 2}
>>> with_a.eval({'a': '2'}, keys=True)
{1: 2}

Use a schema to specify that a test parameter should be evaluated, but defer that evaluation until within the test:

>>> @parametrize_from_file(  
...         schema=cast(
...             expected=with_a.eval(defer=True),
...         ),
... )
... def test_snippet(expected)
...     expected = expected.eval()

Details

It’s sometimes convenient to call this method on values that have been processed by error_or. Such inputs may contain instances of two types that cannot normally be evaluated: unittest.mock.Mock and the internal context manager type returned by error. To allow for this convenience, both of these types are treated specially by this method and passed through unchanged.

exec(src=<object object>, get=<object object>, defer=False)[source]

Execute the given python snippet within this namespace.

Parameters:
  • src (str) – A snippet of python code to execute.

  • get (str, collections.abc.Iterable, collections.abc.Callable) –

    If string: The name of a variable defined in the given snippet to look up and pass on to the caller.

    If iterable: The names of variables defined in the given snippet to look up and return to the caller. The return value will be a tuple with the same length as the given iterable.

    If callable: The given function will be passed a read-only dictionary containing all the names defined in the given snippet. Whatever that function returns will be passed on to the caller.

  • defer (bool) – If true, instead of actually evaluating the given snippet, return a no-argument callable that will evaluate it when called. The purpose of this is to make it possible to specify that a test parameter should be executed in a schema, but to defer actually executing it until inside the test function.

Returns:

If src was not specified: A functools.partial version of this function that will remember any specified keyword arguments.

If src was specified and the defer argument was True: A functools.partial version of this function that will remember the snippet and keyword arguments given to it. The return value will also have an exec attribute that aliases the deferred function.

If src was specified and get was not: A new Namespace containing all of the variables defined in the snippet.

If src and get were specified: The value(s) of the indicated variable(s) defined the snippet.

Return type:

Any

Examples

Basic usage:

>>> with_a = Namespace(a=1)
>>> with_b = with_a.exec('b = a + 1')
>>> with_a
Namespace({'a': 1})
>>> with_b
Namespace({'a': 1, 'b': 2})

Get a specific value from the executed snippet:

>>> with_a.exec('b = a + 1', get='b')
2

Use a schema to specify that a test parameter should be executed, but defer that execution until within the test:

>>> @parametrize_from_file(  
...         schema={
...             'snippet': with_a.exec(defer=True),
...         },
... )
... def test_snippet(snippet)
...     snippet = snippet.exec()

Details

It’s sometimes convenient to call this method on values that have been processed by error_or. Such inputs may contain instances of two types that cannot normally be evaluated: unittest.mock.Mock and the internal context manager type returned by error. To allow for this convenience, both of these types are treated specially by this method and passed through unchanged.

fork(*args, **kwargs)[source]

Create a shallow copy of this namespace.

The arguments allow new names to be added to the new namespace. All arguments have the same meaning as in the constructor.

get(k[, d])
items()
keys()
values()