Colin-b/pytest_httpx

Logging Error: "TypeError: %d format: a real number is required, not re.Pattern"

Closed this issue · 2 comments

I recently encountered this error in our tests, however it happens only occasionally and I haven't been able to reliably reproduce it. At first glance it seems like the status_code of the Response is somehow getting set to a re.Pattern object.

Hopefully someone more knowledge of pytest_httpx may recognize the problem; however in the meantime I'll continue to investigate and see if I can come up with a minimal reproducible example.

Here is the line that is (presumably) causing the error:

httpx_mock.add_response(re.compile(r"http://www.example.com.*"), text="wat")

Here is the full pytest traceback:

httpx_mock = <pytest_httpx._httpx_mock.HTTPXMock object at 0x7fd13a696710>, helpers = <bbot.core.helpers.helper.ConfigAwareHelper object at 0x7fd13161b340>

    @pytest.mark.asyncio
    async def test_web_http_compare(httpx_mock, helpers):
        httpx_mock.add_response(re.compile(r"http://www.example.com.*"), text="wat")
        compare_helper = helpers.http_compare("http://www.example.com")
>       await compare_helper.compare("http://www.example.com", headers={"asdf": "asdf"})

bbot/test/test_step_2/test_web.py:155: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
bbot/core/helpers/diff.py:137: in compare
    await self._baseline()
bbot/core/helpers/diff.py:28: in _baseline
    baseline_1 = await self.parent_helper.request(
bbot/core/helpers/web.py:99: in request
    response = await client.request(*args, **kwargs)
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/httpx/_client.py:1530: in request
    return await self.send(request, auth=auth, follow_redirects=follow_redirects)
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/httpx/_client.py:1617: in send
    response = await self._send_handling_auth(
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/httpx/_client.py:1645: in _send_handling_auth
    response = await self._send_handling_redirects(
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/httpx/_client.py:1682: in _send_handling_redirects
    response = await self._send_single_request(request)
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/httpx/_client.py:1729: in _send_single_request
    logger.info(
/usr/lib/python3.10/logging/__init__.py:1477: in info
    self._log(INFO, msg, args, **kwargs)
/usr/lib/python3.10/logging/__init__.py:1624: in _log
    self.handle(record)
/usr/lib/python3.10/logging/__init__.py:1634: in handle
    self.callHandlers(record)
/usr/lib/python3.10/logging/__init__.py:1696: in callHandlers
    hdlr.handle(record)
/usr/lib/python3.10/logging/__init__.py:968: in handle
    self.emit(record)
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/_pytest/logging.py:350: in emit
    super().emit(record)
/usr/lib/python3.10/logging/__init__.py:1108: in emit
    self.handleError(record)
/usr/lib/python3.10/logging/__init__.py:1100: in emit
    msg = self.format(record)
/usr/lib/python3.10/logging/__init__.py:943: in format
    return fmt.format(record)
../../../.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/_pytest/logging.py:114: in format
    return super().format(record)
/usr/lib/python3.10/logging/__init__.py:678: in format
    record.message = record.getMessage()
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <LogRecord: httpx, 20, /home/bls/.cache/pypoetry/virtualenvs/bbot-yxGMlPK5-py3.10/lib/python3.10/site-packages/httpx/_client.py, 1729, "HTTP Request: %s %s "%s %d %s"">

    def getMessage(self):
        """
        Return the message for this LogRecord.
    
        Return the message for this LogRecord after merging any user-supplied
        arguments with the message.
        """
        msg = str(self.msg)
        if self.args:
>           msg = msg % self.args
E           TypeError: %d format: a real number is required, not re.Pattern

/usr/lib/python3.10/logging/__init__.py:368: TypeError

Aaaaand closing for user error. Forgot url kwarg.

Indeed the first parameter is the status code, but in any case I should break compatibility at some point and force explicit argument naming, it would prevent such mistakes and force a single way of doing things