Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/main.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ jobs:
runs-on: ubuntu-20.04
strategy:
matrix:
python-version: ['3.7', '3.8', '3.9', '3.10', '3.11', 'pypy3.10']
python-version: ['3.8', '3.9', '3.10', '3.11', '3.12', 'pypy3.10']

steps:
- uses: actions/checkout@v3
Expand Down
4 changes: 2 additions & 2 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
repos:
- repo: https://github.com/pre-commit/pre-commit-hooks
rev: v4.4.0
rev: v4.5.0
hooks:
- id: check-yaml
args: ['--unsafe']
Expand All @@ -23,6 +23,6 @@ repos:
- id: isort

- repo: https://github.com/psf/black
rev: 23.3.0
rev: 23.10.0
hooks:
- id: black
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ services-down:

test-python:
@echo "Running Python tests"
wait-for-it --service httpbin.local:443 --service localhost:6379 --timeout 5 -- python run_tests.py || exit 1
wait-for-it --service httpbin.local:443 --service localhost:6379 --timeout 5 -- pytest tests/ || exit 1
@echo ""

lint-python:
Expand Down
2 changes: 1 addition & 1 deletion mocket/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@

__all__ = ("async_mocketize", "mocketize", "Mocket", "MocketEntry", "Mocketizer")

__version__ = "3.11.1"
__version__ = "3.12.0"
11 changes: 6 additions & 5 deletions mocket/mocket.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,9 @@
true_gethostname = socket.gethostname
true_getaddrinfo = socket.getaddrinfo
true_socketpair = socket.socketpair
true_ssl_wrap_socket = ssl.wrap_socket
true_ssl_wrap_socket = getattr(
ssl, "wrap_socket", None
) # in Py3.12 it's only under SSLContext
true_ssl_socket = ssl.SSLSocket
true_ssl_context = ssl.SSLContext
true_inet_pton = socket.inet_pton
Expand Down Expand Up @@ -538,7 +540,8 @@ def disable():
socket.gethostbyname = socket.__dict__["gethostbyname"] = true_gethostbyname
socket.getaddrinfo = socket.__dict__["getaddrinfo"] = true_getaddrinfo
socket.socketpair = socket.__dict__["socketpair"] = true_socketpair
ssl.wrap_socket = ssl.__dict__["wrap_socket"] = true_ssl_wrap_socket
if true_ssl_wrap_socket:
ssl.wrap_socket = ssl.__dict__["wrap_socket"] = true_ssl_wrap_socket
ssl.SSLContext = ssl.__dict__["SSLContext"] = true_ssl_context
socket.inet_pton = socket.__dict__["inet_pton"] = true_inet_pton
urllib3.util.ssl_.wrap_socket = urllib3.util.ssl_.__dict__[
Expand Down Expand Up @@ -602,9 +605,7 @@ def __init__(self, location, responses):
else:
self.responses = []
for r in responses:
if isinstance(r, BaseException):
pass
elif not getattr(r, "data", False):
if not isinstance(r, BaseException) and not getattr(r, "data", False):
if isinstance(r, text_type):
r = encode_to_bytes(r)
r = self.response_cls(r)
Expand Down
13 changes: 6 additions & 7 deletions mocket/mockhttp.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@

STATUS = {k: v[0] for k, v in BaseHTTPRequestHandler.responses.items()}
CRLF = "\r\n"
ASCII = "ascii"


class Protocol:
Expand All @@ -25,7 +26,7 @@ def __init__(self):
self.headers = {}

def on_header(self, name: bytes, value: bytes):
self.headers[name.decode("ascii")] = value.decode("ascii")
self.headers[name.decode(ASCII)] = value.decode(ASCII)

def on_body(self, body: bytes):
try:
Expand All @@ -34,7 +35,7 @@ def on_body(self, body: bytes):
self.body = body

def on_url(self, url: bytes):
self.url = url.decode("ascii")
self.url = url.decode(ASCII)


class Request:
Expand All @@ -51,7 +52,7 @@ def add_data(self, data):

@property
def method(self):
return self._parser.get_method().decode("ascii")
return self._parser.get_method().decode(ASCII)

@property
def path(self):
Expand Down Expand Up @@ -110,7 +111,7 @@ def get_protocol_data(self, str_format_fun_name="capitalize"):
for k, v in self.headers.items()
)
)
return "{0}\r\n{1}\r\n\r\n".format(status_line, header_lines).encode("utf-8")
return "{0}\r\n{1}\r\n\r\n".format(status_line, header_lines).encode(ENCODING)

def set_base_headers(self):
self.headers = {
Expand All @@ -121,7 +122,7 @@ def set_base_headers(self):
"Content-Length": str(len(self.body)),
}
if not self.is_file_object:
self.headers["Content-Type"] = "text/plain; charset=utf-8"
self.headers["Content-Type"] = f"text/plain; charset={ENCODING}"
elif self.magic:
self.headers["Content-Type"] = do_the_magic(self.magic, self.body)

Expand Down Expand Up @@ -237,7 +238,6 @@ def _parse_requestline(line):

@classmethod
def register(cls, method, uri, *responses, **config):

if "body" in config or "status" in config:
raise AttributeError("Did you mean `Entry.single_register(...)`?")

Expand All @@ -263,7 +263,6 @@ def single_register(
match_querystring=True,
exception=None,
):

response = (
exception
if exception
Expand Down
11 changes: 5 additions & 6 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,11 @@ classifiers = [
"Development Status :: 6 - Mature",
"Intended Audience :: Developers",
"Operating System :: OS Independent",
"Programming Language :: Python :: 3.7",
"Programming Language :: Python :: 3.8",
"Programming Language :: Python :: 3.9",
"Programming Language :: Python :: 3.10",
"Programming Language :: Python :: 3.11",
"Programming Language :: Python :: 3.12",
"Programming Language :: Python :: Implementation :: CPython",
"Programming Language :: Python :: Implementation :: PyPy",
"Topic :: Software Development",
Expand All @@ -45,9 +45,9 @@ test = [
"gevent",
"sure",
"pook",
"flake8",
"flake8>5",
"xxhash",
"aiohttp",
"aiohttp;python_version<'3.12'",
"httpx",
"pipfile",
"build",
Expand All @@ -56,8 +56,8 @@ test = [
"wait-for-it",
]
speedups = [
'xxhash;platform_python_implementation=="CPython"',
'xxhash-cffi;platform_python_implementation=="PyPy"',
"xxhash;platform_python_implementation=='CPython'",
"xxhash-cffi;platform_python_implementation=='PyPy'",
]
pook = [
"pook>=0.2.1",
Expand All @@ -71,7 +71,6 @@ ignore-vcs = true

[tool.hatch.build.targets.sdist]
include = [
"run_tests.py",
"README.rst",
"LICENSE",
"pyproject.toml",
Expand Down
27 changes: 0 additions & 27 deletions run_tests.py

This file was deleted.

29 changes: 16 additions & 13 deletions tests/main/test_https.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,11 @@
from mocket.mockhttp import Entry


@pytest.fixture
def url_to_mock():
return "https://httpbin.org/ip"


@pytest.fixture
def response():
return {
Expand Down Expand Up @@ -39,13 +44,11 @@ def test_json(response):


@pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)')
def test_truesendall_with_recording_https():
def test_truesendall_with_recording_https(url_to_mock):
with tempfile.TemporaryDirectory() as temp_dir:
with Mocketizer(truesocket_recording_dir=temp_dir):
url = "https://mockbin.org/ip"

requests.get(url, headers={"Accept": "application/json"})
resp = requests.get(url, headers={"Accept": "application/json"})
requests.get(url_to_mock, headers={"Accept": "application/json"})
resp = requests.get(url_to_mock, headers={"Accept": "application/json"})
assert resp.status_code == 200

dump_filename = os.path.join(
Expand All @@ -55,25 +58,25 @@ def test_truesendall_with_recording_https():
with io.open(dump_filename) as f:
responses = json.load(f)

assert len(responses["mockbin.org"]["443"].keys()) == 1
assert len(responses["httpbin.org"]["443"].keys()) == 1


@pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)')
def test_truesendall_after_mocket_session():
def test_truesendall_after_mocket_session(url_to_mock):
Mocket.enable()
Mocket.disable()

url = "https://mockbin.org/ip"
resp = requests.get(url)
resp = requests.get(url_to_mock)
assert resp.status_code == 200


@pytest.mark.skipif('os.getenv("SKIP_TRUE_HTTP", False)')
def test_real_request_session():
def test_real_request_session(url_to_mock):
session = requests.Session()

url1 = "https://mockbin.org/ip"
url2 = "http://httpbin.org/headers"
url_to_compare = "http://httpbin.org/headers"

with Mocketizer():
assert len(session.get(url1).content) < len(session.get(url2).content)
assert len(session.get(url_to_mock).content) < len(
session.get(url_to_compare).content
)
5 changes: 1 addition & 4 deletions tests/main/test_httpx.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import json

import aiohttp
import httpx
import pytest
from asgiref.sync import async_to_sync
Expand All @@ -9,11 +8,9 @@
from mocket.mockhttp import Entry
from mocket.plugins.httpretty import httprettified, httpretty

timeout = aiohttp.ClientTimeout(total=3)


@mocketize
@pytest.mark.parametrize("url", ["http://httpbin.org/ip", "https://httpbin.org/ip"])
@pytest.mark.parametrize("url", ("http://httpbin.org/ip", "https://httpbin.org/ip"))
def test_body(url):
body = "asd" * 100
Entry.single_register(Entry.GET, url, body=body, status=404)
Expand Down
Loading