Add test case where idna is not installed
MODIFY
test/__init__.py
test/__init__.py
@@ -3,6 +3,7 @@ import logging
import os
import platform
import socket
+import sys
import warnings
import pytest
@@ -261,3 +262,53 @@ class LogRecorder:
def __exit__(self, exc_type, exc_value, traceback):
self.uninstall()
return False
+
+
+class ImportBlocker:
+ """
+ Block Imports
+
+ To be placed on ``sys.meta_path``. This ensures that the modules
+ specified cannot be imported, even if they are a builtin.
+ """
+
+ def __init__(self, *namestoblock):
+ self.namestoblock = namestoblock
+
+ def find_module(self, fullname, path=None):
+ if fullname in self.namestoblock:
+ return self
+ return None
+
+ def load_module(self, fullname):
+ raise ImportError(f"import of {fullname} is blocked")
+
+
+class ModuleStash:
+ """
+ Stashes away previously imported modules
+
+ If we reimport a module the data from coverage is lost, so we reuse the old
+ modules
+ """
+
+ def __init__(self, namespace, modules=sys.modules):
+ self.namespace = namespace
+ self.modules = modules
+ self._data = {}
+
+ def stash(self):
+ self._data[self.namespace] = self.modules.pop(self.namespace, None)
+
+ for module in list(self.modules.keys()):
+ if module.startswith(self.namespace + "."):
+ self._data[module] = self.modules.pop(module)
+
+ def pop(self):
+ self.modules.pop(self.namespace, None)
+
+ for module in list(self.modules.keys()):
+ if module.startswith(self.namespace + "."):
+ self.modules.pop(module)
+
+ self.modules.update(self._data)

MODIFY
test/test_no_ssl.py
test/test_no_ssl.py
@@ -6,60 +6,10 @@ Test what happens if Python was built without SSL
"""
import sys
+from test import ImportBlocker, ModuleStash
import pytest
-
-class ImportBlocker:
- """
- Block Imports
-
- To be placed on ``sys.meta_path``. This ensures that the modules
- specified cannot be imported, even if they are a builtin.
- """
-
- def __init__(self, *namestoblock):
- self.namestoblock = namestoblock
-
- def find_module(self, fullname, path=None):
- if fullname in self.namestoblock:
- return self
- return None
-
- def load_module(self, fullname):
- raise ImportError(f"import of {fullname} is blocked")
-
-
-class ModuleStash:
- """
- Stashes away previously imported modules
-
- If we reimport a module the data from coverage is lost, so we reuse the old
- modules
- """
-
- def __init__(self, namespace, modules=sys.modules):
- self.namespace = namespace
- self.modules = modules
- self._data = {}
-
- def stash(self):
- self._data[self.namespace] = self.modules.pop(self.namespace, None)
-
- for module in list(self.modules.keys()):
- if module.startswith(self.namespace + "."):
- self._data[module] = self.modules.pop(module)
-
- def pop(self):
- self.modules.pop(self.namespace, None)
-
- for module in list(self.modules.keys()):
- if module.startswith(self.namespace + "."):
- self.modules.pop(module)
-
- self.modules.update(self._data)
-
-
ssl_blocker = ImportBlocker("ssl", "_ssl")
module_stash = ModuleStash("urllib3")

MODIFY
test/test_util.py
test/test_util.py
@@ -2,9 +2,10 @@ import io
import logging
import socket
import ssl
+import sys
import warnings
from itertools import chain
-from test import notBrotli, onlyBrotli
+from test import ImportBlocker, ModuleStash, notBrotli, onlyBrotli
from unittest.mock import Mock, patch
import pytest
@@ -889,3 +890,25 @@ class TestUtilSSL:
context, warn = self._wrap_socket_and_mock_warn(sock, None)
context.wrap_socket.assert_called_once_with(sock, server_hostname=None)
warn.assert_not_called()
+
+
+idna_blocker = ImportBlocker("idna")
+module_stash = ModuleStash("urllib3")
+
+
+class TestUtilWithoutIdna:
+ @classmethod
+ def setup_class(cls):
+ sys.modules.pop("idna", None)
+
+ module_stash.stash()
+ sys.meta_path.insert(0, idna_blocker)
+
+ def teardown_class(cls):
+ sys.meta_path.remove(idna_blocker)
+ module_stash.pop()
+
+ def test_parse_url_without_idna(self):
+ url = "http://\uD7FF.com"
+ with pytest.raises(LocationParseError, match=f"Failed to parse: {url}"):
+ parse_url(url)

Add test case where idna is not installed