Skip to content

Commit

Permalink
feat: preserve order of args in wrap_fixture
Browse files Browse the repository at this point in the history
  • Loading branch information
theY4Kman committed Jul 17, 2022
1 parent 67bccba commit 7f5eb24
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 4 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.

## [Unreleased]
### Changed
- Preserve declared order of arguments with `wrap_fixture` (decorated method's first, then wrapped fixture's, then `request`)
- DOC: add destructuring examples to README


Expand Down
15 changes: 11 additions & 4 deletions pytest_lambda/util.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import functools
from contextlib import suppress
from typing import Callable, Iterable, Union

from _pytest.compat import getfuncargnames, get_real_func
Expand Down Expand Up @@ -61,17 +62,23 @@ def admin_user(team, wrapped):
fixturefunc = get_real_func(fixturefunc)

def decorator(fn: Callable):
decorated_arg_names = set(getfuncargnames(fn))
decorated_arg_names = list(getfuncargnames(fn))
if wrapped_param not in decorated_arg_names:
raise TypeError(
f'The decorated method must include an arg named {wrapped_param} '
f'as the wrapped fixture func.')

# Don't include the wrapped param in the argspec we expose to pytest
decorated_arg_names -= {wrapped_param}
decorated_arg_names.remove(wrapped_param)

fixture_arg_names = set(getfuncargnames(fixturefunc)) - set(ignore)
all_arg_names = fixture_arg_names | decorated_arg_names | {'request'}
fixture_arg_names = list(getfuncargnames(fixturefunc))
for ignored in ignore:
with suppress(ValueError):
fixture_arg_names.remove(ignored)

# Remove duplicates while retaining order of args (decorated, then wrapped)
all_arg_names = [*decorated_arg_names, *fixture_arg_names, 'request']
all_arg_names = list(sorted(set(all_arg_names), key=all_arg_names.index))

def extension_impl(**all_args):
request = all_args['request']
Expand Down
14 changes: 14 additions & 0 deletions tests/test_util.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,20 @@ def extended_fixture(extension_unique, wrapped):
actual = set(args) - {'request'}
assert expected == actual

def it_orders_decorated_method_args_first(self):
def fixture(fixture_unique):
pass

@wrap_fixture(fixture)
def extended_fixture(extension_unique, wrapped):
pass

args = getfuncargnames(extended_fixture)

expected = ('extension_unique', 'fixture_unique', 'request')
actual = args
assert expected == actual


def it_passes_wrapped_fixture_to_extension(self, request):
class Called(AssertionError):
Expand Down

0 comments on commit 7f5eb24

Please sign in to comment.