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

GH-76846, GH-85281: Call __new__() and __init__() on pathlib subclasses#102789
barneygale merged 9 commits into
python:mainfrom
barneygale:gh-76846-unify-constructors

Conversation

@barneygale

@barneygalebarneygale 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.

@zoobazooba left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM (with what I marked). Any concerns in particular that you'd like me to take a closer look at?

Comment threadLib/pathlib.py Outdated
Comment threadLib/pathlib.py Outdated
Comment threadLib/pathlib.py Outdated
Comment threadLib/pathlib.py Outdated
Co-authored-by: Steve Dower <steve.dower@microsoft.com>
Comment threadLib/pathlib.py Outdated
Comment threadLib/test/test_pathlib.py
@barneygale

Copy link
Copy Markdown
ContributorAuthor

I think those were my only areas of concern! Thanks for the review :)

@barneygale

Copy link
Copy Markdown
ContributorAuthor

Are you happy for me to merge, @zooba?

@zooba

zooba commented Apr 3, 2023

Copy link
Copy Markdown
Member

All yours :shipit:

@barneygale
barneygale merged commit 11c3020 into python:mainApr 3, 2023
gaogaotiantian pushed a commit to gaogaotiantian/cpython that referenced this pull request Apr 8, 2023
…pathlib subclasses (pythonGH-102789)
Fix an issue where `__new__()` and `__init__()` were not called on subclasses of `pathlib.PurePath` and `Path` in some circumstances.
Paths are now normalized on-demand. This speeds up path construction, `p.joinpath(q)`, and `p / q`.
Co-authored-by: Steve Dower <steve.dower@microsoft.com>
warsaw pushed a commit to warsaw/cpython that referenced this pull request Apr 11, 2023
…pathlib subclasses (pythonGH-102789)
Fix an issue where `__new__()` and `__init__()` were not called on subclasses of `pathlib.PurePath` and `Path` in some circumstances.
Paths are now normalized on-demand. This speeds up path construction, `p.joinpath(q)`, and `p / q`.
Co-authored-by: Steve Dower <steve.dower@microsoft.com>
Sign up for freeto 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

@barneygale@zooba@bedevere-bot