Skip to content

Client64¤

Base class for communicating with a 32-bit library from 64-bit Python.

Server32 is used in combination with Client64 to communicate with a 32-bit library from 64-bit Python.

Client64 ¤

Client64(
    module32,
    *,
    add_dll_directory=None,
    append_environ_path=None,
    append_sys_path=None,
    host="127.0.0.1",
    port=0,
    protocol=5,
    rpc_timeout=None,
    server32_dir=None,
    timeout=10,
    **kwargs,
)

Base class for communicating with a 32-bit library from 64-bit Python.

Starts a 32-bit server, Server32, to host a Python class that is a wrapper around a 32-bit library. Client64 runs within a 64-bit Python interpreter and it sends requests to the server which calls the 32-bit library to execute the request. The server then sends the response back to the client.

Parameters:

Name Type Description Default
module32 PathLike

The name of, or the path to, a Python module that will be imported by the 32-bit server. The module must contain a class that inherits from Server32.

required
add_dll_directory PathLike | Iterable[PathLike] | None

Add path(s) to the 32-bit server's DLL search path. See os.add_dll_directory for more details. Supported on Windows only.

Added in version 1.0

None
append_environ_path PathLike | Iterable[PathLike] | None

Append path(s) to the 32-bit server's os.environ["PATH"] variable. This may be useful if the library that is being loaded requires additional libraries that must be available on PATH.

None
append_sys_path PathLike | Iterable[PathLike] | None

Append path(s) to the 32-bit server's sys.path variable. The value of sys.path from the 64-bit process is automatically included, i.e.,

path32 = path64 + append_sys_path

None
host str | None

The hostname (IP address) of the 32-bit server. If None then the connection to the server is mocked.

Changed in version 1.0

A value of None is allowed.

'127.0.0.1'
port int

The port to open on the 32-bit server. If 0, any available port will be used.

0
protocol int

The pickle protocol to use.

Added in version 0.8

5
rpc_timeout float | None

The maximum number of seconds to wait for a response from the 32-bit server. The RPC timeout value is used for all requests from the server. If you want different requests to have different timeout values, you will need to implement custom timeout handling for each method on the server. Default is None, which will call socket.getdefaulttimeout to get the timeout value.

Added in version 0.6

None
server32_dir PathLike | None

The directory where the 32-bit server is located. Specifying this value may be useful if you created a custom server.

Added in version 0.10

None
timeout float

The maximum number of seconds to wait to establish a connection with the 32-bit server.

10
kwargs Any

All additional keyword arguments are passed to the Server32 subclass. The data type of each value is not preserved. It will be of type str at the constructor of the Server32 subclass.

{}

Raises:

Type Description
OSError

If the 32-bit server cannot be found.

ConnectionTimeoutError

If the connection to the 32-bit server cannot be established.

Note

If module32 is not located in the current working directory then you must either specify the full path to module32 or you can specify the folder where module32 is located by passing a value to the append_sys_path parameter. Using the append_sys_path option also allows for any other modules that module32 may depend on to also be included in sys.path so that those modules can be imported when module32 is imported.

Source code in src/msl/loadlib/client64.py
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
def __init__(  # noqa: PLR0913
    self,
    module32: PathLike,
    *,
    add_dll_directory: PathLike | Iterable[PathLike] | None = None,
    append_environ_path: PathLike | Iterable[PathLike] | None = None,
    append_sys_path: PathLike | Iterable[PathLike] | None = None,
    host: str | None = "127.0.0.1",
    port: int = 0,
    protocol: int = 5,
    rpc_timeout: float | None = None,
    server32_dir: PathLike | None = None,
    timeout: float = 10,
    **kwargs: Any,
) -> None:
    """Base class for communicating with a 32-bit library from 64-bit Python.

    Starts a 32-bit server, [Server32][], to host a Python class that is a wrapper
    around a 32-bit library. [Client64][] runs within a 64-bit Python interpreter
    and it sends requests to the server which calls the 32-bit library to execute
    the request. The server then sends the response back to the client.

    Args:
        module32: The name of, or the path to, a Python module that will be imported by the
            32-bit server. The module must contain a class that inherits from [Server32][].

        add_dll_directory: Add path(s) to the 32-bit server's DLL search path.
            See [os.add_dll_directory][]{:target="_blank"} for more details.
            Supported on Windows only.

            !!! note "Added in version 1.0"

        append_environ_path: Append path(s) to the 32-bit server's
            [os.environ["PATH"]][os.environ]{:target="_blank"} variable. This may be useful if
            the library that is being loaded requires additional libraries that
            must be available on `PATH`.

        append_sys_path: Append path(s) to the 32-bit server's [sys.path][]{:target="_blank"}
            variable. The value of [sys.path][]{:target="_blank"} from the 64-bit process is
            automatically included, i.e.,

            <code>path<sub>32</sub> = path<sub>64</sub> + append_sys_path</code>

        host: The hostname (IP address) of the 32-bit server. If `None` then the
            connection to the server is [mocked][faq-mock].

            !!! note "Changed in version 1.0"
                A value of `None` is allowed.

        port: The port to open on the 32-bit server. If `0`, any available port will be used.

        protocol: The [pickle protocol][pickle-protocols]{:target="_blank"} to use.
            !!! note "Added in version 0.8"

        rpc_timeout: The maximum number of seconds to wait for a response from the 32-bit server.
            The [RPC](https://en.wikipedia.org/wiki/Remote_procedure_call){:target="_blank"}
            timeout value is used for *all* requests from the server. If you want different
            requests to have different timeout values, you will need to implement custom
            timeout handling for each method on the server. Default is `None`, which will
            call [socket.getdefaulttimeout][]{:target="_blank"} to get the timeout value.

            !!! note "Added in version 0.6"

        server32_dir: The directory where the 32-bit server is located.
            Specifying this value may be useful if you created a [custom server][refreeze].

            !!! note "Added in version 0.10"

        timeout: The maximum number of seconds to wait to establish a connection
            with the 32-bit server.

        kwargs: All additional keyword arguments are passed to the [Server32][] subclass.
            The data type of each value is not preserved. It will be of type [str][]
            at the constructor of the [Server32][] subclass.

    Raises:
        OSError: If the 32-bit server cannot be found.
        ConnectionTimeoutError: If the connection to the 32-bit server cannot be established.

    !!! note
        If `module32` is not located in the current working directory then you
        must either specify the full path to `module32` **or** you can
        specify the folder where `module32` is located by passing a value to the
        `append_sys_path` parameter. Using the `append_sys_path` option also allows
        for any other modules that `module32` may depend on to also be included
        in [sys.path][]{:target="_blank"} so that those modules can be imported when `module32`
        is imported.
    """
    self._client: _MockClient | _HTTPClient
    if host is None:
        self._client = _MockClient(
            os.fsdecode(module32),
            add_dll_directory=add_dll_directory,
            append_environ_path=append_environ_path,
            append_sys_path=append_sys_path,
            **kwargs,
        )
    else:
        self._client = _HTTPClient(
            os.fsdecode(module32),
            add_dll_directory=add_dll_directory,
            append_environ_path=append_environ_path,
            append_sys_path=append_sys_path,
            host=host,
            port=port,
            protocol=protocol,
            rpc_timeout=rpc_timeout,
            server32_dir=server32_dir,
            timeout=timeout,
            **kwargs,
        )

connection property ¤

connection

HTTPConnection | None — The connection to the 32-bit server.

The value is None for a mocked connection or if the connection has been closed.

host property ¤

host

str | None — The host address of the 32-bit server.

The value is None for a mocked connection.

lib32_path property ¤

lib32_path

str — The path to the 32-bit library file.

port property ¤

port

int — The port number of the 32-bit server.

The value is -1 for a mocked connection.

request32 ¤

request32(name, *args, **kwargs)

Send a request to the 32-bit server.

Parameters:

Name Type Description Default
name str

The name of a method, property or attribute of the Server32 subclass.

required
args Any

The arguments that the method of the Server32 subclass requires.

()
kwargs Any

The keyword arguments that the method of the Server32 subclass requires.

{}

Returns:

Type Description
Any

Whatever is returned by calling name.

Raises:

Type Description
Server32Error

If there was an error processing the request on the 32-bit server.

ResponseTimeoutError

If a timeout occurs while waiting for the response from the 32-bit server.

Source code in src/msl/loadlib/client64.py
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
def request32(self, name: str, *args: Any, **kwargs: Any) -> Any:
    """Send a request to the 32-bit server.

    Args:
        name: The name of a method, property or attribute of the [Server32][] subclass.
        args: The arguments that the method of the [Server32][] subclass requires.
        kwargs: The keyword arguments that the method of the [Server32][] subclass requires.

    Returns:
        Whatever is returned by calling `name`.

    Raises:
        Server32Error: If there was an error processing the request on the 32-bit server.
        ResponseTimeoutError: If a timeout occurs while waiting for the response from the 32-bit server.
    """
    return self._client.request32(name, *args, **kwargs)

shutdown_server32 ¤

shutdown_server32(kill_timeout=10)

Shut down the 32-bit server.

This method shuts down the 32-bit server, closes the client connection, and deletes the temporary file that was used to store the serialized pickled data.

Parameters:

Name Type Description Default
kill_timeout float

If the 32-bit server is still running after kill_timeout seconds, the server will be killed using brute force. A warning will be issued if the server is killed in this manner.

Added in version 0.6

10

Returns:

Type Description
tuple[IO[bytes], IO[bytes]]

The (stdout, stderr) streams from the 32-bit server.

Limit the total number of characters that are written to either stdout or stderr on the 32-bit server to be < 4096. This will avoid potential blocking when reading the stdout and stderr PIPE buffers.

Changed in version 0.8

Prior to version 0.8 this method returned None

Tip

This method gets called automatically when the reference count to the Client64 instance reaches zero (see object.__del__).

Source code in src/msl/loadlib/client64.py
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
def shutdown_server32(self, kill_timeout: float = 10) -> tuple[IO[bytes], IO[bytes]]:
    """Shut down the 32-bit server.

    This method shuts down the 32-bit server, closes the client connection, and deletes
    the temporary file that was used to store the serialized [pickle][]{:target="_blank"}d data.

    Args:
        kill_timeout: If the 32-bit server is still running after `kill_timeout`
            seconds, the server will be killed using brute force. A warning will be
            issued if the server is killed in this manner.

            !!! note "Added in version 0.6"

    Returns:
        The `(stdout, stderr)` streams from the 32-bit server.

            Limit the total number of characters that are written to either `stdout`
            or `stderr` on the 32-bit server to be &lt; 4096. This will avoid potential
            blocking when reading the `stdout` and `stderr` PIPE buffers.

            !!! note "Changed in version 0.8"
                Prior to version 0.8 this method returned `None`

    !!! tip
        This method gets called automatically when the reference count to the
        [Client64][] instance reaches zero (see [`object.__del__`][]{:target="_blank"}).
    """
    return self._client.shutdown_server32(kill_timeout=kill_timeout)