When defining fixtures in Pytest, the decorator fixture supports both parentheses and arguments, such as(scope = "session"), and parentheses and arguments. The following code is an example of both uses in the Pytest documentation.
Source: Pytest documentation
python
@pytest.fixture
def smtp():
return smtplib.SMTP("smtp.gmail.com")
python
@pytest.fixture(scope="module")
def smtp():
return smtplib.SMTP("smtp.gmail.com")
I tried to find out how to describe such a decorator.
To be precise, in the former parenthesis and no-argument usage, fixture is called a decorator, and in the latter parenthesis and no-argument usage, fixture is a decorator-creating decorator (decomaker). .. ([PEP 318 --Decorators for Functions and Methods]
(https://www.python.org/dev/peps/pep-0318/#current-syntax))
In Pytest's fixture source, the fixture was implemented as follows:
python
def fixture(scope="function", params=None, autouse=False, ids=None, name=None):
""" (return a) decorator to mark a fixture factory function.
This decorator ....(Abbreviation)
"""
if callable(scope) and params is None and autouse == False:
# direct decoration
return FixtureFunctionMarker(
"function", params, autouse, name=name)(scope)
if params is not None and not isinstance(params, (list, tuple)):
params = list(params)
return FixtureFunctionMarker(scope, params, autouse, ids=ids, name=name)
If fixture is used as a decorator with parentheses and no arguments, the scope argument to fixture is passed the function object defined in the function definition following the decorator (smtp in the example above). I will.
ʻIf callable (on the line of ..., check if scope is callable(at the same time, if the argument that follows is the default value), and if so, decomakerFixtureFunctionMakerCreate an instance of, and passscope to its () `.
On the other hand, if fixture is used with parentheses and arguments, it returns the decorator (decomaker instance) itself. Python passes smtp to the returned decorator and assigns the return value to the name smtp.
It's unpleasant to use the initial argument scope for a completely different purpose, but it can be aggregated into a single function, creating a user-friendly decorator interface.
Recommended Posts