socks.set_default_proxy() stores defaults for future PySocks socksocket objects. It does not replace Python's native socket class. Consequently, it does not reroute ftplib merely because the call happens before an FTP connection.

Follow the constructors, not the variable holding the proxy URL. ftplib creates a control connection and additional transfer connections. With passive FTP, a successful login proves only that the control connection worked; the data socket used for a listing or file transfer also needs the intended route.

A recipe that replaces socket.socket or wraps a module performs another action beyond setting PySocks defaults. It can affect other libraries sharing that module. Temporarily restoring the original afterward does not make concurrent connections isolated from the mutation.

A custom ftplib subclass can cover the connection paths, but copied internals carry the assumptions of the Python release they came from, including timeout sentinels and protocol handling. Standard-library updates do not update the copy.

Choose a maintained client or supported integration for the required proxy and FTP mode. A PycURL passive FTP download example illustrates a separate client path. For an application-owned customization, identify which constructor opens each control and data socket and preserve the upstream behavior it replaces. A correct proxy value is useful only when those constructors actually consume it.

Mikanda mikatakata