Skip to content

Commit eae87e3

Browse files
bharelilevkivskyi
authored andcommitted
bpo-38878: Fix os.PathLike __subclasshook__ (GH-17336)
Quick subclasshook fix using the same method is being used in collections.abc (up to a certain degree).
1 parent f522a6d commit eae87e3

File tree

3 files changed

+15
-1
lines changed

3 files changed

+15
-1
lines changed

Lib/os.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@
2626
import sys
2727
import stat as st
2828

29+
from _collections_abc import _check_methods
30+
2931
_names = sys.builtin_module_names
3032

3133
# Note: more names are added to __all__ later.
@@ -1070,7 +1072,9 @@ def __fspath__(self):
10701072

10711073
@classmethod
10721074
def __subclasshook__(cls, subclass):
1073-
return hasattr(subclass, '__fspath__')
1075+
if cls is PathLike:
1076+
return _check_methods(subclass, '__fspath__')
1077+
return NotImplemented
10741078

10751079
def __class_getitem__(cls, type):
10761080
return cls

Lib/test/test_os.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4048,6 +4048,14 @@ def test_bad_pathlike(self):
40484048
self.assertRaises(ZeroDivisionError, self.fspath,
40494049
FakePath(ZeroDivisionError()))
40504050

4051+
def test_pathlike_subclasshook(self):
4052+
# bpo-38878: subclasshook causes subclass checks
4053+
# true on abstract implementation.
4054+
class A(os.PathLike):
4055+
pass
4056+
self.assertFalse(issubclass(FakePath, A))
4057+
self.assertTrue(issubclass(FakePath, os.PathLike))
4058+
40514059
def test_pathlike_class_getitem(self):
40524060
self.assertIs(os.PathLike[bytes], os.PathLike)
40534061

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
Fixed __subclasshook__ of :class:`os.PathLike` to return a correct result
2+
upon inheritence. Patch by Bar Harel.

0 commit comments

Comments
 (0)