Skip to content

support for blocking of socket.create_connection #432

@stanislavlevin

Description

@stanislavlevin

Consider the test example (test.py):

from urllib.request import urlopen
import pytest


@pytest.mark.disable_socket
def test_1():
    assert urlopen('https://http.codes/200').getcode() == 200

Run pytest over it as:

$ python3 -m pytest test.py

In network-isolated environments the test fails with urllib.error.URLError: <urlopen error [Errno -3] Temporary failure in name resolution>:

============================= test session starts ==============================
platform linux -- Python 3.12.11, pytest-8.3.5, pluggy-1.6.0
rootdir: /usr/src/RPM/BUILD
plugins: subket-0.8.1
collected 1 item

test.py F                                                                [100%]

=================================== FAILURES ===================================
____________________________________ test_1 ____________________________________
self = <urllib.request.HTTPSHandler object at 0x7fc43d1d7e30>
http_class = <class 'http.client.HTTPSConnection'>
req = <urllib.request.Request object at 0x7fc43d1bccb0>
http_conn_args = {'context': <ssl.SSLContext object at 0x7fc43d1ee350>}
host = 'http.codes', h = <http.client.HTTPSConnection object at 0x7fc43d1bdf70>
headers = {'Connection': 'close', 'Host': 'http.codes', 'User-Agent': 'Python-urllib/3.12'}

...

            try:
>               h.request(req.get_method(), req.selector, req.data, headers,
                          encode_chunked=req.has_header('Transfer-encoding'))

/usr/lib64/python3.12/urllib/request.py:1344:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib64/python3.12/http/client.py:1338: in request
    self._send_request(method, url, body, headers, encode_chunked)
/usr/lib64/python3.12/http/client.py:1384: in _send_request
    self.endheaders(body, encode_chunked=encode_chunked)
/usr/lib64/python3.12/http/client.py:1333: in endheaders
    self._send_output(message_body, encode_chunked=encode_chunked)
/usr/lib64/python3.12/http/client.py:1093: in _send_output
    self.send(msg)
/usr/lib64/python3.12/http/client.py:1037: in send
    self.connect()
/usr/lib64/python3.12/http/client.py:1472: in connect
    super().connect()
/usr/lib64/python3.12/http/client.py:1003: in connect
    self.sock = self._create_connection(
/usr/lib64/python3.12/socket.py:841: in create_connection
    for res in getaddrinfo(host, port, 0, SOCK_STREAM):
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

host = 'http.codes', port = 443, family = 0, type = <SocketKind.SOCK_STREAM: 1>
proto = 0, flags = 0

    def getaddrinfo(host, port, family=0, type=0, proto=0, flags=0):
        """Resolve host and port into list of address info entries.

        Translate the host/port argument into a sequence of 5-tuples that contain
        all the necessary arguments for creating a socket connected to that service.
        host is a domain name, a string representation of an IPv4/v6 address or
        None. port is a string service name such as 'http', a numeric port number or
        None. By passing None as the value of host and port, you can pass NULL to
        the underlying C API.

        The family, type and proto arguments can be optionally specified in order to
        narrow the list of addresses returned. Passing zero as a value for each of
        these arguments selects the full range of results.
        """
        # We override this function since we want to translate the numeric family
        # and socket type values to enum constants.
        addrlist = []
>       for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
E       socket.gaierror: [Errno -3] Temporary failure in name resolution

/usr/lib64/python3.12/socket.py:978: gaierror

...

Expected result:
Failure with pytest_socket._core.SocketBlockedError: A test tried to use socket.socket

Is it expected that pytest-socket doesn't block socket.create_connection (function)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    staleMarked stale due to inactivity

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions