'How to create a pathlib relative path with a dot starting point?
I needed to create a relative path starting with the current directory as a "." dot
For example, in windows ".\envs\.some.env" or "./envs/.some.env" elsewhere
I wanted to do this using pathlib. A solution was found, but it has a kludgy replace statement. Is there a better way to do this using pathlib?
The usage was django-environ, and the goal was to support multiple env files. The working folder contained an envs folder with the multiple env files within that folder.
import environ
from pathlib import Path
import os
domain_env = Path.cwd()
dotdot = Path("../")
some_env = dotdot / "envs" / ".some.env"
envsome = environ.Env()
envsome.read_env(envsome.str(str(domain_env), str(some_env).replace("..", ".")))
print(str(some_env))
print(str(some_env).replace("..", "."))
dot = Path("./") # Path(".") gives the same result
some_env = dot / "envs" / ".some.env"
print(str(some_env))
On windows gives:
..\envs\.some.env
.\envs\.some.env
envs\.some.env
Solution 1:[1]
The best I could find was (as suggested by metatoaster in the question’s comments):
os.path.join(".", some_env)
where some_env
may either be a string or bytes
or (since Python 3.6) any path-like object (which means you don’t have to convert your Path
objects to strings anymore).
And since some people are wondering why this might be useful:
- A shell script
foo.sh
in the current directory cannot be called byfoo.sh
(except when.
is in$PATH
), but must instead be invoked using./foo.sh
. - As Boris explained, in a Node.js
require()
statement there’s a difference betweenfoo
and./foo
. - I myself needed this in order to create a file name argument to ExifTool that’s guaranteed to not be parsed as a command line option, even if the file is for example called
-quiet
. ExifTool doesn’t adhere to the Unix convention of having a--
argument that denotes all the following argument to not be options, and the official suggestion by its author is to “[p]ut the directory name before the file name if the file name begins with a dash”.
Solution 2:[2]
Here's a multi-platform idea:
import ntpath
import os
import posixpath
from pathlib import Path, PurePosixPath, PureWindowsPath
def dot_path(pth):
"""Return path str that may start with '.' if relative."""
if pth.is_absolute():
return os.fsdecode(pth)
if isinstance(pth, PureWindowsPath):
return ntpath.join(".", pth)
elif isinstance(pth, PurePosixPath):
return posixpath.join(".", pth)
else:
return os.path.join(".", pth)
print(dot_path(PurePosixPath("file.txt"))) # ./file.txt
print(dot_path(PureWindowsPath("file.txt"))) # .\file.txt
print(dot_path(Path("file.txt"))) # one of the above, depending on host OS
print(dot_path(Path("file.txt").resolve())) # (e.g.) /path/to/file.txt
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | scy |
Solution 2 | Mike T |