Skip to content
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

[3.12] gh-118507 : Speed up ntpath.isjunction() & ntpath.lexists() with native helpers (GH-118755) #119420

Closed
Closed
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Speedup os.path.isjunction and os.path.lexists on Windows with a …
…native implementation.
  • Loading branch information
nineteendo committed May 22, 2024
commit ecf8d3f91642c263cfd90c76522adfbcb6bf445e
22 changes: 8 additions & 14 deletions Lib/ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -279,19 +279,11 @@ def dirname(p):

# Is a path a junction?

if hasattr(os.stat_result, 'st_reparse_tag'):
def isjunction(path):
"""Test whether a path is a junction"""
try:
st = os.lstat(path)
except (OSError, ValueError, AttributeError):
return False
return bool(st.st_reparse_tag == stat.IO_REPARSE_TAG_MOUNT_POINT)
else:
def isjunction(path):
"""Test whether a path is a junction"""
os.fspath(path)
return False
def isjunction(path):
"""Test whether a path is a junction
Junctions are not supported on the current platform"""
os.fspath(path)
return False


# Being true for dangling symbolic links is also useful.
Expand Down Expand Up @@ -875,9 +867,11 @@ def commonpath(paths):
from nt import _path_isdir as isdir
from nt import _path_isfile as isfile
from nt import _path_islink as islink
from nt import _path_isjunction as isjunction
from nt import _path_exists as exists
from nt import _path_lexists as lexists
except ImportError:
# Use genericpath.* as imported above
# Use Python version or genericpath.* as imported above
pass


Expand Down
4 changes: 4 additions & 0 deletions Lib/test/test_ntpath.py
Original file line number Diff line number Diff line change
Expand Up @@ -1016,8 +1016,12 @@ def test_fast_paths_in_use(self):
self.assertFalse(inspect.isfunction(os.path.isfile))
self.assertTrue(os.path.islink is nt._path_islink)
self.assertFalse(inspect.isfunction(os.path.islink))
self.assertTrue(os.path.isjunction is nt._path_isjunction)
self.assertFalse(inspect.isfunction(os.path.isjunction))
self.assertTrue(os.path.exists is nt._path_exists)
self.assertFalse(inspect.isfunction(os.path.exists))
self.assertTrue(os.path.lexists is nt._path_lexists)
self.assertFalse(inspect.isfunction(os.path.lexists))

@unittest.skipIf(os.name != 'nt', "Dev Drives only exist on Win32")
def test_isdevdrive(self):
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Speedup :func:`os.path.isjunction` and :func:`os.path.lexists` on Windows with a native implementation.
106 changes: 105 additions & 1 deletion Modules/clinic/posixmodule.c.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

38 changes: 38 additions & 0 deletions Modules/posixmodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -5165,6 +5165,25 @@ os__path_exists_impl(PyObject *module, PyObject *path)
}


/*[clinic input]
os._path_lexists -> bool

path: object
/

Test whether a path exists. Returns True for broken symbolic links.

[clinic start generated code]*/

static int
os__path_lexists_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=fec4a91cf4ffccf1 input=8843d4d6d4e7c779]*/
{
path_t _path = PATH_T_INITIALIZE("_path_lexists", "path", 0, 1);
return _testFileExists(&_path, path, FALSE);
}


/*[clinic input]
os._path_isdir -> bool

Expand Down Expand Up @@ -5218,6 +5237,23 @@ os__path_islink_impl(PyObject *module, PyObject *path)
return _testFileType(&_path, path, PY_IFLNK);
}

/*[clinic input]
os._path_isjunction -> bool

path: object

Test whether a path is a junction

[clinic start generated code]*/

static int
os__path_isjunction_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=f1d51682a077654d input=103ccedcdb714f11]*/
{
path_t _path = PATH_T_INITIALIZE("_path_isjunction", "path", 0, 1);
return _testFileType(&_path, path, PY_IFMNT);
}

#undef PY_IFREG
#undef PY_IFDIR
#undef PY_IFLNK
Expand Down Expand Up @@ -16009,7 +16045,9 @@ static PyMethodDef posix_methods[] = {
OS__PATH_ISDIR_METHODDEF
OS__PATH_ISFILE_METHODDEF
OS__PATH_ISLINK_METHODDEF
OS__PATH_ISJUNCTION_METHODDEF
OS__PATH_EXISTS_METHODDEF
OS__PATH_LEXISTS_METHODDEF
{NULL, NULL} /* Sentinel */
};

Expand Down
Loading