Skip to content
Prev Previous commit
Next Next commit
bpo-24132: Add test for direct subclassing of PurePath/Path in pathlib
Add expected failing tests to pathlib that will verify the ability
of PurePath and Path to be subclassed by users. As part of this,
test all of the black-box class properties of the newly subclassed
Path-like class instances, and the instances generated by their methods.
  • Loading branch information
kfollstad committed Jun 24, 2021
commit a373969d084b89b60cf34bbe32becd1fec9e8707
54 changes: 54 additions & 0 deletions Lib/test/test_pathlib.py
Original file line number Diff line number Diff line change
Expand Up @@ -1341,6 +1341,30 @@ def test_instance_class_properties(self):
self.assertClassProperties(p, correct_cls)
self.assertNonIONewInstancesClassProperties(p, correct_cls)

@unittest.expectedFailure
def test_direct_subclassing(self):
P = self.cls
try:
class Derived(P):
pass
except Exception as e:
self.fail(f"Failed to subclass {P}: {e}")
else:
try:
derived = Derived('non_empty_pathsegment')
except Exception as e:
self.fail("Failed to be able to instantiate a class "
f"derived from {P}: {e}")
else:
# Unlike how PurePath behaves, when instantiated, the
# instances of its user-created direct subclass keep
# their original class name (instead of becoming a
# flavour-named variant). Hence we use Derived here.
correct_cls = Derived
self.assertClassProperties(derived, correct_cls)
self.assertNonIONewInstancesClassProperties(derived,
correct_cls)

def test_different_flavours_unequal(self):
p = pathlib.PurePosixPath('a')
q = pathlib.PureWindowsPath('a')
Expand Down Expand Up @@ -2480,6 +2504,36 @@ def test_instance_class_properties(self):
link = P(BASE, "linkA")
self.assertClassProperties(link.readlink(), correct_cls)

@unittest.expectedFailure
def test_direct_subclassing(self):
P = self.cls
try:
class Derived(P):
pass
except Exception as e:
self.fail(f"Failed to subclass {P}: {e}")
else:
try:
derived_base = Derived(BASE)
except Exception as e:
self.fail("Failed to be able to instantiate a class "
f"derived from {P}: {e}")
else:
# Much like in the original version of this method,
# we use Derived here because unlike Path, user-created
# subclasses of Path keep their names when instantiated
# (instead of becoming a flavour-named variant).
correct_cls = Derived
self.assertClassProperties(derived_base, correct_cls)
self.assertNonIONewInstancesClassProperties(derived_base,
correct_cls)
self.assertIONoLinkNewInstancesClassProperties(derived_base,
correct_cls)
if os_helper.can_symlink():
derived_link = Derived(BASE, "linkA")
self.assertClassProperties(derived_link.readlink(),
correct_cls)

def test_class_getitem(self):
self.assertIs(self.cls[str], self.cls)

Expand Down