Skip to content

Commit

Permalink
fix: defer snapshot default extension import (#734)
Browse files Browse the repository at this point in the history
* test: add coverage for bug #719

* fix: defer snapshot default extension import

Fixes unable to use pytest's `pythonpath` option with this project's
`--snapshot-default-extension` option. Does cause extension import
errors to raise later than CLI argument parsing, and therefore emit on
stdout, instead of stderr.

---------

Co-authored-by: Noah Negin-Ulster <noah.negin-ulster@tophatmonocle.com>
  • Loading branch information
john-kurkowski and Noah Negin-Ulster authored Apr 25, 2023
1 parent 3152c56 commit dfd5910
Show file tree
Hide file tree
Showing 4 changed files with 106 additions and 13 deletions.
6 changes: 0 additions & 6 deletions src/syrupy/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,11 +41,6 @@ def __import_extension(value: Optional[str]) -> Any:
raise argparse.ArgumentTypeError(e)


def __default_extension_option(value: Optional[str]) -> Any:
__import_extension(value)
return value


def pytest_addoption(parser: Any) -> None:
"""
Exposes snapshot plugin configuration to pytest.
Expand Down Expand Up @@ -78,7 +73,6 @@ def pytest_addoption(parser: Any) -> None:
# all pytest options to be serializable.
group.addoption(
"--snapshot-default-extension",
type=__default_extension_option,
default=None,
dest="default_extension",
help="Specify the default snapshot extension",
Expand Down
5 changes: 4 additions & 1 deletion src/syrupy/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,14 @@ def import_module_member(path: str) -> Any:
)
)
try:
return getattr(import_module(module_name), module_member_name)
module = import_module(module_name)
except ModuleNotFoundError:
raise FailedToLoadModuleMember(
gettext("Module '{}' does not exist.").format(module_name)
)

try:
return getattr(module, module_member_name)
except AttributeError:
raise FailedToLoadModuleMember(
gettext("Member '{}' not found in module '{}'.").format(
Expand Down
7 changes: 1 addition & 6 deletions tests/integration/test_snapshot_option_extension.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,12 +37,7 @@ def test_snapshot_default_extension_option_failure(testfile):
"--snapshot-default-extension",
"syrupy.extensions.amber.DoesNotExistExtension",
)
result.stderr.re_match_lines(
(
r".*error: argument --snapshot-default-extension"
r": Member 'DoesNotExistExtension' not found.*",
)
)
result.stdout.re_match_lines((r".*: Member 'DoesNotExistExtension' not found.*",))
assert not Path(
testfile.tmpdir, "__snapshots__", "test_file", "test_default.raw"
).exists()
Expand Down
101 changes: 101 additions & 0 deletions tests/integration/test_snapshot_option_extension_pythonpath.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
import textwrap
from pathlib import Path

import pytest

import syrupy

SUBDIR = "subdir_not_on_default_path"


@pytest.fixture(autouse=True)
def cache_clear():
syrupy.__import_extension.cache_clear()


@pytest.fixture
def testfile(pytester):
subdir = pytester.mkpydir(SUBDIR)

Path(
subdir,
"extension_file.py",
).write_text(
data=textwrap.dedent(
"""
from syrupy.extensions.single_file import SingleFileSnapshotExtension
class MySingleFileExtension(SingleFileSnapshotExtension):
pass
"""
),
encoding="utf-8",
)

pytester.makepyfile(
test_file=(
"""
def test_default(snapshot):
assert b"default extension serializer" == snapshot
"""
)
)

return pytester


def test_snapshot_default_extension_option_success(testfile):
testfile.makeini(
f"""
[pytest]
pythonpath =
{Path(testfile.path, SUBDIR).as_posix()}
"""
)

result = testfile.runpytest(
"-v",
"--snapshot-update",
"--snapshot-default-extension",
"extension_file.MySingleFileExtension",
)
result.stdout.re_match_lines((r"1 snapshot generated\."))
assert Path(
testfile.path, "__snapshots__", "test_file", "test_default.raw"
).exists()
assert not result.ret


def test_snapshot_default_extension_option_module_not_found(testfile):
result = testfile.runpytest(
"-v",
"--snapshot-update",
"--snapshot-default-extension",
"extension_file.MySingleFileExtension",
)
result.stdout.re_match_lines((r".*: Module 'extension_file' does not exist.*",))
assert not Path(
testfile.path, "__snapshots__", "test_file", "test_default.raw"
).exists()
assert result.ret


def test_snapshot_default_extension_option_failure(testfile):
testfile.makeini(
f"""
[pytest]
pythonpath =
{Path(testfile.path, SUBDIR).as_posix()}
"""
)

result = testfile.runpytest(
"-v",
"--snapshot-update",
"--snapshot-default-extension",
"extension_file.DoesNotExistExtension",
)
result.stdout.re_match_lines((r".*: Member 'DoesNotExistExtension' not found.*",))
assert not Path(
testfile.path, "__snapshots__", "test_file", "test_default.raw"
).exists()
assert result.ret

0 comments on commit dfd5910

Please sign in to comment.