Skip to content

GH-76846, GH-85281: Call __new__() and __init__() on pathlib subclasses - #102789

Merged
barneygale merged 9 commits into
python:mainfrom
barneygale:gh-76846-unify-constructors
Apr 3, 2023
Merged

barneygale merged 9 commits into
python:mainfrom
barneygale:gh-76846-unify-constructors

Conversation

@barneygale

@barneygale barneygale commented Mar 17, 2023 •

Copy link
Copy Markdown
Contributor

This PR fixes an issue where __new__() and __init__() were not called on subclasses of pathlib.PurePath and Path in some circumstances.

Specifically, the _from_parsed_parts() constructor -- which is used when iterating directories, parents, and in with_name() and friends -- has been altered as follows:

diff --git a/Lib/pathlib.py b/Lib/pathlib.py
index 55c44f12e5..c9b45ddbfa 100644
--- a/Lib/pathlib.py
+++ b/Lib/pathlib.py
@@ -310,7 +310,9 @@ def _from_parts(cls, args):
 
     @classmethod
     def _from_parsed_parts(cls, drv, root, parts):
-        self = object.__new__(cls)
+        path = cls._format_parsed_parts(drv, root, parts)
+        self = cls(path)
+        self._str = path or '.'
         self._drv = drv
         self._root = root
         self._parts = parts

This change alone has an unfortunate effect: paths constructed this way are re-parsed and re-normalized even though we have the fully normalized path at hand.

To fix this, we change the main constructor to not normalize paths. Instead, paths are normalized on-demand. This also speeds up path construction, p.joinpath(q), and p / q.

Loading
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants