-
-
Notifications
You must be signed in to change notification settings - Fork 31k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
pathlib.Path._from_parsed_parts should call cls.__new__(cls) #76846
Comments
Hi, I tried subclassing pathlib.Path and provide it with a new attribute (basically an accessor to an extended attribute). I am rather new to the concept of __slots__ and __new__() but here is how I pictured it should look: from errno import ENODATA
from os import getxattr, setxattr
from pathlib import Path
class Path_(type(Path())):
__slots__ = ("new_attr",)
def __new__(cls, *args, new_attr=None, **kwargs):
self = super().__new__(cls, *args, **kwargs)
self._new_attr = new_attr
return self
@property
def new_attr(self):
if self._new_attr:
return self._new_attr
new_attr = b"something_dynamic" # for example uuid4().bytes
setxattr(self, "user.new_attr", new_attr)
self._new_attr = new_attr
return new_attr The issue I have is that although my class defines its own __new__() method, it is not always called by the methods of pathlib.Path. For example: >>> Path_("/etc").parent.new_attr
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/path/to/reproducer.py", line 19, in new_attr
if self._new_attr:
AttributeError: _new_attr The current workaround I use consists in redefining pathlib.Path's _from_parsed_parts() method in my class: instead of creating a new object using: This is the first time I play with the __new__() special method, so it is possible I missed something, if so, sorry for the noise. |
Typo in the code of the previous comment:
|
This behaviour is because "parent" descriptor ends calling: @classmethod
def _from_parsed_parts(cls, drv, root, parts, init=True):
self = object.__new__(cls)
self._drv = drv
self._root = root
self._parts = parts
if init:
self._init()
return self and this calls object.__new__ and this call raises AttributeError: new_attr. Notice that object.__new__(cls) will not raise as this snippet shows: >>>: class A:
ZeroDivisionError Traceback (most recent call last)
<python> in <module>()
----> 1 A() <python> in __new__(*args) ZeroDivisionError:
|
Sorry, the exception of object.__new__(cls) is AttributeError: _drv |
Antoine, is the reason of calling object.new(cls) in |
#100481 removes |
`PurePath` now normalises and splits paths only when necessary, e.g. when `.name` or `.parent` is accessed. The result is cached. This speeds up path object construction by around 4x. `PurePath.__fspath__()` now returns an unnormalised path, which should be transparent to filesystem APIs (else pathlib's normalisation is broken!). This extends the earlier performance improvement to most impure `Path` methods, and also speeds up pickling, `p.joinpath('bar')` and `p / 'bar'`. This also fixes pythonGH-76846 and pythonGH-85281 by unifying path constructors and adding an `__init__()` method.
…lasses (GH-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>
…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>
…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>
Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.
Show more details
GitHub fields:
bugs.python.org fields:
Linked PRs
__new__()
and__init__()
on pathlib subclasses #102789The text was updated successfully, but these errors were encountered: