Describe the bug
When the fs fixture is used as input into a fixture yielding a Flask test client, using the test client fixture causes the test to error with the error message "importlib.metadata.PackageNotFoundError: No package metadata was found for werkzeug"
Test stack trace:
_______________________________ ERROR at setup of test_app ________________________________
cls = <class '_pytest.runner.CallInfo'>
func = <function call_and_report.<locals>.<lambda> at 0x10bdac820>, when = 'setup'
reraise = (<class '_pytest.outcomes.Exit'>, <class 'KeyboardInterrupt'>)
@classmethod
def from_call(
cls,
func: Callable[[], TResult],
when: Literal["collect", "setup", "call", "teardown"],
reraise: type[BaseException] | tuple[type[BaseException], ...] | None = None,
) -> CallInfo[TResult]:
"""Call func, wrapping the result in a CallInfo.
:param func:
The function to call. Called without arguments.
:type func: Callable[[], _pytest.runner.TResult]
:param when:
The phase in which the function is called.
:param reraise:
Exception or exceptions that shall propagate if raised by the
function, instead of being wrapped in the CallInfo.
"""
excinfo = None
start = timing.time()
precise_start = timing.perf_counter()
try:
> result: TResult | None = func()
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/runner.py:341:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/runner.py:242: in <lambda>
lambda: runtest_hook(item=item, **kwds), when=when, reraise=reraise
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/pluggy/_hooks.py:513: in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/pluggy/_manager.py:120: in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/unraisableexception.py:90: in pytest_runtest_setup
yield from unraisable_exception_runtest_hook()
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/unraisableexception.py:70: in unraisable_exception_runtest_hook
yield
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/logging.py:840: in pytest_runtest_setup
yield from self._runtest_for(item, "setup")
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/logging.py:829: in _runtest_for
yield
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/capture.py:893: in pytest_runtest_setup
return (yield)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/threadexception.py:87: in pytest_runtest_setup
yield from thread_exception_runtest_hook()
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/threadexception.py:68: in thread_exception_runtest_hook
yield
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/runner.py:160: in pytest_runtest_setup
item.session._setupstate.setup(item)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/runner.py:514: in setup
col.setup()
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/python.py:1630: in setup
self._request._fillfixtures()
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:697: in _fillfixtures
item.funcargs[argname] = self.getfixturevalue(argname)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:532: in getfixturevalue
fixturedef = self._get_active_fixturedef(argname)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:617: in _get_active_fixturedef
fixturedef.execute(request=subrequest)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:1091: in execute
result = ihook.pytest_fixture_setup(fixturedef=self, request=request)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/pluggy/_hooks.py:513: in __call__
return self._hookexec(self.name, self._hookimpls.copy(), kwargs, firstresult)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/pluggy/_manager.py:120: in _hookexec
return self._inner_hookexec(hook_name, methods, kwargs, firstresult)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/setuponly.py:36: in pytest_fixture_setup
return (yield)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:1140: in pytest_fixture_setup
result = call_fixture_func(fixturefunc, request, kwargs)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/_pytest/fixtures.py:891: in call_fixture_func
fixture_result = next(generator)
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/conftest.py:16: in test_client
yield app_fixture.test_client()
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/flask/app.py:723: in test_client
return cls( # type: ignore
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/flask/testing.py:131: in __init__
"HTTP_USER_AGENT": f"Werkzeug/{_get_werkzeug_version()}",
/Users/ryanoldford/Programming/Work/Berlinguette/TryingThingsOut/fakefs_importlib_metadata_bug/.venv/lib/python3.10/site-packages/flask/testing.py:103: in _get_werkzeug_version
_werkzeug_version = importlib.metadata.version("werkzeug")
/Users/ryanoldford/.pyenv/versions/3.10.5/lib/python3.10/importlib/metadata/__init__.py:984: in version
return distribution(distribution_name).version
/Users/ryanoldford/.pyenv/versions/3.10.5/lib/python3.10/importlib/metadata/__init__.py:957: in distribution
return Distribution.from_name(distribution_name)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
cls = <class 'importlib.metadata.Distribution'>, name = 'werkzeug'
@classmethod
def from_name(cls, name):
"""Return the Distribution for the given package name.
:param name: The name of the distribution package to search for.
:return: The Distribution instance (or subclass thereof) for the named
package, if found.
:raises PackageNotFoundError: When the named package's distribution
metadata cannot be found.
"""
for resolver in cls._discover_resolvers():
dists = resolver(DistributionFinder.Context(name=name))
dist = next(iter(dists), None)
if dist is not None:
return dist
else:
> raise PackageNotFoundError(name)
E importlib.metadata.PackageNotFoundError: No package metadata was found for werkzeug
/Users/ryanoldford/.pyenv/versions/3.10.5/lib/python3.10/importlib/metadata/__init__.py:548: PackageNotFoundError
How To Reproduce
Import these packages: Flask 3.1.0, pyfakefs 5.8.0, pytest 8.3.5
Create the following files:
app.py
from contextlib import contextmanager
from typing import Generator
from flask import Flask
from local_types import ApiResponse
@contextmanager
def create_app() -> Generator[Flask, None, None]:
app = Flask(__name__)
@app.route("/", methods=["GET"])
def basic_get() -> ApiResponse:
return {"message": "Works!"}, 200
yield app
local_types.py
from typing import Any, Generator, TypeVar
ApiResponse = tuple[dict[str, Any], int]
T = TypeVar("T")
YieldFixture = Generator[T, Any, Any]
conftest.py
import pytest
from local_types import YieldFixture
from flask import Flask
from flask.testing import FlaskClient
from app import create_app
@pytest.fixture(scope="function")
def app_fixture(fs) -> YieldFixture[Flask]:
# mocking goes here
with create_app() as _app:
yield _app
@pytest.fixture(scope="function")
def test_client(app_fixture: Flask) -> YieldFixture[FlaskClient]:
yield app_fixture.test_client()
test_app.py
from flask.testing import FlaskClient
def test_app(test_client: FlaskClient, fs):
response = test_client.get("/")
assert response.status_code == 200
response_json = response.json
assert isinstance(response_json, dict)
assert response_json.get("message") == "Works!"
Run pytest and you will see the error. If you remove fs from the fixture parameters, the tests will pass normally.
Your environment
macOS-15.3.2-x86_64-i386-64bit
Python 3.10.5 (main, Apr 1 2025, 16:28:06) [Clang 16.0.0 (clang-1600.0.26.6)]
pyfakefs 5.8.0
pytest 8.3.5
Describe the bug
When the fs fixture is used as input into a fixture yielding a Flask test client, using the test client fixture causes the test to error with the error message "importlib.metadata.PackageNotFoundError: No package metadata was found for werkzeug"
Test stack trace:
How To Reproduce
Import these packages: Flask 3.1.0, pyfakefs 5.8.0, pytest 8.3.5
Create the following files:
app.py
local_types.py
conftest.py
test_app.py
Run pytest and you will see the error. If you remove fs from the fixture parameters, the tests will pass normally.
Your environment
macOS-15.3.2-x86_64-i386-64bit
Python 3.10.5 (main, Apr 1 2025, 16:28:06) [Clang 16.0.0 (clang-1600.0.26.6)]
pyfakefs 5.8.0
pytest 8.3.5