[Python-Dev] SSL support in _socket

Tim Peters tim.one@comcast.net
Mon, 18 Feb 2002 00:19:26 -0500

[M.-A. Lemburg]
> Some explanation:
> The _ssl module needs access to the type object defined in
> the _socket module. Since cross-DLL linking introduces a lot of
> problems on many platforms, the "trick" is to wrap the
> C API of a module in a struct which then gets exported to
> other modules via a PyCObject.
> The code in socketmodule.c defines this struct (which currently
> only contains the type object reference, but could very
> well also include other C APIs needed by other modules)
> and exports it as PyCObject via the module dictionary
> under the name "CAPI".
> Other modules can now include the socketmodule.h file
> which defines the needed C APIs to import and set up
> a static copy of this struct in the importing module.
> After initialization, the importing module can then
> access the C APIs from the _socket module by simply
> referring to the static struct, e.g.
>         /* Load _socket module and its C API; this sets up the global
>            PySocketModule */
>         if (PySocketModule_ImportModuleAndAPI())
>                 return;
>         ...
>         if (!PyArg_ParseTuple(args, "O!|zz:ssl",
>                               PySocketModule.Sock_Type,
>                               (PyObject*)&Sock,
>                               &key_file, &cert_file))
>                 return NULL;
> (Perhaps I should copy the above explanation into the source
>  files ?!)

I don't know.  I really don't have time to try and understand this, but I
can tell you I spent a lot of time staring at the code just trying to fix
the part that didn't work, and it was slow and painful going.  Without deep
understanding, I can only repeat that all this machinery *seems* to be
overkill in this specific case; and since there is no other case in the
Python core, a mass of overly general machinery in the Python core seems out
of place.

> ...
> Ah, you're right, the export of the type object is not
> needed anymore since this is now done using the PyCObject.
> Sorry, my bad.

No problem -- that part turned out to be easy, once I found it.

> ...
> The reason for putting the code in the header file is
> to avoid duplication of code. The import API is needed by
> all modules wishing to use the C API of the socket module.

But in this specific case you confirm that there is only one client:

> Currently, only _ssl needs this, but I think it would be
> a good strategy to extend this technique to other modules
> as well (esp. the array module would be a good candidate).

Possibly, but it's overly elaborate in this specific case.  If it needed to
be hypergeneral (and it doesn't here), it seems it would be better to make
the code template *more* general, so that every importer of every module
could include a common (e.g.) PyImportModuleAndApi.h header file one or more
times, after setting a pile of #defines to specialize it to the module at

> I don't think it's overly complicated.

You've confirmed that it is in this specific case, and that's the only case
there is in the codebase all the Python developers work with.

> As I read the checkins, you've remove the type object export.

Well, I removed the DL_IMPORT.  The problem was more that it wasn't
exported, and now it doesn't need to be imported or exported.

> I am curious why the test_socket still fails on Windows
> though. Both test_socket and test_socket_ssl work just fine on
> Linux.

test_socket was a red herring.  Merely trying to import socket died with
NameError on Windows.  That got fixed too, and the non-SLL socket tests on
Windows worked fine then.