Replace unmaintained httpretty with mocket in the test suite
@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 withstaticmethod(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:
staticmethodobjects only
became callable in Python 3.10, so #488's two module-level assignments
(ssl.wrap_socketandrequests_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
socketandssltoo. This buys a maintainer, not real
TLS. Only a real local server (for examplepytest-httpserver) would give
real TLS, at the cost of rewriting all registrations and adding certificate
plumbing. responsesandrequests-mockare not options. rsconnect useshttp.client
directly (rsconnect/http_support.py), notrequests.
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_socketshim is deleted fromconftest.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
- Không có Dockerfile hay tệp Docker Compose
- Có mẫu pull request
- Đọc hướng dẫn đóng góp
Bắt đầu từ đâu
- Đọc hết issue, rồi đọc hướng dẫn đóng góp của dự án.
- 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.
- Fork repository và làm thay đổi trên một nhánh.
- Mở pull request có tham chiếu số hiệu của issue.
Issue khác của posit-dev/rsconnect-python
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
posit-dev/rsconnect-python#786 · 1 reaction ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 62/100
posit-dev/rsconnect-python#543 · 2 bình luận ·
-
Độ khó 1/5 Dưới một giờ Mức phù hợp với người mới 72/100
posit-dev/rsconnect-python#513 ·
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 65/100
posit-dev/rsconnect-python#178 ·
-
bug
Độ khó 4/5 3-5 ngày Mức phù hợp với người mới 50/100
posit-dev/rsconnect-python#857 ·
Tất cả issue của posit-dev/rsconnect-python
Issue tương tự
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
LearningCircuit/local-deep-research#7206 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
[TASK] Document technology stackĐang mở
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 68/100
chingu-voyages/V62-tier3-team-33#285 ·
Maintainer thường phản hồi trong vòng 1 ngày
-
Proxy drops log notifications from backends that don't send FastMCP's msg/extra dictCó thể đã có người làm @asasemahmed đã nhận hôm nay. Đang mởbug server
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày
-
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 82/100
Maintainer thường phản hồi trong vòng 1 ngày
-
[Bug]: Bedrock request metadata forwarding does not work for /embeddingsCó thể đã có người làm Có pull request liên kết đang mở hoặc đã được merge. Đang mởbug llm translation
Độ khó 2/5 1-3 giờ Mức phù hợp với người mới 78/100
Maintainer thường phản hồi trong vòng 1 ngày