| Commit message (Collapse) | Author | Age |
| |
|
|
|
|
|
|
|
|
|
|
|
| |
Move `_PurePathBase` and `_PathBase` to a new `pathlib._abc` module, and
drop the underscores from the class names.
Tests are mostly left alone in this commit, but they'll be similarly split
in a subsequent commit.
The `pathlib._abc` module will be published as an independent PyPI package
(similar to how `zipfile._path` is published as `zipp`), to be refined
and stabilised prior to its possible addition to the standard library.
|
|
|
|
|
| |
Add private `pathlib._PurePathBase` class: a private superclass of both `PurePath` and `_PathBase`. Unlike `PurePath`, it does not define any of these special methods: `__fspath__`, `__bytes__`, `__reduce__`, `__hash__`, `__eq__`, `__lt__`, `__le__`, `__gt__`, `__ge__`. Its initializer and path joining methods accept only strings, not os.PathLike objects more broadly.
This is important for supporting *virtual paths*: user subclasses of `_PathBase` that provide access to archive files, FTP servers, etc. In these classes, the above methods should be implemented by users only as appropriate, with due consideration for the hash/equality of any backing objects, such as file objects or sockets.
|
|
|
|
|
|
|
|
|
|
|
| |
(#112676)
In `test_pathlib`, the `check_drive_root_parts` test methods evaluated
both joining and parsing/normalisation of paths. This dates from a time
when pathlib implemented both functions itself, but nowadays path joining
is done with `posixpath.join()` and `ntpath.join()`.
This commit moves the joining-related test cases into `test_posixpath` and
`test_ntpath`.
|
|
|
|
| |
`group()` (#107962)
|
|
|
|
|
|
|
| |
Add trailing slashes to expected `Path.glob()` results wherever a pattern
has a trailing slash. This matches what `glob.glob()` produces.
Due to another bug (GH-65238) pathlib strips all trailing slashes, so this
change is academic for now.
|
|
|
|
|
| |
Construct only one new list object (using `list.copy()`) when creating a
new path object with a modified tail. This slightly speeds up
`with_name()` and `with_suffix()`
|
|
|
|
| |
Co-authored-by: blurb-it[bot] <43283697+blurb-it[bot]@users.noreply.github.com>
Co-authored-by: Barney Gale <barney.gale@gmail.com>
|
|
|
|
|
|
|
|
|
|
|
| |
Add `PurePathTest` as a superclass of `PathTest`, and therefore also
`PathSubclassTest`. This adds coverage of pure functionality in user
subclasses of `pathlib.Path`.
Remove `PosixPathAsPureTest` and `WindowsPathAsPureTest`, as they
now duplicate `PosixPathTest` and `WindowsPathTest`.
This makes the MROs of test unit classes match the MROs of pathlib
classes.
|
|
|
|
|
|
| |
`group()` (#112239)
Move test methods from `WindowsPathAsPureTest` to `WindowsPathTest` unit.
The former test unit is intended to exercise only pure path functionality.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Re-arrange `pathlib.PurePath` methods in source code. No other changes.
The `PurePath` implementations of certain special methods, such as
`__eq__()` and `__hash__()`, are not usually applicable to user subclasses
of `_PathBase`. To facilitate their removal, another patch will split the
`PurePath` class into `_PurePathBase` and `PurePath`, with the latter
providing these special methods.
This patch prepares the ground for splitting `PurePath`. It's similar to
e8d77b0, which preceded splitting `Path`. By churning the methods here,
subsequent patches will be easier to review and less likely to break
things.
|
|
|
|
| |
(#110655)
|
|
|
|
|
|
| |
Ensure that `PurePath('foo/a').with_name('.')` raises `ValueError`
Ensure that `PureWindowsPath('foo/a').with_name('a:b')` does not raise
`ValueError`.
|
|
|
| |
Use the class under test to create files, directories and symlinks.
|
|
|
|
|
|
|
| |
This method supports file URIs (including variants) as described in RFC 8089, such as URIs generated by `pathlib.Path.as_uri()` and `urllib.request.pathname2url()`.
The method is added to `Path` rather than `PurePath` because it uses `os.fsdecode()`, and so its results vary from system to system. I intend to deprecate `PurePath.as_uri()` and move it to `Path` for the same reason.
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
|
|
|
|
|
| |
Add private `pathlib._PathBase` class. This will be used by an experimental PyPI package to incubate a `tarfile.TarPath` class.
Co-authored-by: Adam Turner <9087854+AA-Turner@users.noreply.github.com>
|
|
|
|
| |
Treat symlink loops like other errors: in strict mode, raise `OSError`, and
in non-strict mode, do not raise any exception.
|
|
|
|
|
|
|
| |
(#107320)
`pathlib.Path.iterdir()` now immediately raises any `OSError`
exception from `os.listdir()`, rather than waiting until its
result is iterated over.
|
|
|
|
|
|
| |
(GH-105413)
In a future Python release, patterns with this ending will match both files
and directories. Users may add a trailing slash to remove the warning.
|
|
|
|
| |
It makes sense to raise an Error because ".." can not
be resolved and the current working directory is unknown.
|
|
|
|
| |
This instance attribute stores the implementation of `os.path` used for
low-level path operations: either `posixpath` or `ntpath`.
|
|
|
|
|
| |
We match paths using the `_lines` attribute, which is derived from the
path's string representation. The bug arises because an empty path's string
representation is `'.'` (not `''`), which is matched by the `'*'` wildcard.
|
|
|
|
|
| |
Make assertions about the `st_mode`, `st_ino` and `st_dev` attributes of
the stat results from two files and a directory, rather than checking if
`chmod()` affects `st_mode` (which is already tested elsewhere).
|
|
|
|
|
|
|
| |
- Split out dedicated test for unbuffered `open()`
- Split out dedicated test for `is_mount()` at the filesystem root
- Avoid `os.stat()` when checking that empty paths point to '.'
- Remove unnecessary `rmtree()` call
- Remove unused `assertSame()` method
|
|
|
|
| |
Slightly expand the test coverage of `is_junction()`. The existing test
only checks that `os.path.isjunction()` is called under-the-hood.
|
|
|
|
|
|
|
| |
Adjust the pathlib tests to add a new `PathTest.can_symlink` class
attribute, which allows us to enable or disable symlink support in tests.
A (near-)future commit will add an `AbstractPath` class; its tests will
hard-code the value to `True` or `False` depending on a stub subclass's
capabilities.
|
|
|
|
|
|
| |
Remove `PathTest.dirlink()` function. Symlinks in `PathTest.setUp()` are
created using `os.symlink()` directly; symlinks in test functions use
`Path.symlink_to()` in order to make the tests applicable to a
(near-)future `AbstractPath` class.
|
|
|
|
|
|
|
| |
`is_file()` (GH-105794)
Brings `pathlib.Path.is_dir()` and `in line with `os.DirEntry.is_dir()`, which
will be important for implementing generic path walking and globbing.
Likewise `is_file()`.
|
|
|
|
|
|
|
| |
This new exception type is raised instead of `NotImplementedError` when
a path operation is not supported. It can be raised from `Path.readlink()`,
`symlink_to()`, `hardlink_to()`, `owner()` and `group()`. In a future
version of pathlib, it will be raised by `AbstractPath` for these methods
and others, such as `AbstractPath.mkdir()` and `unlink()`.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Re-arrange `pathlib.Path` test methods in source code. No other changes.
The test methods are arranged in two groups. The first group checks
`stat()`, `open()`, `iterdir()`, `readlink()`, and derived methods like
`exists()`, `read_text()`, `glob()` and `resolve()`. The second group
checks all other `Path` methods. To minimise the diff I've maintained the
method order within groups where possible.
This patch prepares the ground for a new `_AbstractPath` class, which will
support methods in the first group above. By churning the test methods
here, subsequent patches will be easier to review and less likely to break
things.
|
|
|
|
|
|
| |
Clean up pathlib tests.
Merge `PurePathTest` into `_BasePurePathTest`, and `PathTest` into
`_BasePathTest`.
|
|
|
|
| |
(#105744)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This commit introduces a 'walk-and-match' strategy for handling glob patterns that include a non-terminal `**` wildcard, such as `**/*.py`. For this example, the previous implementation recursively walked directories using `os.scandir()` when it expanded the `**` component, and then **scanned those same directories again** when expanded the `*.py` component. This is wasteful.
In the new implementation, any components following a `**` wildcard are used to build a `re.Pattern` object, which is used to filter the results of the recursive walk. A pattern like `**/*.py` uses half the number of `os.scandir()` calls; a pattern like `**/*/*.py` a third, etc.
This new algorithm does not apply if either:
1. The *follow_symlinks* argument is set to `None` (its default), or
2. The pattern contains `..` components.
In these cases we fall back to the old implementation.
This commit also replaces selector classes with selector functions. These generators directly yield results rather calling through to their successors. A new internal `Path._glob()` method takes care to chain these generators together, which simplifies the lazy algorithm and slightly improves performance. It should also be easier to understand and maintain.
|
| |
|
|
|
|
|
|
|
|
| |
`PurePath.match()` now handles the `**` wildcard as in `Path.glob()`, i.e. it matches any number of path segments.
We now compile a `re.Pattern` object for the entire pattern. This is made more difficult by `fnmatch` not treating directory separators as special when evaluating wildcards (`*`, `?`, etc), and so we arrange the path parts onto separate *lines* in a string, and ensure we don't set `re.DOTALL`.
Co-authored-by: Hugo van Kemenade <hugovk@users.noreply.github.com>
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
|
|
|
|
|
| |
Add a keyword-only *follow_symlinks* parameter to `pathlib.Path.glob()` and`rglob()`.
When *follow_symlinks* is `None` (the default), these methods follow symlinks except when evaluating "`**`" wildcards. When set to true or false, symlinks are always or never followed, respectively.
|
|
|
|
|
|
|
|
|
| |
(GH-104949)
For backwards compatibility, accept backslashes as path separators in
`PurePosixPath` if an instance of `PureWindowsPath` is supplied.
This restores behaviour from Python 3.11.
Co-authored-by: Gregory P. Smith <greg@krypto.org>
|
|
|
|
|
|
|
|
| |
platforms (GH-104948)
Use `str.lower()` rather than `ntpath.normcase()` to normalize case of
Windows paths. This restores behaviour from Python 3.11.
Co-authored-by: Gregory P. Smith <greg@krypto.org>
|
|
|
|
|
|
|
|
|
|
| |
(GH-104807)
In Python 3.8 and prior, `pathlib.Path.__exit__()` marked a path as closed;
some subsequent attempts to perform I/O would raise an IOError. This
functionality was never documented, and had the effect of making `Path`
objects mutable, contrary to PEP 428. In Python 3.9 we made `__exit__()` a
no-op, and in 3.11 `__enter__()` began raising deprecation warnings. Here
we remove both methods.
|
|
|
| |
Co-authored-by: Barney Gale <barney.gale@gmail.com>
|
|
|
|
| |
Use `Path.walk()` to implement the recursive wildcard `**`. This method
uses an iterative (rather than recursive) walk - see GH-100282.
|
|
|
|
|
|
|
|
|
|
|
| |
`pathlib.Path.glob()` now suppresses all OSError exceptions, except
those raised from calling `is_dir()` on the top-level path.
Previously, `glob()` suppressed ENOENT, ENOTDIR, EBADF and ELOOP
errors and their Windows equivalents. PermissionError was also
suppressed unless it occurred when calling `is_dir()` on the
top-level path. However, the selector would abort prematurely
if a PermissionError was raised, and so `glob()` could return
incomplete results.
|
|
|
|
| |
Fix issue where `pathlib.Path.glob()` raised `OSError` when it encountered
a symlink to an overly long path.
|
|
|
|
|
|
|
|
|
|
| |
Stop de-duplicating results in `_RecursiveWildcardSelector`. A new
`_DoubleRecursiveWildcardSelector` class is introduced which performs
de-duplication, but this is used _only_ for patterns with multiple
non-adjacent `**` segments, such as `path.glob('**/foo/**')`. By avoiding
the use of a set, `PurePath.__hash__()` is not called, and so paths do not
need to be stringified and case-normalised.
Also merge adjacent '**' segments in patterns.
|
| |
|
|
|
|
|
| |
Add `pathlib.PurePath.with_segments()`, which creates a path object from arguments. This method is called whenever a derivative path is created, such as from `pathlib.PurePath.parent`. Subclasses may override this method to share information between path objects.
Co-authored-by: Alex Waygood <Alex.Waygood@Gmail.com>
|
|
|
|
|
|
| |
This argument allows case-sensitive matching to be enabled on Windows, and
case-insensitive matching to be enabled on Posix.
Co-authored-by: Steve Dower <steve.dower@microsoft.com>
|
|
|
|
|
|
|
|
|
| |
case (GH-104116)
We now use `_WildcardSelector` to evaluate literal pattern segments, which
allows us to retrieve the real filesystem case.
This change is necessary in order to implement a *case_sensitive* argument
(see GH-81079) and a *follow_symlinks* argument (see GH-77609).
|
|
|
|
|
| |
precise match (GH-29655)
Co-authored-by: Barney Gale <barney.gale@gmail.com>
|
|
|
|
|
|
|
|
| |
(GH-104103)
These segments do not require a `stat()` call, as the selector's
`_select_from()` method is called after we've established that the
parent is a directory.
|