Optimize contruction of Path and PurePath objects

This commit is contained in:
Rémi Lapeyre 2020-05-21 13:49:45 +02:00
parent e16d2f7c37
commit 7cb260068b
3 changed files with 17 additions and 0 deletions

View File

@ -658,6 +658,8 @@ class PurePath(object):
"""
if cls is PurePath:
cls = PureWindowsPath if os.name == 'nt' else PurePosixPath
if len(args) == 1 and type(args[0]) is cls:
return args[0]
return cls._from_parts(args)
def __reduce__(self):
@ -1064,6 +1066,8 @@ class Path(PurePath):
def __new__(cls, *args, **kwargs):
if cls is Path:
cls = WindowsPath if os.name == 'nt' else PosixPath
if len(args) == 1 and len(kwargs) == 0 and type(args[0]) is cls:
return args[0]
self = cls._from_parts(args, init=False)
if not self._flavour.is_supported:
raise NotImplementedError("cannot instantiate %r on your system"

View File

@ -214,6 +214,12 @@ class _BasePurePathTest(object):
for part in p.parts:
self.assertIs(type(part), str)
def test_init(self):
# See bpo-39783, creating a PurePath or a Path object from an other
# PurePath instance return the existing instance.
p = self.cls('foo')
self.assertIs(p, self.cls(p))
def test_str_subclass_common(self):
self._check_str_subclass('')
self._check_str_subclass('.')
@ -1402,6 +1408,10 @@ class _BasePathTest(object):
self.assertIs(type(p), type(q))
self.assertTrue(p.is_absolute())
def test_init(self):
p = self.cls('foo')
self.assertIs(p, self.cls(p))
def test_cwd(self):
p = self.cls.cwd()
self._test_cwd(p)

View File

@ -0,0 +1,3 @@
:class:`pathlib.PurePath`, :class:`pathlib.Path` and their subclasses now
return the same object when their argument is already a Path. Patch
contributed by Rémi Lapeyre.