Skip to content

Conversation

@julianz-
Copy link
Contributor

@julianz- julianz- commented Dec 8, 2025

We replace the MakeFile factory function with direct class instantiation. The MakeFile function now emits a DeprecationWarning and will be removed in a future release.

The makefile() methods in the SSL adapters and the base Adapter class are also deprecated. These methods are no longer necessary because the adapters now return wrapped sockets that work directly with StreamReader and StreamWriter.

The pyOpenSSL adapter wraps its SSL.Connection objects in a new TLSSocket class. TLSSocket implements a socket interface that handles OpenSSL-specific errors (WantReadError, WantWriteError, etc.). This allows plain StreamReader and StreamWriter to work transparently with pyOpenSSL connections.

Although its makefile is no longer used, the builtin SSL adapter continues to work essentially as before - Python's ssl.SSLSocket already provided a compatible interface that works directly with StreamReader and StreamWriter.

This change eliminates the abstraction leak where HTTPConnection needed to call upon an SSL adapter custom makefile() method. Now, HTTPConnection simply creates StreamReader and StreamWriter instances with whatever socket it receives, whether it's a plain socket, ssl.SSLSocket, or TLSSocket.

This is a step towards unifying the two SSL adapters while simplifying higher-level logic.

@codecov
Copy link

codecov bot commented Dec 8, 2025

Codecov Report

❌ Patch coverage is 96.98630% with 11 lines in your changes missing coverage. Please review.
✅ Project coverage is 79.49%. Comparing base (c5d5175) to head (fb4f826).
⚠️ Report is 1 commits behind head on main.
✅ All tests successful. No failed tests found.

Additional details and impacted files
@@            Coverage Diff             @@
##             main     #805      +/-   ##
==========================================
+ Coverage   78.19%   79.49%   +1.30%     
==========================================
  Files          41       42       +1     
  Lines        4788     5102     +314     
  Branches      547      566      +19     
==========================================
+ Hits         3744     4056     +312     
- Misses        905      907       +2     
  Partials      139      139              

@julianz- julianz- force-pushed the remove_makefile_minimal branch 2 times, most recently from dad25d2 to d6a334a Compare December 8, 2025 03:33
@julianz- julianz- force-pushed the remove_makefile_minimal branch 2 times, most recently from 6407321 to 58938f6 Compare December 8, 2025 03:47
raise


def _make_file_object(sock, mode='r', bufsize=io.DEFAULT_BUFFER_SIZE):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was hoping this trampoline would be made redundant. Why is it necessary? What are the challenges in using the right stream constructors right away?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok maybe this is better. I have jettisoned _make_file_object. HTTPConnection now checks server.ssl_adapter to decide whether to use plain StreamReader/StreamWriter or, if there is one, the SSL adapter's makefile() method. pyopenSSL adapter still needs such a method so that it can offer wrapped streaming methods that know how to deal with WantReadError, WantWriteError etc. The builtin adapter is fine relying on the plain streaming classes.

@julianz- julianz- force-pushed the remove_makefile_minimal branch 11 times, most recently from 7e162f6 to ea44c0b Compare December 9, 2025 05:40
@webknjaz webknjaz changed the title Deprecated Makefile in favor of StreamReader and StreamWriter. Deprecate MakeFile() in favor of StreamReader and StreamWriter Dec 10, 2025
Comment on lines 1291 to 1296
# Check if SSL adapter needs custom wrapped streaming
# objects (pyOpenSSL does, builtin doesn't)
if server.ssl_adapter is not None and hasattr(
server.ssl_adapter,
'makefile',
):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks like an abstraction leak. We shouldn't make TLS adapters and HTTP connections coupled. Let's think of a better solution. I wonder if this initializer could work with a pre-wrapped socket or something. It doesn't feel right that HTTP layer would care whether TCP's got a TLS tunnel or not.

Also, having a conditionally existing method on adapters seems fragile.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm starting to wonder if the server instance would need a makefile() method that would hold the callable selection logic...

Copy link
Contributor Author

@julianz- julianz- Dec 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is largely what lead to my earlier TLSSocket approach but I've revisited that implementing a more focussed version. The TLSSocket class now wraps the pyOpenSSL SSL.Connection to handle OpenSSL-specific errors like WantReadError internally. This allows plain StreamReader/StreamWriter to work directly now with pyOpenSSL connections. So we get rid of makefile without any abstraction leaks hopefully. See what you think.

"""
File object attached to a socket object.
This method is now deprecated: Use StreamReader or StreamWriter directly.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a function, not a method.

last_used = None

def __init__(self, server, sock, makefile=MakeFile):
def __init__(self, server, sock):
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removing args from method signatures is a breaking API change. They'd need to be deprecated first. Although, I'm not entirely sure how to handle the constructor split beyond that.

@julianz- julianz- force-pushed the remove_makefile_minimal branch 2 times, most recently from 1b57f6d to 3ce3eb2 Compare December 10, 2025 23:30
# self.socket is of OpenSSL.SSL.Connection type
resp_sock = self.socket._socket
# Unwrap to get raw TCP socket
resp_sock = self.socket._sock
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this attr always exist?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently handle_no_ssl() will only ever get called when using PyOpenSSLAdapter so yes provided we make sure it's there on that adapter this should work. However, the property mimics the same pattern that ssl.SSLSocket uses and also socket.socket.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, it's probably okay for right now. But I hope that in a follow-up we'll be able to have a better way to reach the underlying socket and won't be accessing the private attributes.

@julianz- julianz- force-pushed the remove_makefile_minimal branch from 3ce3eb2 to 6e99e85 Compare December 10, 2025 23:46
@julianz- julianz- force-pushed the remove_makefile_minimal branch 5 times, most recently from ff05b9c to 6b422bf Compare December 16, 2025 18:51
@julianz- julianz- force-pushed the remove_makefile_minimal branch 7 times, most recently from 99e08a1 to 2e54b22 Compare December 17, 2025 20:42
@julianz- julianz- force-pushed the remove_makefile_minimal branch 14 times, most recently from adb3e86 to 3d15b25 Compare December 18, 2025 21:49
We replace the `MakeFile` factory function with direct class instantiation.
The `MakeFile` function now emits a `DeprecationWarning` and will be
removed in a future release.

`makefile()` methods are also deprecated on the adapters and its
base class.
@julianz- julianz- force-pushed the remove_makefile_minimal branch from 3d15b25 to fb4f826 Compare December 18, 2025 22:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants