16

I want to test if obj is a pathlib path and realized that the condition type(obj) is pathlib.PosixPath will be False for a path generated on a Windows machine.

Thus the question, is there a way to test if an object is a pathlib path (any of the possible, Path, PosixPath, WindowsPath, or the Pure...-analogs) without checking for all 6 version explicitly?

Matthias Arras
  • 565
  • 7
  • 25

3 Answers3

32

Yes, using isinstance(). Some sample code:

# Python 3.4+
import pathlib

path = pathlib.Path("foo/test.txt")
# path = pathlib.PureWindowsPath(r'C:\foo\file.txt')

# checks if the variable is any instance of pathlib
if isinstance(path, pathlib.PurePath):
    print("It's pathlib!")

    # No PurePath
    if isinstance(path, pathlib.Path):
        print("No Pure path found here")
        if isinstance(path, pathlib.WindowsPath):
            print("We're on Windows")
        elif isinstance(path, pathlib.PosixPath):
            print("We're on Linux / Mac")
    # PurePath
    else:
        print("We're a Pure path")

Why does isinstance(path, pathlib.PurePath) work for all types? Take a look at this diagram:

PathLib overview

We see that PurePath is at the top, that means everything else is a subclass of it. Therefore, we only have to check this one. Same reasoning for Path to check non-pure Paths.

Bonus: You can use a tuple in isinstance(path, (pathlib.WindowsPath, pathlib.PosixPath)) to check 2 types at once.

NumesSanguis
  • 5,832
  • 6
  • 41
  • 76
1

I liked NumesSanguis answer and this is how I used what I learnt:

def check_path_instance(obj: object, name: str) -> pathlib.Path:
    """ Check path instance type then convert and return
    :param obj: object to check and convert
    :param name: name of the object to check (apparently there is no sane way to get the name of the variable)
    :return: pathlib.Path of the object else exit the programe with critical error
    """

    if isinstance(obj, (pathlib.WindowsPath, pathlib.PosixPath)):
        return pathlib.Path(obj)
    else:
        if isinstance(obj, str):
            return pathlib.Path(str(obj)) 
        else:
            logging.critical(
                f'{name} type is: {type(obj)}, not pathlib.WindowsPath or pathlib.PosixPath or str')
            )
            sys.exit(1)
mikey-no
  • 189
  • 2
  • 5
0

Late answer, but I find the following code more robust (PathLike is more generic):

from pathlib import Path
from os import PathLike

p = Path('/tmp/test')

if isinstance(p, PathLike):
   ... do something

A handy one-liner for promoting a string to path:

p = p if isinstance(p, os.PathLike) else Path(p)
plg
  • 1
  • 1