Browse Source

Intermediate changes
commit_hash:a2b7c09c50267438f198d0f36dc6d40678894b70

robot-piglet 1 month ago
parent
commit
77d9db7a95

+ 133 - 114
contrib/python/responses/py3/.dist-info/METADATA

@@ -1,6 +1,6 @@
 Metadata-Version: 2.1
 Name: responses
-Version: 0.25.3
+Version: 0.25.5
 Summary: A utility library for mocking out the `requests` Python library.
 Home-page: https://github.com/getsentry/responses
 Author: David Cramer
@@ -24,21 +24,21 @@ Classifier: Topic :: Software Development
 Requires-Python: >=3.8
 Description-Content-Type: text/x-rst
 License-File: LICENSE
-Requires-Dist: requests <3.0,>=2.30.0
-Requires-Dist: urllib3 <3.0,>=1.25.10
+Requires-Dist: requests<3.0,>=2.30.0
+Requires-Dist: urllib3<3.0,>=1.25.10
 Requires-Dist: pyyaml
 Provides-Extra: tests
-Requires-Dist: pytest >=7.0.0 ; extra == 'tests'
-Requires-Dist: coverage >=6.0.0 ; extra == 'tests'
-Requires-Dist: pytest-cov ; extra == 'tests'
-Requires-Dist: pytest-asyncio ; extra == 'tests'
-Requires-Dist: pytest-httpserver ; extra == 'tests'
-Requires-Dist: flake8 ; extra == 'tests'
-Requires-Dist: types-PyYAML ; extra == 'tests'
-Requires-Dist: types-requests ; extra == 'tests'
-Requires-Dist: mypy ; extra == 'tests'
-Requires-Dist: tomli-w ; extra == 'tests'
-Requires-Dist: tomli ; (python_version < "3.11") and extra == 'tests'
+Requires-Dist: pytest>=7.0.0; extra == "tests"
+Requires-Dist: coverage>=6.0.0; extra == "tests"
+Requires-Dist: pytest-cov; extra == "tests"
+Requires-Dist: pytest-asyncio; extra == "tests"
+Requires-Dist: pytest-httpserver; extra == "tests"
+Requires-Dist: flake8; extra == "tests"
+Requires-Dist: types-PyYAML; extra == "tests"
+Requires-Dist: types-requests; extra == "tests"
+Requires-Dist: mypy; extra == "tests"
+Requires-Dist: tomli-w; extra == "tests"
+Requires-Dist: tomli; python_version < "3.11" and extra == "tests"
 
 Responses
 =========
@@ -104,100 +104,6 @@ Please ensure to update your code according to the guidance.
      - Use ``responses.mock.assert_all_requests_are_fired``,
        ``responses.mock.passthru_prefixes``, ``responses.mock.target`` instead.
 
-BETA Features
--------------
-Below you can find a list of BETA features. Although we will try to keep the API backwards compatible
-with released version, we reserve the right to change these APIs before they are considered stable. Please share your feedback via
-`GitHub Issues <https://github.com/getsentry/responses/issues>`_.
-
-Record Responses to files
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can perform real requests to the server and ``responses`` will automatically record the output to the
-file. Recorded data is stored in `YAML <https://yaml.org>`_ format.
-
-Apply ``@responses._recorder.record(file_path="out.yaml")`` decorator to any function where you perform
-requests to record responses to ``out.yaml`` file.
-
-Following code
-
-.. code-block:: python
-
-    import requests
-    from responses import _recorder
-
-
-    def another():
-        rsp = requests.get("https://httpstat.us/500")
-        rsp = requests.get("https://httpstat.us/202")
-
-
-    @_recorder.record(file_path="out.yaml")
-    def test_recorder():
-        rsp = requests.get("https://httpstat.us/404")
-        rsp = requests.get("https://httpbin.org/status/wrong")
-        another()
-
-will produce next output:
-
-.. code-block:: yaml
-
-    responses:
-    - response:
-        auto_calculate_content_length: false
-        body: 404 Not Found
-        content_type: text/plain
-        method: GET
-        status: 404
-        url: https://httpstat.us/404
-    - response:
-        auto_calculate_content_length: false
-        body: Invalid status code
-        content_type: text/plain
-        method: GET
-        status: 400
-        url: https://httpbin.org/status/wrong
-    - response:
-        auto_calculate_content_length: false
-        body: 500 Internal Server Error
-        content_type: text/plain
-        method: GET
-        status: 500
-        url: https://httpstat.us/500
-    - response:
-        auto_calculate_content_length: false
-        body: 202 Accepted
-        content_type: text/plain
-        method: GET
-        status: 202
-        url: https://httpstat.us/202
-
-
-Replay responses (populate registry) from files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can populate your active registry from a ``yaml`` file with recorded responses.
-(See `Record Responses to files`_ to understand how to obtain a file).
-To do that you need to execute ``responses._add_from_file(file_path="out.yaml")`` within
-an activated decorator or a context manager.
-
-The following code example registers a ``patch`` response, then all responses present in
-``out.yaml`` file and a ``post`` response at the end.
-
-.. code-block:: python
-
-    import responses
-
-
-    @responses.activate
-    def run():
-        responses.patch("http://httpbin.org")
-        responses._add_from_file(file_path="out.yaml")
-        responses.post("http://httpbin.org/form")
-
-
-    run()
-
 Basics
 ------
 
@@ -941,16 +847,19 @@ Integration with unit test frameworks
 Responses as a ``pytest`` fixture
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+Use the pytest-responses package to export ``responses`` as a pytest fixture.
+
+``pip install pytest-responses``
+
+You can then access it in a pytest script using:
+
 .. code-block:: python
 
-    @pytest.fixture
-    def mocked_responses():
-        with responses.RequestsMock() as rsps:
-            yield rsps
+    import pytest_responses
 
 
-    def test_api(mocked_responses):
-        mocked_responses.get(
+    def test_api(responses):
+        responses.get(
             "http://twitter.com/api/1/foobar",
             body="{}",
             status=200,
@@ -1441,6 +1350,116 @@ single thread to access it.
 
         await run()
 
+BETA Features
+-------------
+Below you can find a list of BETA features. Although we will try to keep the API backwards compatible
+with released version, we reserve the right to change these APIs before they are considered stable. Please share your feedback via
+`GitHub Issues <https://github.com/getsentry/responses/issues>`_.
+
+Record Responses to files
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can perform real requests to the server and ``responses`` will automatically record the output to the
+file. Recorded data is stored in `YAML <https://yaml.org>`_ format.
+
+Apply ``@responses._recorder.record(file_path="out.yaml")`` decorator to any function where you perform
+requests to record responses to ``out.yaml`` file.
+
+Following code
+
+.. code-block:: python
+
+    import requests
+    from responses import _recorder
+
+
+    def another():
+        rsp = requests.get("https://httpstat.us/500")
+        rsp = requests.get("https://httpstat.us/202")
+
+
+    @_recorder.record(file_path="out.yaml")
+    def test_recorder():
+        rsp = requests.get("https://httpstat.us/404")
+        rsp = requests.get("https://httpbin.org/status/wrong")
+        another()
+
+will produce next output:
+
+.. code-block:: yaml
+
+    responses:
+    - response:
+        auto_calculate_content_length: false
+        body: 404 Not Found
+        content_type: text/plain
+        method: GET
+        status: 404
+        url: https://httpstat.us/404
+    - response:
+        auto_calculate_content_length: false
+        body: Invalid status code
+        content_type: text/plain
+        method: GET
+        status: 400
+        url: https://httpbin.org/status/wrong
+    - response:
+        auto_calculate_content_length: false
+        body: 500 Internal Server Error
+        content_type: text/plain
+        method: GET
+        status: 500
+        url: https://httpstat.us/500
+    - response:
+        auto_calculate_content_length: false
+        body: 202 Accepted
+        content_type: text/plain
+        method: GET
+        status: 202
+        url: https://httpstat.us/202
+
+If you are in the REPL, you can also activete the recorder for all following responses:
+
+.. code-block:: python
+
+    import requests
+    from responses import _recorder
+
+    _recorder.recorder.start()
+
+    requests.get("https://httpstat.us/500")
+
+    _recorder.recorder.dump_to_file("out.yaml")
+
+    # you can stop or reset the recorder
+    _recorder.recorder.stop()
+    _recorder.recorder.reset()
+
+Replay responses (populate registry) from files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can populate your active registry from a ``yaml`` file with recorded responses.
+(See `Record Responses to files`_ to understand how to obtain a file).
+To do that you need to execute ``responses._add_from_file(file_path="out.yaml")`` within
+an activated decorator or a context manager.
+
+The following code example registers a ``patch`` response, then all responses present in
+``out.yaml`` file and a ``post`` response at the end.
+
+.. code-block:: python
+
+    import responses
+
+
+    @responses.activate
+    def run():
+        responses.patch("http://httpbin.org")
+        responses._add_from_file(file_path="out.yaml")
+        responses.post("http://httpbin.org/form")
+
+
+    run()
+
 
 Contributing
 ------------

+ 119 - 100
contrib/python/responses/py3/README.rst

@@ -62,100 +62,6 @@ Please ensure to update your code according to the guidance.
      - Use ``responses.mock.assert_all_requests_are_fired``,
        ``responses.mock.passthru_prefixes``, ``responses.mock.target`` instead.
 
-BETA Features
--------------
-Below you can find a list of BETA features. Although we will try to keep the API backwards compatible
-with released version, we reserve the right to change these APIs before they are considered stable. Please share your feedback via
-`GitHub Issues <https://github.com/getsentry/responses/issues>`_.
-
-Record Responses to files
-^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can perform real requests to the server and ``responses`` will automatically record the output to the
-file. Recorded data is stored in `YAML <https://yaml.org>`_ format.
-
-Apply ``@responses._recorder.record(file_path="out.yaml")`` decorator to any function where you perform
-requests to record responses to ``out.yaml`` file.
-
-Following code
-
-.. code-block:: python
-
-    import requests
-    from responses import _recorder
-
-
-    def another():
-        rsp = requests.get("https://httpstat.us/500")
-        rsp = requests.get("https://httpstat.us/202")
-
-
-    @_recorder.record(file_path="out.yaml")
-    def test_recorder():
-        rsp = requests.get("https://httpstat.us/404")
-        rsp = requests.get("https://httpbin.org/status/wrong")
-        another()
-
-will produce next output:
-
-.. code-block:: yaml
-
-    responses:
-    - response:
-        auto_calculate_content_length: false
-        body: 404 Not Found
-        content_type: text/plain
-        method: GET
-        status: 404
-        url: https://httpstat.us/404
-    - response:
-        auto_calculate_content_length: false
-        body: Invalid status code
-        content_type: text/plain
-        method: GET
-        status: 400
-        url: https://httpbin.org/status/wrong
-    - response:
-        auto_calculate_content_length: false
-        body: 500 Internal Server Error
-        content_type: text/plain
-        method: GET
-        status: 500
-        url: https://httpstat.us/500
-    - response:
-        auto_calculate_content_length: false
-        body: 202 Accepted
-        content_type: text/plain
-        method: GET
-        status: 202
-        url: https://httpstat.us/202
-
-
-Replay responses (populate registry) from files
-^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-
-You can populate your active registry from a ``yaml`` file with recorded responses.
-(See `Record Responses to files`_ to understand how to obtain a file).
-To do that you need to execute ``responses._add_from_file(file_path="out.yaml")`` within
-an activated decorator or a context manager.
-
-The following code example registers a ``patch`` response, then all responses present in
-``out.yaml`` file and a ``post`` response at the end.
-
-.. code-block:: python
-
-    import responses
-
-
-    @responses.activate
-    def run():
-        responses.patch("http://httpbin.org")
-        responses._add_from_file(file_path="out.yaml")
-        responses.post("http://httpbin.org/form")
-
-
-    run()
-
 Basics
 ------
 
@@ -899,16 +805,19 @@ Integration with unit test frameworks
 Responses as a ``pytest`` fixture
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
+Use the pytest-responses package to export ``responses`` as a pytest fixture.
+
+``pip install pytest-responses``
+
+You can then access it in a pytest script using:
+
 .. code-block:: python
 
-    @pytest.fixture
-    def mocked_responses():
-        with responses.RequestsMock() as rsps:
-            yield rsps
+    import pytest_responses
 
 
-    def test_api(mocked_responses):
-        mocked_responses.get(
+    def test_api(responses):
+        responses.get(
             "http://twitter.com/api/1/foobar",
             body="{}",
             status=200,
@@ -1399,6 +1308,116 @@ single thread to access it.
 
         await run()
 
+BETA Features
+-------------
+Below you can find a list of BETA features. Although we will try to keep the API backwards compatible
+with released version, we reserve the right to change these APIs before they are considered stable. Please share your feedback via
+`GitHub Issues <https://github.com/getsentry/responses/issues>`_.
+
+Record Responses to files
+^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can perform real requests to the server and ``responses`` will automatically record the output to the
+file. Recorded data is stored in `YAML <https://yaml.org>`_ format.
+
+Apply ``@responses._recorder.record(file_path="out.yaml")`` decorator to any function where you perform
+requests to record responses to ``out.yaml`` file.
+
+Following code
+
+.. code-block:: python
+
+    import requests
+    from responses import _recorder
+
+
+    def another():
+        rsp = requests.get("https://httpstat.us/500")
+        rsp = requests.get("https://httpstat.us/202")
+
+
+    @_recorder.record(file_path="out.yaml")
+    def test_recorder():
+        rsp = requests.get("https://httpstat.us/404")
+        rsp = requests.get("https://httpbin.org/status/wrong")
+        another()
+
+will produce next output:
+
+.. code-block:: yaml
+
+    responses:
+    - response:
+        auto_calculate_content_length: false
+        body: 404 Not Found
+        content_type: text/plain
+        method: GET
+        status: 404
+        url: https://httpstat.us/404
+    - response:
+        auto_calculate_content_length: false
+        body: Invalid status code
+        content_type: text/plain
+        method: GET
+        status: 400
+        url: https://httpbin.org/status/wrong
+    - response:
+        auto_calculate_content_length: false
+        body: 500 Internal Server Error
+        content_type: text/plain
+        method: GET
+        status: 500
+        url: https://httpstat.us/500
+    - response:
+        auto_calculate_content_length: false
+        body: 202 Accepted
+        content_type: text/plain
+        method: GET
+        status: 202
+        url: https://httpstat.us/202
+
+If you are in the REPL, you can also activete the recorder for all following responses:
+
+.. code-block:: python
+
+    import requests
+    from responses import _recorder
+
+    _recorder.recorder.start()
+
+    requests.get("https://httpstat.us/500")
+
+    _recorder.recorder.dump_to_file("out.yaml")
+
+    # you can stop or reset the recorder
+    _recorder.recorder.stop()
+    _recorder.recorder.reset()
+
+Replay responses (populate registry) from files
+^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+You can populate your active registry from a ``yaml`` file with recorded responses.
+(See `Record Responses to files`_ to understand how to obtain a file).
+To do that you need to execute ``responses._add_from_file(file_path="out.yaml")`` within
+an activated decorator or a context manager.
+
+The following code example registers a ``patch`` response, then all responses present in
+``out.yaml`` file and a ``post`` response at the end.
+
+.. code-block:: python
+
+    import responses
+
+
+    @responses.activate
+    def run():
+        responses.patch("http://httpbin.org")
+        responses._add_from_file(file_path="out.yaml")
+        responses.post("http://httpbin.org/form")
+
+
+    run()
+
 
 Contributing
 ------------

+ 23 - 1
contrib/python/responses/py3/responses/__init__.py

@@ -249,7 +249,7 @@ class CallList(Sequence[Any], Sized):
         ...
 
     @overload
-    def __getitem__(self, idx: slice) -> List[Call]:
+    def __getitem__(self, idx: "slice[int, int, Optional[int]]") -> List[Call]:
         ...
 
     def __getitem__(self, idx: Union[int, slice]) -> Union[Call, List[Call]]:
@@ -714,6 +714,11 @@ class RequestsMock:
     POST: Literal["POST"] = "POST"
     PUT: Literal["PUT"] = "PUT"
 
+    Response: Type[Response] = Response
+
+    # Make the `matchers` name available under a RequestsMock instance
+    from responses import matchers
+
     response_callback: Optional[Callable[[Any], Any]] = None
 
     def __init__(
@@ -1054,6 +1059,22 @@ class RequestsMock:
             params[key] = values
         return params
 
+    def _read_filelike_body(
+        self, body: Union[str, bytes, BufferedReader, None]
+    ) -> Union[str, bytes, None]:
+        # Requests/urllib support multiple types of body, including file-like objects.
+        # Read from the file if it's a file-like object to avoid storing a closed file
+        # in the call list and allow the user to compare against the data that was in the
+        # request.
+        # See GH #719
+        if isinstance(body, str) or isinstance(body, bytes) or body is None:
+            return body
+        # Based on
+        # https://github.com/urllib3/urllib3/blob/abbfbcb1dd274fc54b4f0a7785fd04d59b634195/src/urllib3/util/request.py#L220
+        if hasattr(body, "read") or isinstance(body, BufferedReader):
+            return body.read()
+        return body
+
     def _on_request(
         self,
         adapter: "HTTPAdapter",
@@ -1067,6 +1088,7 @@ class RequestsMock:
         request.params = self._parse_request_params(request.path_url)  # type: ignore[attr-defined]
         request.req_kwargs = kwargs  # type: ignore[attr-defined]
         request_url = str(request.url)
+        request.body = self._read_filelike_body(request.body)
 
         match, match_failed_reasons = self._find_match(request)
         resp_callback = self.response_callback

+ 6 - 2
contrib/python/responses/py3/responses/_recorder.py

@@ -9,6 +9,7 @@ if TYPE_CHECKING:  # pragma: no cover
     from typing import Callable
     from typing import Dict
     from typing import List
+    from typing import Optional
     from typing import Type
     from typing import Union
     from responses import FirstMatchRegistry
@@ -122,10 +123,13 @@ class Recorder(RequestsMock):
 
     def dump_to_file(
         self,
-        *,
         file_path: "Union[str, bytes, os.PathLike[Any]]",
-        registered: "List[BaseResponse]",
+        *,
+        registered: "Optional[List[BaseResponse]]" = None,
     ) -> None:
+        """Dump the recorded responses to a file."""
+        if registered is None:
+            registered = self.get_registry().registered
         with open(file_path, "w") as file:
             _dump(registered, file, yaml.dump)
 

+ 0 - 2
contrib/python/responses/py3/responses/py.typed

@@ -1,2 +0,0 @@
-# Marker file for PEP 561.  The mypy package uses inline types.
-# file must be here according to https://peps.python.org/pep-0561/#packaging-type-information

+ 1 - 2
contrib/python/responses/py3/ya.make

@@ -2,7 +2,7 @@
 
 PY3_LIBRARY()
 
-VERSION(0.25.3)
+VERSION(0.25.5)
 
 LICENSE(Apache-2.0)
 
@@ -26,7 +26,6 @@ RESOURCE_FILES(
     PREFIX contrib/python/responses/py3/
     .dist-info/METADATA
     .dist-info/top_level.txt
-    responses/py.typed
 )
 
 END()