Search code examples
pythondjangoenvironment-variablespathlib

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

  • 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