Типовое значение PySocks не перенаправляет ftplib
Простежьте, какие сокеты ftplib действительно создаёт, вместо того чтобы считать, что set_default_proxy меняет встроенную реализацию сокетов Python.
socks.set_default_proxy() сохраняет значения по умолчанию для будущих объектов socksocket PySocks. Он не заменяет встроенный класс socket в Python. Поэтому он не перенаправляет ftplib только из-за того, что вызов происходит до подключения по FTP.
Следите за конструкторами, а не за переменной, в которой хранится URL прокси. ftplib создаёт управляющее соединение и дополнительные соединения для передачи. При пассивном FTP успешный вход доказывает лишь то, что управляющее соединение работало; сокет данных, используемый для листинга или передачи файла, тоже должен идти по нужному маршруту.
Рецепт, который заменяет socket.socket или оборачивает модуль, делает нечто иное, чем установка значений PySocks по умолчанию. Он может затронуть другие библиотеки, использующие тот же модуль. Последующее восстановление оригинала не делает одновременные соединения изолированными от изменения.
Собственный подкласс ftplib может охватить пути соединений, но скопированные внутренности несут допущения той версии Python, из которой они взяты, включая сторожевые значения тайм-аута и обработку протокола. Обновления стандартной библиотеки не обновляют копию.
Выберите поддерживаемый клиент или поддерживаемую интеграцию для нужного прокси и режима FTP. Пример пассивной загрузки по FTP с PycURL показывает отдельный путь клиента. Для доработки, принадлежащей приложению, определите, какой конструктор открывает каждый управляющий и каждый сокет данных, и сохраните поведение, которое она заменяет. Правильное значение прокси полезно только тогда, когда эти конструкторы действительно его используют.