# Pre-PEP discussion: revival of PEP 543 - A Unified TLS API for Python

**URL:** <https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263>\
**Category:** Core Development\
**Tags:** pep\
**Created:** [April 17, 2024, 8:44pm UTC](https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263 "2024-04-17T20:44:38Z")\
**Posts on this page:** 1\
**Showing post:** 76

<div class="post-metadata">

**Author:** ![Julien00859](https://sea2.discourse-cdn.com/flex002/user_avatar/discuss.python.org/julien00859/32/1300_2.png) [@Julien00859](https://discuss.python.org/u/Julien00859)\
**Post date:** [January 7, 2026, 1:57am UTC](https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263/76 "2026-01-07T01:57:04Z")

</div>

Hello @jvdprng, thank you for your answer.

It is nice that you reply today because I’m almost done implementing tlslib in my lib, I’ve got the TLSBuffer and TLSSocket mostly done (I’m still not compliant with some `WantToRead`/`WantToWrite`), the TLSConfiguration is not done yet but that’s easier than the rest.

I’ve implemented the TLSSocket as such in my work: [socket.py](https://codeberg.org/drlazor8/siotls/src/commit/fcd1ed17e0f69d1c17efd4869187b15e0f0c56db/src/siotls/socket.py), the files at `src/examples/simple_client.py` and `src/examples/simple_server.py` showcase how it works.

It boils down to the following (the actual code contains lengthy docstrings):

```python
class TLSSocket:
    def __exit__ (self, exc_type, exc_value, traceback):
        if exc_type:
            self.fail()
        else:
            self.close()

    def shutdown(self, how: int) -> None:
        if how in (socket.SHUT_RD, socket.SHUT_RDWR):
            # force close the receiving end
            logger.debug("Fake receiving %s", short_name(alerts.CloseNotify()))
            self._buffer._state.process(alerts.CloseNotify()) # noqa: SLF001
        if how in (socket.SHUT_WR, socket.SHUT_RDWR):
            self._buffer.close_sending_end()
            self.flush()
        self._socket.shutdown(how)

    def fail(self) -> None:
        self._buffer.fail()
        self.flush()
        self._socket.close()

    def close(self) -> None:
        self._buffer.close_sending_end()
        self.flush()
        # is_closed() => True when the receiving end is closed, False otherwise
        if not self._buffer.is_closed():
            e = "the peer didn't send a CloseNotify yet"
            raise tlslib.WantReadError(e)
        self._socket.close()

```

In this version the user must explicitly call `shutdown(SHUT_RD)` if he doesn’t care about truncation. If he cares about truncation he gotta call `recv()` until it returns `b''`. There’s no `force` argument, the user must explicitly shutdowns read, or receive everything.

I solved the forked-server problem thanks to a `TLSContext(Client|Server).wrap_socket` function. In the parent process (the one that `accept()`) I create a regular socket (i.e. `import socket`, not `import tlslib`). In the child process (the one that `recv()`/`send()`) I wrap/upgrade the regular TCP socket to a TLS one using this function. I’ve tested other things but they were less elegant.

---

_[View the full topic](https://discuss.python.org/t/pre-pep-discussion-revival-of-pep-543-a-unified-tls-api-for-python/51263)._
