Перепишите файл zipfile.py из библиотеки питона к себе, и исправьте строки decode('cp437') и decode("cp437") на decode('cp866'). По-крайней мере, имена файлов внутри архивов станут правильными. Ну и еще надо иметь ввиду, что метод read() выдает байты, а не строки.
Кстати, если всегда
bytes.decode('cp437').encode('cp437') == bytes
то можно обойтись и без патча zipfile.py:
f = ZipFile('z.zip', 'r')
for name in f.namelist():
unicode_name = name.encode('cp437').decode('cp866')
print(unicode_name)
P.S. Почему имена файлов хранятся внутри архива в OEM кодировке, я не понимаю. Что Windows так делает, что 7-zip.