diff --git a/cloudpathlib/anypath.py b/cloudpathlib/anypath.py index de56f330..197dbe65 100644 --- a/cloudpathlib/anypath.py +++ b/cloudpathlib/anypath.py @@ -1,4 +1,5 @@ import os +from abc import ABC from pathlib import Path from typing import Union @@ -6,19 +7,7 @@ from .exceptions import AnyPathTypeError -class AnyPathMeta(type): - """Metaclass for AnyPath that implements special methods so that AnyPath works as a virtual - superclass when using isinstance or issubclass checks on CloudPath or Path inputs. See - [PEP 3119](https://www.python.org/dev/peps/pep-3119/#overloading-isinstance-and-issubclass).""" - - def __instancecheck__(cls, inst): - return isinstance(inst, CloudPath) or isinstance(inst, Path) - - def __subclasscheck__(cls, sub): - return issubclass(sub, CloudPath) or issubclass(sub, Path) - - -class AnyPath(metaclass=AnyPathMeta): +class AnyPath(ABC): """Polymorphic virtual superclass for CloudPath and pathlib.Path. Constructing an instance will automatically dispatch to CloudPath or Path based on the input. It also supports both isinstance and issubclass checks. @@ -55,6 +44,10 @@ def _validate(cls, value) -> Union[CloudPath, Path]: return cls.__new__(cls, value) +AnyPath.register(CloudPath) # type: ignore +AnyPath.register(Path) + + def to_anypath(s: Union[str, os.PathLike]) -> Union[CloudPath, Path]: """Convenience method to convert a str or os.PathLike to the proper Path or CloudPath object using AnyPath. diff --git a/tests/test_anypath.py b/tests/test_anypath.py index 90c97bd5..47cac832 100644 --- a/tests/test_anypath.py +++ b/tests/test_anypath.py @@ -36,3 +36,7 @@ def test_anypath_cloudpath(rig): def test_anypath_bad_input(): with pytest.raises(AnyPathTypeError): AnyPath(0) + + +def test_anypath_subclass_anypath(): + assert issubclass(AnyPath, AnyPath)