python / python/cpython

Result of os.path.realpath("") is incorrect if cwd is on letter-less drive (\\?\-prefixed)

Aperta
#94,696 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

OS-windows stdlib type-bug
Lingua principale
Python
Stelle
77.2k
Fork
36k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

Bug report

  1. Create volume, dir on it, don't assign a drive letter
  2. In Python:
>>> import os
>>> os.chdir("\\\\?\\Volume{<uuid>}\\<dir>")
>>> os.path.realpath("")
'\\\\?\\Volume{<uuid>}\\<dir>\\.'

The dot is invalid in \\?\-prefixed path.
Dots (. and ..) are normalized by Windows API (at least on NTFS). But \\?\ paths bypass normalization and so may not contain dots. See, for example, here.
All later WinAPI calls with this path fail.

As a simple test, dir \\?\Volume{<uuid>}\dir\. doesn't work whereas dir \\?\Volume{<uuid>}\dir works.

P.S. os.path.realpath(".") gives the same invalid result

Your environment

CPython 3.10.0
Windows 10

Context
The problem arises from pip.
sys.path contains empty string (meaning current dir I presume).
And legacy installation method resolves sys.path relatively to cwd.

Investigation
Here:
https://github.com/python/cpython/blob/4bed0db7c222f8df1b4e31107c0305214caf3f56/Lib/ntpath.py#L704
os.path.join still adds slash even if the second argument is empty. And if the path is ended with slash, dot is added somewhere below.

I fixed it to:

path = cwd if path == "." or path == "" else join(cwd, path)

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia in Lib/ntpath.py intorno alla riga 704 indicata e riproduci il comportamento di Windows con un percorso di volume \?-con prefisso la cui directory corrente non ha una lettera di unità. Verifica come os.path.realpath("") e os.path.realpath(".") costruiscono i relativi percorsi, quindi aggiungi una copertura di regressione che mostri che nessuno dei due risultati termina con un componente \. non valido e che il percorso risultante funziona con le chiamate WinAPI successive.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
python
Ambito
operating-systems
Tipo di issue
Bug
Difficoltà
3/5
Tempo stimato
1-2 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.