Pathlib 'нормализует' пути UN C с помощью "$" - PullRequest
1 голос
/ 05 февраля 2020

В Python3 .8 я пытаюсь использовать pathlib для объединения строки с путем UN C, который находится на диске C удаленного компьютера.
Это странно противоречиво .
Например:

>>> remote = Path("\\\\remote\\", "C$\\Some\\Path")
>>> remote
WindowsPath('//remote//C$/Some/Path')

>>> remote2 = Path(remote, "More")
>>> remote2
WindowsPath('/remote/C$/Some/Path/More')

Обратите внимание, как начальный // превращается в /?
Впрочем, поместите начальный путь в одну строку, и все в порядке:

>>> remote = Path("\\\\remote\\C$\\Some\\Path")
>>> remote
WindowsPath('//remote/C$/Some/Path')

>>> remote2 = Path(remote, "more")
>>> remote2
WindowsPath('//remote/C$/Some/Path/more')

Это работает как обходной путь, но я подозреваю, что я неправильно понимаю, как это должно работать или делает это неправильно.
Кто-нибудь понял, что происходит?

1 Ответ

2 голосов
/ 05 февраля 2020

tldr: вы должны предоставить всю долю UN C (\\\\host\\share) как единое целое, pathlib имеет особый случай обработки путей UN C, но ему нужен именно этот префикс для признать путь как ООН C. Вы не можете использовать средства pathlib для раздельного управления хостом и общим ресурсом, это заставляет pathlib нарушать прокладку.

Конструктор Path нормализует (дедуплицирует) разделители пути:

>>> PPP('///foo//bar////qux')
PurePosixPath('/foo/bar/qux')
>>> PWP('///foo//bar////qux')
PureWindowsPath('/foo/bar/qux')

PureWindowsPath имеет специальное случай для путей, распознаваемых как UN C, то есть //host/share..., что позволяет избежать свертывания ведущих разделителей.

Однако ваша первоначальная конкатенация помещает его в странный фанк, потому что он создает путь формируется //host//share..., затем путь преобразуется обратно в строку при передаче конструктору, после чего он больше не соответствует UN C и все разделители свернуты:

>>> PWP("\\\\remote\\", "C$\\Some\\Path")
PureWindowsPath('//remote//C$/Some/Path')
>>> str(PWP("\\\\remote\\", "C$\\Some\\Path"))
'\\\\remote\\\\C$\\Some\\Path'
>>> PWP(str(PWP("\\\\remote\\", "C$\\Some\\Path")))
PureWindowsPath('/remote/C$/Some/Path')

Похоже, проблема заключается именно в наличии конечного разделителя на пути UN C, я не знаю, является ли это ошибкой или соответствует ли он другому UN C стилю (но не UN C) особый случай:

>>> PWP("//remote")
PureWindowsPath('/remote')
>>> PWP("//remote/")
PureWindowsPath('//remote//') # this one is weird, the trailing separator gets doubled which breaks everything
>>> PWP("//remote/foo")
PureWindowsPath('//remote/foo/')
>>> PWP("//remote//foo")
PureWindowsPath('/remote/foo')

Такое поведение на самом деле не выглядит документированным, pathlib do c специально отмечает, что оно сворачивает разделители пути и имеет fe w примеры ООН C, которые показывают, что это не так, но я действительно не знаю, что именно должно произойти. В любом случае кажется, что пути UN C обрабатываются в некоторой степени правильно только в том случае, если первые два сегмента хранятся в виде одного «диска», а общий путь считается диском , что специально задокументировано .

Примечание: использование joinpath / / не вызывает повторную нормализацию, ваш путь остается неправильным (поскольку второй путь пути между хостом и общим ресурсом остается удвоенным), но он не становится полностью разрушилась.

...