I'm programming my own shell in python. Right now I'm trying to implement the cd
command to my shell.
The function that performs this command has several variables:
self.current_dir = "C:\\"
- The default value, it changes depends on the user's input using the cd command
dir = "..."
- The requested directory that the user types. "..." is an example for an input that causes the problem.
Here is my code:
def command_cd(self, dir):
if os.path.isdir(self.shell.current_dir + dir):
self.shell.current_dir = self.shell.current_dir + dir + "\\"
The problem is that for some strange reason, os.path.isdir(self.shell.current_dir + dir)
returns True
when the user types dots (Just like the example inputs for the variables which I gave above).
The problem occurs even if you change the amount of dots (even above 5 dots) and I really have no idea what causes it.
There's obviously no folder named ...
or anything like it.
If my problem isn't clear enough please comment and I'll edit it
.
is the current directory, ..
is the parent directory, and there no such reference of anything greater than two dots.
But however, the reason for why os.path.isdir()
returns True is because python registers everything greater than two dots as one dot.
import os
print(os.path.abspath(".......") == os.path.abspath("."))
print(os.path.abspath("....") == os.path.abspath("."))
# and that
print(os.path.samefile('......', '.'))
# also prints True
They will all print True, since ....
,.......
and .
points to the same place.
As chepner has pointed out in the comments, this problem doesn’t occur in POSIX systems, whereas it’s caused by os.stat
mistakenly equates '....'
with '.'
(which is not the case, see later edit)
Important Edit:
Commented by eriksun:
Windows
os.path.isdir
is implemented by callingGetFileAttributes
, which callsNtQueryAttributesFile
. Like all file system functions, first it has to convert theDOS
path to a nativeNT
path. To the kernel"."
and".."
are just normal names, so the runtime library first has to normalize the path via the functionRtlGetFullPathName_Ustr
, which also gets used byos.path.abspath
, so the result is similar. The way it reduces more than two dots and trailing spaces in the final component is a legacy inherited fromDOS
. It's doing its best to emulate anOS
from the 1980s.
Therefore this problem has nothing to do with python itself, as this problem occurs in Windows cmd as well, cd c:\.....
or cd .\....\..
Windows will still let you get away with it, by referencing two than two dots with one dot. As it was inherited from DOS
to reduce more than two dots to one and remove trailing spaces.