How are Behave decorators created / declared?

I am currently using Behave (BDD for Python) and digging through the source code to understand how decoders are declared @given

, @when

and @then

.

The most I've gone away is to see step_registry.py

where I found the function setup_step_decorators(context=None, registry=registry)

that appears to be doing the job.

However, I don't quite understand how these decorators are created, since they are not explicitly specified in the source code in the form def when(...):

. I am under the impression that they are declared based on a list of strings ( for step_type in ('given', 'when', 'then', 'step'):

), which is then processed by the call make_decorator()

.

Can anyone walk through the code and explain where / how these decorators are declared ?

You can access the source code for Behave here .

+3


source to share


2 answers


Well, let's start from the outside:

if context is None:
    context = globals()
for step_type in ('given', 'when', 'then', 'step'):
    step_decorator = registry.make_decorator(step_type)
    context[step_type.title()] = context[step_type] = step_decorator

      

I think the last line is confusing you.

Each global module namespace is just a dictionary. The function globals()

returns this dictionary. If you modify this dictionary, you are creating global global modules. For example:



>>> globals()['a'] = 2
>>> a
2

      

In this case, by default context = globals()

. So, for, say, the first one step_type

, you effectively do this:

>>> globals()['given'] = step_decorator

      

+3


source


They are put in globals()

around line 90 (at this point context

there is globals()

because there context

is None

):

# -- Create the decorators
def setup_step_decorators(context=None, registry=registry):
    if context is None:
        context = globals()
    for step_type in ('given', 'when', 'then', 'step'):
        step_decorator = registry.make_decorator(step_type)
        context[step_type.title()] = context[step_type] = step_decorator

      



You can do this too ( globals()

works just like a regular dictionary):

>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined
>>> globals()['a'] = 5
>>> a
5

      

+3


source







All Articles