Hacktoberfest 2026: những issue maintainer đã đánh dấu cho tháng Mười, đang mở và phù hợp người mới. Xem issue Hacktoberfest

Replace unmaintained httpretty with mocket in the test suite

Đang mở
#833 0 bình luận 0 reaction 1 người được giao Xem trên GitHub

@mconflitti-pbc đang làm issue này rồi.

Từ ngày 7/8/2026.

Đánh giá

Issue này chưa được đánh giá.

Mô tả

Problem

Adding Python 3.14 support required a shim in conftest.py, because httpretty
fails on 3.14. This ticket proposes removing that shim by replacing httpretty
with a maintained equivalent.

Root cause

CPython 3.14 makes functools.partial objects method descriptors. A
FutureWarning was added in 3.13 (python/cpython#121027) and the behavior
changed in 3.14 (python/cpython#125983):

3.13: class C: m = partial(f, "PRE")  ->  C().m("SOCK") == ("PRE", "SOCK")  + FutureWarning
3.14: class C: m = partial(f, "PRE")  ->  C().m("SOCK") == ("PRE", <C obj>, "SOCK")

httpretty mocks TLS with this class-attribute assignment
(httpretty/core.py:1875):

ssl.SSLContext.wrap_socket = partial(fake_wrap_socket, old_ssl_wrap_socket)

On 3.14 the partial now binds, so the SSLContext arrives as the first
positional argument and httpretty mistakes it for the socket. Every HTTPS test
fails with:

AttributeError: 'SSLContext' object has no attribute 'sendall'

That is 3 tests today (the shinyapps.io paths in tests/test_main.py), but it
affects the whole TLS mock, which covers over 100 https:// registrations.

Upstream will probably not fix this
  • gabrielfalcao/HTTPretty#488 ("Support Python 3.14 partial() changes", opened
    2026-04-10) fixes it with staticmethod(partial(...)), but is unmerged.
  • httpretty 1.1.4 was released 2021-08-16. The last merged PR was 2022-10-11.
    There are 129 open issues, with PRs from 2023 and 2024 still open. The PyPI
    classifiers stop at Python 3.9.
  • Even a released upstream fix may not help us: staticmethod objects only
    became callable in Python 3.10, so #488's two module-level assignments
    (ssl.wrap_socket and requests_urllib3_connection.ssl_wrap_socket) would
    break on our 3.8 and 3.9 floor if anything called them.
Current workaround

conftest.py wraps httpretty.core.fake_wrap_socket and drops the leading
SSLContext. It is 4 lines and verified on 3.8, 3.13 and 3.14, and it stays
correct if #488 lands (the isinstance check simply stops matching).

Its downside: it reads a private function at import time. If httpretty renames
fake_wrap_socket, the failure is not one red test. Collection fails and the
entire suite stops on every Python version and OS.

Proposal: migrate to mocket

mocket 3.14.3 (uploaded
2026-07-13) is actively maintained, declares requires-python = ">=3.8", and
classifies 3.8 through 3.14, so it covers our full support range. Its major
version tracks the newest supported Python.

Verified against rsconnect's real http.client HTTPS path on 3.14 using
mocket.plugins.httpretty: status 200 and the JSON body came back intact with
strict_mode=True.

Note the honest limits:

  • mocket monkeypatches socket and ssl too. This buys a maintainer, not real
    TLS. Only a real local server (for example pytest-httpserver) would give
    real TLS, at the cost of rewriting all registrations and adding certificate
    plumbing.
  • responses and requests-mock are not options. rsconnect uses http.client
    directly (rsconnect/http_support.py), not requests.
Migration scope

6 test files: test_api.py, test_main.py, test_main_content.py,
test_main_environment.py, test_main_integration.py,
test_main_system_caches.py.

Item Count Notes
@httpretty.activate(verbose=True, allow_net_connect=False) 81 becomes @mocketize(strict_mode=True); verbose has no equivalent
httpretty.register_uri(...) 165 body, adding_headers and status confirmed working
latest_requests() / last_request() 17 attributes in mocket, not calls; verify .method, .path, .body parity
has_request 1 no equivalent; needs a manual replacement

Acceptance criteria

  • The fake_wrap_socket shim is deleted from conftest.py.
  • The suite is green on Python 3.8 through 3.14.
  • Test count and skip count are unchanged (768 passed, 12 skipped today).
  • Line coverage does not regress (83.0% today).

Context

Closed #528 is where this repo deliberately adopted httpretty over
mock_connect, so that trade-off is worth re-reading before changing direction.

Separate pre-existing gap, unchanged by any of the above and out of scope here:
the custom-CA branch (ssl.create_default_context(cadata=...)) and the
--insecure branch (ssl._create_unverified_context()) in
rsconnect/http_support.py are not covered by the httpretty tests on any
Python version.

Ngôn ngữ chính
Python
Star
38
Fork
28
Merge trung bình
10 giờ 32 phút
Pull request đã merge (30 ngày)
7

Chuẩn bị môi trường

Bắt đầu từ đâu

  1. Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
  2. Bình luận trên issue rằng bạn sẽ nhận — tránh hai người làm cùng một việc.
  3. Fork repository và làm thay đổi trên một nhánh.
  4. Mở pull request có tham chiếu số hiệu của issue.

Issue khác của posit-dev/rsconnect-python

Tất cả issue của posit-dev/rsconnect-python

Issue tương tự

Thêm issue về Python

Nhận issue mới trong hộp thư của bạn

Bản tóm tắt ngắn những issue GitHub phù hợp với người mới.