Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pip_cert fixture breaks tests if PIP_CERT is in os.environ #2048

Closed
frenzymadness opened this issue Jan 12, 2021 · 4 comments · Fixed by #2083
Closed

pip_cert fixture breaks tests if PIP_CERT is in os.environ #2048

frenzymadness opened this issue Jan 12, 2021 · 4 comments · Fixed by #2083

Comments

@frenzymadness
Copy link
Contributor

The new fixture pip_cert implemented in bc787b2 does not work if PIP_CERT is in os.environ. Pytest expect it to yield a value because it's recognized as a generator but if PIP_CERT is present in os.environ, the fixture returns None which causes pytest to fail with:

fixturefunc = <function pip_cert at 0x7f14f12ef3a0>
request = <SubRequest 'pip_cert' for <Function test_python[no_prompt]>>
kwargs = {'tmp_path_factory': TempPathFactory(_given_basetemp=None, _trace=<pluggy._tracing.TagTracerSub object at 0x7f14f0197490>, _basetemp=PosixPath('/tmp/pytest-of-mockbuild/pytest-0'))}

    def call_fixture_func(
        fixturefunc: "_FixtureFunc[_FixtureValue]", request: FixtureRequest, kwargs
    ) -> _FixtureValue:
        if is_generator(fixturefunc):
            fixturefunc = cast(
                Callable[..., Generator[_FixtureValue, None, None]], fixturefunc
            )
            generator = fixturefunc(**kwargs)
            try:
                fixture_result = next(generator)
            except StopIteration:
>               raise ValueError(
                    "{} did not yield a value".format(request.fixturename)
                ) from None
E               ValueError: pip_cert did not yield a value

fixturefunc = <function pip_cert at 0x7f14f12ef3a0>
generator  = <generator object pip_cert at 0x7f14ed790580>
kwargs     = {'tmp_path_factory': TempPathFactory(_given_basetemp=None, _trace=<pluggy._tracing.TagTracerSub object at 0x7f14f0197490>, _basetemp=PosixPath('/tmp/pytest-of-mockbuild/pytest-0'))}
request    = <SubRequest 'pip_cert' for <Function test_python[no_prompt]>>

/usr/lib/python3.9/site-packages/_pytest/fixtures.py:917: ValueError

An easy fix might be to use the condition in the decorator like @pytest.fixture(autouse=ensure_str("PIP_CERT") not in os.environ, scope="session").

@hroncok
Copy link
Contributor

hroncok commented Jan 12, 2021

What about changing the return to yield and moving the rest of the function to an else branch?

@pytest.fixture(autouse=True, scope="session")
def pip_cert(tmp_path_factory):
# workaround for https:/pypa/pip/issues/8984 - if the certificate is explicitly set no error can happen
key = ensure_str("PIP_CERT")
if key in os.environ:
return
cert = tmp_path_factory.mktemp("folder") / "cert"
import pkgutil
cert_data = pkgutil.get_data("pip._vendor.certifi", "cacert.pem")
cert.write_bytes(cert_data)
with change_os_environ(key, str(cert)):
yield

@pytest.fixture(autouse=True, scope="session")
def pip_cert(tmp_path_factory):
    # workaround for https:/pypa/pip/issues/8984 - if the certificate is explicitly set no error can happen
    key = ensure_str("PIP_CERT")
    if key in os.environ:
        yield
    else:
        cert = tmp_path_factory.mktemp("folder") / "cert"
        import pkgutil

        cert_data = pkgutil.get_data("pip._vendor.certifi", "cacert.pem")
        cert.write_bytes(cert_data)
        with change_os_environ(key, str(cert)):
            yield

@frenzymadness
Copy link
Contributor Author

Would it be helpful to prepare a PR with the proposed change?

@gaborbernat
Copy link
Contributor

Yes.

@frenzymadness
Copy link
Contributor Author

On it.

frenzymadness added a commit to frenzymadness/virtualenv that referenced this issue Mar 17, 2021
pip_cert is recognized as a generator so it should not use
return if PIP_CERT is in os.environ.

Fixes: pypa#2048
gaborbernat pushed a commit that referenced this issue Mar 17, 2021
pip_cert is recognized as a generator so it should not use
return if PIP_CERT is in os.environ.

Fixes: #2048
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants