https://github.com/httpie/cli/commit/3524ccf0baa9f2b3029368ab07ba5f64e62dcb1f
https://github.com/httpie/cli/commit/db16bbee961ceb93b7831fe1ec44a72d56a33e38

From 3524ccf0baa9f2b3029368ab07ba5f64e62dcb1f Mon Sep 17 00:00:00 2001
From: Jakub Roztocil <jakub@roztocil.co>
Date: Mon, 4 Mar 2024 16:27:52 +0100
Subject: [PATCH] Drop dependency on the abandoned python-lazy-fixture

--- a/setup.py
+++ b/setup.py
@@ -11,7 +11,6 @@
 tests_require = [
     'pytest',
     'pytest-httpbin>=0.0.6',
-    'pytest-lazy-fixture>=0.0.6',
     'responses',
     'pytest-mock',
     'werkzeug<2.1.0'
--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -3,14 +3,14 @@
 import pytest
 from pytest_httpbin import certs
 
-from .utils import ( # noqa
+from .utils import (  # noqa
     HTTPBIN_WITH_CHUNKED_SUPPORT_DOMAIN,
     HTTPBIN_WITH_CHUNKED_SUPPORT,
     REMOTE_HTTPBIN_DOMAIN,
     IS_PYOPENSSL,
     mock_env
 )
-from .utils.plugins_cli import ( # noqa
+from .utils.plugins_cli import (  # noqa
     broken_plugin,
     dummy_plugin,
     dummy_plugins,
@@ -18,7 +18,9 @@
     httpie_plugins_success,
     interface,
 )
-from .utils.http_server import http_server, localhost_http_server # noqa
+from .utils.http_server import http_server, localhost_http_server  # noqa
+# noinspection PyUnresolvedReferences
+from .fixtures import pytest_lazy_fixture
 
 
 @pytest.fixture(scope='function', autouse=True)
--- /dev/null
+++ b/tests/fixtures/pytest_lazy_fixture.py
@@ -0,0 +1,99 @@
+"""
+Replacement for the abandoned `pytest.lazy_fixture` <https://github.com/TvoroG/pytest-lazy-fixture>
+
+Based on <https://github.com/TvoroG/pytest-lazy-fixture/issues/65#issuecomment-1914581161>
+
+"""
+import dataclasses
+import typing
+
+import pytest
+
+
+@dataclasses.dataclass
+class LazyFixture:
+    """Lazy fixture dataclass."""
+
+    name: str
+
+
+def lazy_fixture(name: str) -> LazyFixture:
+    """Mark a fixture as lazy."""
+    return LazyFixture(name)
+
+
+# NOTE: Mimic the original API
+pytest.lazy_fixture = lazy_fixture
+
+
+def is_lazy_fixture(value: object) -> bool:
+    """Check whether a value is a lazy fixture."""
+    return isinstance(value, LazyFixture)
+
+
+def pytest_make_parametrize_id(
+    config: pytest.Config,
+    val: object,
+    argname: str,
+) -> str | None:
+    """Inject lazy fixture parametrized id.
+
+    Reference:
+    - https://bit.ly/48Off6r
+
+    Args:
+        config (pytest.Config): pytest configuration.
+        value (object): fixture value.
+        argname (str): automatic parameter name.
+
+    Returns:
+        str: new parameter id.
+    """
+    if is_lazy_fixture(val):
+        return typing.cast(LazyFixture, val).name
+    return None
+
+
+@pytest.hookimpl(tryfirst=True)
+def pytest_fixture_setup(
+    fixturedef: pytest.FixtureDef,
+    request: pytest.FixtureRequest,
+) -> object | None:
+    """Lazy fixture setup hook.
+
+    This hook will never take over a fixture setup but just simply will
+    try to resolve recursively any lazy fixture found in request.param.
+
+    Reference:
+    - https://bit.ly/3SyvsXJ
+
+    Args:
+        fixturedef (pytest.FixtureDef): fixture definition object.
+        request (pytest.FixtureRequest): fixture request object.
+
+    Returns:
+        object | None: fixture value or None otherwise.
+    """
+    if hasattr(request, "param") and request.param:
+        request.param = _resolve_lazy_fixture(request.param, request)
+    return None
+
+
+def _resolve_lazy_fixture(__val: object, request: pytest.FixtureRequest) -> object:
+    """Lazy fixture resolver.
+
+    Args:
+        __val (object): fixture value object.
+        request (pytest.FixtureRequest): pytest fixture request object.
+
+    Returns:
+        object: resolved fixture value.
+    """
+    if isinstance(__val, list | tuple):
+        return tuple(_resolve_lazy_fixture(v, request) for v in __val)
+    if isinstance(__val, typing.Mapping):
+        return {k: _resolve_lazy_fixture(v, request) for k, v in __val.items()}
+    if not is_lazy_fixture(__val):
+        return __val
+    lazy_obj = typing.cast(LazyFixture, __val)
+    return request.getfixturevalue(lazy_obj.name)

From db16bbee961ceb93b7831fe1ec44a72d56a33e38 Mon Sep 17 00:00:00 2001
From: Jakub Roztocil <jakub@roztocil.co>
Date: Mon, 4 Mar 2024 18:05:26 +0100
Subject: [PATCH] Drop dependency on the abandoned python-lazy-fixture II.

--- a/tests/conftest.py
+++ b/tests/conftest.py
@@ -2,6 +2,7 @@
 
 import pytest
 from pytest_httpbin import certs
+from pytest_httpbin.serve import Server as PyTestHttpBinServer
 
 from .utils import (  # noqa
     HTTPBIN_WITH_CHUNKED_SUPPORT_DOMAIN,
@@ -19,8 +20,10 @@
     interface,
 )
 from .utils.http_server import http_server, localhost_http_server  # noqa
-# noinspection PyUnresolvedReferences
-from .fixtures import pytest_lazy_fixture
+
+
+# Patch to support `url = str(server)` in addition to `url = server + '/foo'`.
+PyTestHttpBinServer.__str__ = lambda self: self.url
 
 
 @pytest.fixture(scope='function', autouse=True)
@@ -72,8 +75,15 @@ def _remote_httpbin_available():
 
 @pytest.fixture
 def remote_httpbin(_remote_httpbin_available):
+
     if _remote_httpbin_available:
-        return 'http://' + REMOTE_HTTPBIN_DOMAIN
+        class Server(str):
+            """Look like `pytest_httpbin.serve.Server` but only provide URL info."""
+            @property
+            def url(self):
+                return self
+
+        return Server('http://' + REMOTE_HTTPBIN_DOMAIN)
     pytest.skip(f'{REMOTE_HTTPBIN_DOMAIN} not resolvable')
 
 
--- a/tests/fixtures/pytest_lazy_fixture.py
+++ /dev/null
@@ -1,99 +0,0 @@
-"""
-Replacement for the abandoned `pytest.lazy_fixture` <https://github.com/TvoroG/pytest-lazy-fixture>
-
-Based on <https://github.com/TvoroG/pytest-lazy-fixture/issues/65#issuecomment-1914581161>
-
-"""
-import dataclasses
-import typing
-
-import pytest
-
-
-@dataclasses.dataclass
-class LazyFixture:
-    """Lazy fixture dataclass."""
-
-    name: str
-
-
-def lazy_fixture(name: str) -> LazyFixture:
-    """Mark a fixture as lazy."""
-    return LazyFixture(name)
-
-
-# NOTE: Mimic the original API
-pytest.lazy_fixture = lazy_fixture
-
-
-def is_lazy_fixture(value: object) -> bool:
-    """Check whether a value is a lazy fixture."""
-    return isinstance(value, LazyFixture)
-
-
-def pytest_make_parametrize_id(
-    config: pytest.Config,
-    val: object,
-    argname: str,
-) -> str | None:
-    """Inject lazy fixture parametrized id.
-
-    Reference:
-    - https://bit.ly/48Off6r
-
-    Args:
-        config (pytest.Config): pytest configuration.
-        value (object): fixture value.
-        argname (str): automatic parameter name.
-
-    Returns:
-        str: new parameter id.
-    """
-    if is_lazy_fixture(val):
-        return typing.cast(LazyFixture, val).name
-    return None
-
-
-@pytest.hookimpl(tryfirst=True)
-def pytest_fixture_setup(
-    fixturedef: pytest.FixtureDef,
-    request: pytest.FixtureRequest,
-) -> object | None:
-    """Lazy fixture setup hook.
-
-    This hook will never take over a fixture setup but just simply will
-    try to resolve recursively any lazy fixture found in request.param.
-
-    Reference:
-    - https://bit.ly/3SyvsXJ
-
-    Args:
-        fixturedef (pytest.FixtureDef): fixture definition object.
-        request (pytest.FixtureRequest): fixture request object.
-
-    Returns:
-        object | None: fixture value or None otherwise.
-    """
-    if hasattr(request, "param") and request.param:
-        request.param = _resolve_lazy_fixture(request.param, request)
-    return None
-
-
-def _resolve_lazy_fixture(__val: object, request: pytest.FixtureRequest) -> object:
-    """Lazy fixture resolver.
-
-    Args:
-        __val (object): fixture value object.
-        request (pytest.FixtureRequest): pytest fixture request object.
-
-    Returns:
-        object: resolved fixture value.
-    """
-    if isinstance(__val, list | tuple):
-        return tuple(_resolve_lazy_fixture(v, request) for v in __val)
-    if isinstance(__val, typing.Mapping):
-        return {k: _resolve_lazy_fixture(v, request) for k, v in __val.items()}
-    if not is_lazy_fixture(__val):
-        return __val
-    lazy_obj = typing.cast(LazyFixture, __val)
-    return request.getfixturevalue(lazy_obj.name)
--- a/tests/test_cookie_on_redirects.py
+++ b/tests/test_cookie_on_redirects.py
@@ -2,54 +2,47 @@
 from .utils import http
 
 
-def _stringify(fixture):
-    return fixture + ''
-
-
-@pytest.mark.parametrize('instance', [
-    pytest.lazy_fixture('httpbin'),
-    pytest.lazy_fixture('remote_httpbin'),
+@pytest.mark.parametrize('target_httpbin', [
+    'httpbin',
+    'remote_httpbin',
 ])
-def test_explicit_user_set_cookie(httpbin, instance):
-    # User set cookies ARE NOT persisted within redirects
-    # when there is no session, even on the same domain.
-
+def test_explicit_user_set_cookie(httpbin, target_httpbin, request):
+    """User set cookies ARE NOT persisted within redirects when there is no session, even on the same domain."""
+    target_httpbin = request.getfixturevalue(target_httpbin)
     r = http(
         '--follow',
         httpbin + '/redirect-to',
-        f'url=={_stringify(instance)}/cookies',
+        f'url=={target_httpbin.url}/cookies',
         'Cookie:a=b'
     )
     assert r.json == {'cookies': {}}
 
 
-@pytest.mark.parametrize('instance', [
-    pytest.lazy_fixture('httpbin'),
-    pytest.lazy_fixture('remote_httpbin'),
+@pytest.mark.parametrize('target_httpbin', [
+    'httpbin',
+    'remote_httpbin',
 ])
-def test_explicit_user_set_cookie_in_session(tmp_path, httpbin, instance):
-    # User set cookies ARE persisted within redirects
-    # when there is A session, even on the same domain.
-
+def test_explicit_user_set_cookie_in_session(tmp_path, httpbin, target_httpbin, request):
+    """User set cookies ARE persisted within redirects when there is A session, even on the same domain."""
+    target_httpbin = request.getfixturevalue(target_httpbin)
     r = http(
         '--follow',
         '--session',
         str(tmp_path / 'session.json'),
         httpbin + '/redirect-to',
-        f'url=={_stringify(instance)}/cookies',
+        f'url=={target_httpbin}/cookies',
         'Cookie:a=b'
     )
     assert r.json == {'cookies': {'a': 'b'}}
 
 
-@pytest.mark.parametrize('instance', [
-    pytest.lazy_fixture('httpbin'),
-    pytest.lazy_fixture('remote_httpbin'),
+@pytest.mark.parametrize('target_httpbin', [
+    'httpbin',
+    'remote_httpbin',
 ])
-def test_saved_user_set_cookie_in_session(tmp_path, httpbin, instance):
-    # User set cookies ARE persisted within redirects
-    # when there is A session, even on the same domain.
-
+def test_saved_user_set_cookie_in_session(tmp_path, httpbin, target_httpbin, request):
+    """User set cookies ARE persisted within redirects when there is A session, even on the same domain."""
+    target_httpbin = request.getfixturevalue(target_httpbin)
     http(
         '--follow',
         '--session',
@@ -62,32 +55,33 @@ def test_saved_user_set_cookie_in_session(tmp_path, httpbin, instance):
         '--session',
         str(tmp_path / 'session.json'),
         httpbin + '/redirect-to',
-        f'url=={_stringify(instance)}/cookies',
+        f'url=={target_httpbin}/cookies',
     )
     assert r.json == {'cookies': {'a': 'b'}}
 
 
-@pytest.mark.parametrize('instance', [
-    pytest.lazy_fixture('httpbin'),
-    pytest.lazy_fixture('remote_httpbin'),
+@pytest.mark.parametrize('target_httpbin', [
+    'httpbin',
+    'remote_httpbin',
 ])
 @pytest.mark.parametrize('session', [True, False])
-def test_explicit_user_set_headers(httpbin, tmp_path, instance, session):
-    # User set headers ARE persisted within redirects
-    # even on different domains domain with or without
-    # an active session.
+def test_explicit_user_set_headers(httpbin, tmp_path, target_httpbin, session, request):
+    """
+    User set headers ARE persisted within redirects even on different domains domain with or without an active session.
+
+    """
+    target_httpbin = request.getfixturevalue(target_httpbin)
     session_args = []
     if session:
         session_args.extend([
             '--session',
             str(tmp_path / 'session.json')
         ])
-
     r = http(
         '--follow',
         *session_args,
         httpbin + '/redirect-to',
-        f'url=={_stringify(instance)}/get',
+        f'url=={target_httpbin}/get',
         'X-Custom-Header:value'
     )
     assert 'X-Custom-Header' in r.json['headers']
@@ -95,16 +89,13 @@ def test_explicit_user_set_headers(httpbin, tmp_path, instance, session):
 
 @pytest.mark.parametrize('session', [True, False])
 def test_server_set_cookie_on_redirect_same_domain(tmp_path, httpbin, session):
-    # Server set cookies ARE persisted on the same domain
-    # when they are forwarded.
-
+    """Server set cookies ARE persisted on the same domain when they are forwarded."""
     session_args = []
     if session:
         session_args.extend([
             '--session',
             str(tmp_path / 'session.json')
         ])
-
     r = http(
         '--follow',
         *session_args,
@@ -136,8 +127,7 @@ def test_server_set_cookie_on_redirect_different_domain(tmp_path, http_server, h
 
 
 def test_saved_session_cookies_on_same_domain(tmp_path, httpbin):
-    # Saved session cookies ARE persisted when making a new
-    # request to the same domain.
+    """Saved session cookies ARE persisted when making a new request to the same domain."""
     http(
         '--session',
         str(tmp_path / 'session.json'),
@@ -152,8 +142,7 @@ def test_saved_session_cookies_on_same_domain(tmp_path, httpbin):
 
 
 def test_saved_session_cookies_on_different_domain(tmp_path, httpbin, remote_httpbin):
-    # Saved session cookies ARE persisted when making a new
-    # request to a different domain.
+    """Saved session cookies ARE persisted when making a new request to a different domain."""
     http(
         '--session',
         str(tmp_path / 'session.json'),
@@ -167,45 +156,49 @@ def test_saved_session_cookies_on_different_domain(tmp_path, httpbin, remote_htt
     assert r.json == {'cookies': {}}
 
 
-@pytest.mark.parametrize('initial_domain, first_request_domain, second_request_domain, expect_cookies', [
+@pytest.mark.parametrize(['initial_domain', 'first_request_domain', 'second_request_domain', 'expect_cookies'], [
     (
         # Cookies are set by    Domain A
         # Initial domain is     Domain A
         # Redirected domain is  Domain A
-        pytest.lazy_fixture('httpbin'),
-        pytest.lazy_fixture('httpbin'),
-        pytest.lazy_fixture('httpbin'),
+        'httpbin',
+        'httpbin',
+        'httpbin',
         True,
     ),
     (
         # Cookies are set by    Domain A
         # Initial domain is     Domain B
         # Redirected domain is  Domain B
-        pytest.lazy_fixture('httpbin'),
-        pytest.lazy_fixture('remote_httpbin'),
-        pytest.lazy_fixture('remote_httpbin'),
+        'httpbin',
+        'remote_httpbin',
+        'remote_httpbin',
         False,
     ),
     (
         # Cookies are set by    Domain A
         # Initial domain is     Domain A
         # Redirected domain is  Domain B
-        pytest.lazy_fixture('httpbin'),
-        pytest.lazy_fixture('httpbin'),
-        pytest.lazy_fixture('remote_httpbin'),
+        'httpbin',
+        'httpbin',
+        'remote_httpbin',
         False,
     ),
     (
         # Cookies are set by    Domain A
         # Initial domain is     Domain B
         # Redirected domain is  Domain A
-        pytest.lazy_fixture('httpbin'),
-        pytest.lazy_fixture('remote_httpbin'),
-        pytest.lazy_fixture('httpbin'),
+        'httpbin',
+        'remote_httpbin',
+        'httpbin',
         True,
     ),
 ])
-def test_saved_session_cookies_on_redirect(tmp_path, initial_domain, first_request_domain, second_request_domain, expect_cookies):
+def test_saved_session_cookies_on_redirect(
+        tmp_path, initial_domain, first_request_domain, second_request_domain, expect_cookies, request):
+    initial_domain = request.getfixturevalue(initial_domain)
+    first_request_domain = request.getfixturevalue(first_request_domain)
+    second_request_domain = request.getfixturevalue(second_request_domain)
     http(
         '--session',
         str(tmp_path / 'session.json'),
@@ -216,7 +209,7 @@ def test_saved_session_cookies_on_redirect(tmp_path, initial_domain, first_reque
         str(tmp_path / 'session.json'),
         '--follow',
         first_request_domain + '/redirect-to',
-        f'url=={_stringify(second_request_domain)}/cookies'
+        f'url=={second_request_domain}/cookies'
     )
     if expect_cookies:
         expected_data = {'cookies': {'a': 'b'}}
--- a/tests/test_sessions.py
+++ b/tests/test_sessions.py
@@ -821,16 +821,17 @@ def test_session_multiple_headers_with_same_name(basic_session, httpbin):
     'server, expected_cookies',
     [
         (
-            pytest.lazy_fixture('localhost_http_server'),
+            'localhost_http_server',
             {'secure_cookie': 'foo', 'insecure_cookie': 'bar'}
         ),
         (
-            pytest.lazy_fixture('remote_httpbin'),
+            'remote_httpbin',
             {'insecure_cookie': 'bar'}
         )
     ]
 )
-def test_secure_cookies_on_localhost(mock_env, tmp_path, server, expected_cookies):
+def test_secure_cookies_on_localhost(mock_env, tmp_path, server, expected_cookies, request):
+    server = request.getfixturevalue(server)
     session_path = tmp_path / 'session.json'
     http(
         '--session', str(session_path),
--- a/tests/test_update_warnings.py
+++ b/tests/test_update_warnings.py
@@ -132,10 +132,10 @@ def test_check_updates_first_invocation(
 
 
 @pytest.mark.parametrize(
-    'should_issue_warning, build_channel',
+    ['should_issue_warning', 'build_channel'],
     [
-        (False, pytest.lazy_fixture('lower_build_channel')),
-        (True, pytest.lazy_fixture('higher_build_channel')),
+        (False, 'lower_build_channel'),
+        (True, 'higher_build_channel'),
     ],
 )
 def test_check_updates_first_time_after_data_fetch(
@@ -145,7 +145,9 @@ def test_check_updates_first_time_after_data_fetch(
     static_fetch_data,
     should_issue_warning,
     build_channel,
+    request,
 ):
+    request.getfixturevalue(build_channel)
     http('fetch_updates', '--daemon', env=with_warnings)
     r = http(httpbin + '/get', env=with_warnings)
 
@@ -176,14 +178,15 @@ def test_cli_check_updates(
 
 
 @pytest.mark.parametrize(
-    "build_channel", [
-        pytest.lazy_fixture("lower_build_channel"),
-        pytest.lazy_fixture("unknown_build_channel")
+    'build_channel', [
+        'lower_build_channel',
+        'unknown_build_channel',
     ]
 )
 def test_cli_check_updates_not_shown(
-    static_fetch_data, build_channel
+    static_fetch_data, build_channel, request
 ):
+    request.getfixturevalue(build_channel)
     r = httpie('cli', 'check-updates')
     assert r.exit_status == ExitStatus.SUCCESS
     assert not check_update_warnings(r)
