gh-118263: Add additional arguments to path_t (Argument Clinic type) in posixmodule (GH-118355)

(cherry picked from commit 96b392df30)

Co-authored-by: Nice Zombies <nineteendo19d0@gmail.com>
This commit is contained in:
Miss Islington (bot) 2024-05-24 20:26:06 +02:00 committed by GitHub
parent 217d57fc3c
commit cc38ee1edb
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
7 changed files with 390 additions and 360 deletions

View File

@ -168,19 +168,12 @@ def splitdrive(p):
try:
from nt import _path_splitroot_ex
from nt import _path_splitroot_ex as splitroot
except ImportError:
def splitroot(p):
"""Split a pathname into drive, root and tail. The drive is defined
exactly as in splitdrive(). On Windows, the root may be a single path
separator or an empty string. The tail contains anything after the root.
For example:
"""Split a pathname into drive, root and tail.
splitroot('//server/share/') == ('//server/share', '/', '')
splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney')
splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham')
splitroot('Windows/notepad') == ('', '', 'Windows/notepad')
"""
The tail contains anything after the root."""
p = os.fspath(p)
if isinstance(p, bytes):
sep = b'\\'
@ -220,23 +213,6 @@ except ImportError:
else:
# Relative path, e.g. Windows
return empty, empty, p
else:
def splitroot(p):
"""Split a pathname into drive, root and tail. The drive is defined
exactly as in splitdrive(). On Windows, the root may be a single path
separator or an empty string. The tail contains anything after the root.
For example:
splitroot('//server/share/') == ('//server/share', '/', '')
splitroot('C:/Users/Barney') == ('C:', '/', 'Users/Barney')
splitroot('C:///spam///ham') == ('C:', '/', '//spam///ham')
splitroot('Windows/notepad') == ('', '', 'Windows/notepad')
"""
p = os.fspath(p)
if isinstance(p, bytes):
drive, root, tail = _path_splitroot_ex(os.fsdecode(p))
return os.fsencode(drive), os.fsencode(root), os.fsencode(tail)
return _path_splitroot_ex(p)
# Split a path in head (everything up to the last '/') and tail (the
@ -538,7 +514,7 @@ def expandvars(path):
# Previously, this function also truncated pathnames to 8+3 format,
# but as this module is called "ntpath", that's obviously wrong!
try:
from nt import _path_normpath
from nt import _path_normpath as normpath
except ImportError:
def normpath(path):
@ -577,14 +553,6 @@ except ImportError:
comps.append(curdir)
return prefix + sep.join(comps)
else:
def normpath(path):
"""Normalize path, eliminating double slashes, etc."""
path = os.fspath(path)
if isinstance(path, bytes):
return os.fsencode(_path_normpath(os.fsdecode(path))) or b"."
return _path_normpath(path) or "."
def _abspath_fallback(path):
"""Return the absolute version of a path as a fallback function in case

View File

@ -135,18 +135,12 @@ def splitdrive(p):
try:
from posix import _path_splitroot_ex
from posix import _path_splitroot_ex as splitroot
except ImportError:
def splitroot(p):
"""Split a pathname into drive, root and tail. On Posix, drive is always
empty; the root may be empty, a single slash, or two slashes. The tail
contains anything after the root. For example:
"""Split a pathname into drive, root and tail.
splitroot('foo/bar') == ('', '', 'foo/bar')
splitroot('/foo/bar') == ('', '/', 'foo/bar')
splitroot('//foo/bar') == ('', '//', 'foo/bar')
splitroot('///foo/bar') == ('', '/', '//foo/bar')
"""
The tail contains anything after the root."""
p = os.fspath(p)
if isinstance(p, bytes):
sep = b'/'
@ -164,23 +158,6 @@ except ImportError:
# Precisely two leading slashes, e.g.: '//foo'. Implementation defined per POSIX, see
# https://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap04.html#tag_04_13
return empty, p[:2], p[2:]
else:
def splitroot(p):
"""Split a pathname into drive, root and tail. On Posix, drive is always
empty; the root may be empty, a single slash, or two slashes. The tail
contains anything after the root. For example:
splitroot('foo/bar') == ('', '', 'foo/bar')
splitroot('/foo/bar') == ('', '/', 'foo/bar')
splitroot('//foo/bar') == ('', '//', 'foo/bar')
splitroot('///foo/bar') == ('', '/', '//foo/bar')
"""
p = os.fspath(p)
if isinstance(p, bytes):
# Optimisation: the drive is always empty
_, root, tail = _path_splitroot_ex(os.fsdecode(p))
return b'', os.fsencode(root), os.fsencode(tail)
return _path_splitroot_ex(p)
# Return the tail (basename) part of a path, same as split(path)[1].
@ -363,7 +340,7 @@ def expandvars(path):
# if it contains symbolic links!
try:
from posix import _path_normpath
from posix import _path_normpath as normpath
except ImportError:
def normpath(path):
@ -394,14 +371,6 @@ except ImportError:
path = initial_slashes + sep.join(comps)
return path or dot
else:
def normpath(path):
"""Normalize path, eliminating double slashes, etc."""
path = os.fspath(path)
if isinstance(path, bytes):
return os.fsencode(_path_normpath(os.fsdecode(path))) or b"."
return _path_normpath(path) or "."
def abspath(path):
"""Return an absolute path."""

View File

@ -1129,6 +1129,10 @@ class TestNtpath(NtpathTestCase):
# There are fast paths of these functions implemented in posixmodule.c.
# Confirm that they are being used, and not the Python fallbacks in
# genericpath.py.
self.assertTrue(os.path.splitroot is nt._path_splitroot_ex)
self.assertFalse(inspect.isfunction(os.path.splitroot))
self.assertTrue(os.path.normpath is nt._path_normpath)
self.assertFalse(inspect.isfunction(os.path.normpath))
self.assertTrue(os.path.isdir is nt._path_isdir)
self.assertFalse(inspect.isfunction(os.path.isdir))
self.assertTrue(os.path.isfile is nt._path_isfile)

View File

@ -1,3 +1,4 @@
import inspect
import os
import posixpath
import sys
@ -5,7 +6,7 @@ import unittest
from posixpath import realpath, abspath, dirname, basename
from test import test_genericpath
from test.support import import_helper
from test.support import os_helper
from test.support import cpython_only, os_helper
from test.support.os_helper import FakePath
from unittest import mock
@ -283,6 +284,16 @@ class PosixPathTest(unittest.TestCase):
def test_isjunction(self):
self.assertFalse(posixpath.isjunction(ABSTFN))
@unittest.skipIf(sys.platform == 'win32', "Fast paths are not for win32")
@cpython_only
def test_fast_paths_in_use(self):
# There are fast paths of these functions implemented in posixmodule.c.
# Confirm that they are being used, and not the Python fallbacks
self.assertTrue(os.path.splitroot is posix._path_splitroot_ex)
self.assertFalse(inspect.isfunction(os.path.splitroot))
self.assertTrue(os.path.normpath is posix._path_normpath)
self.assertFalse(inspect.isfunction(os.path.normpath))
def test_expanduser(self):
self.assertEqual(posixpath.expanduser("foo"), "foo")
self.assertEqual(posixpath.expanduser(b"foo"), b"foo")

View File

@ -0,0 +1 @@
Speed up :func:`os.path.splitroot` & :func:`os.path.normpath` with a direct C call.

View File

@ -72,7 +72,7 @@ os_stat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn
#undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("stat", "path", 0, 1);
path_t path = PATH_T_INITIALIZE_P("stat", "path", 0, 0, 0, 1);
int dir_fd = DEFAULT_DIR_FD;
int follow_symlinks = 1;
@ -154,7 +154,7 @@ os_lstat(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("lstat", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("lstat", "path", 0, 0, 0, 0);
int dir_fd = DEFAULT_DIR_FD;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
@ -250,7 +250,7 @@ os_access(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
#undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t path = PATH_T_INITIALIZE("access", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("access", "path", 0, 0, 0, 0);
int mode;
int dir_fd = DEFAULT_DIR_FD;
int effective_ids = 0;
@ -409,7 +409,7 @@ os_chdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("chdir", "path", 0, PATH_HAVE_FCHDIR);
path_t path = PATH_T_INITIALIZE_P("chdir", "path", 0, 0, 0, PATH_HAVE_FCHDIR);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -560,7 +560,7 @@ os_chmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t path = PATH_T_INITIALIZE("chmod", "path", 0, PATH_HAVE_FCHMOD);
path_t path = PATH_T_INITIALIZE_P("chmod", "path", 0, 0, 0, PATH_HAVE_FCHMOD);
int mode;
int dir_fd = DEFAULT_DIR_FD;
int follow_symlinks = CHMOD_DEFAULT_FOLLOW_SYMLINKS;
@ -725,7 +725,7 @@ os_lchmod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
};
#undef KWTUPLE
PyObject *argsbuf[2];
path_t path = PATH_T_INITIALIZE("lchmod", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("lchmod", "path", 0, 0, 0, 0);
int mode;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
@ -802,7 +802,7 @@ os_chflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
#undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t path = PATH_T_INITIALIZE("chflags", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("chflags", "path", 0, 0, 0, 0);
unsigned long flags;
int follow_symlinks = 1;
@ -884,7 +884,7 @@ os_lchflags(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
};
#undef KWTUPLE
PyObject *argsbuf[2];
path_t path = PATH_T_INITIALIZE("lchflags", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("lchflags", "path", 0, 0, 0, 0);
unsigned long flags;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
@ -954,7 +954,7 @@ os_chroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("chroot", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("chroot", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -1190,7 +1190,7 @@ os_chown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
path_t path = PATH_T_INITIALIZE("chown", "path", 0, PATH_HAVE_FCHOWN);
path_t path = PATH_T_INITIALIZE_P("chown", "path", 0, 0, 0, PATH_HAVE_FCHOWN);
uid_t uid;
gid_t gid;
int dir_fd = DEFAULT_DIR_FD;
@ -1355,7 +1355,7 @@ os_lchown(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
};
#undef KWTUPLE
PyObject *argsbuf[3];
path_t path = PATH_T_INITIALIZE("lchown", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("lchown", "path", 0, 0, 0, 0);
uid_t uid;
gid_t gid;
@ -1476,8 +1476,8 @@ os_link(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn
#undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t src = PATH_T_INITIALIZE("link", "src", 0, 0);
path_t dst = PATH_T_INITIALIZE("link", "dst", 0, 0);
path_t src = PATH_T_INITIALIZE_P("link", "src", 0, 0, 0, 0);
path_t dst = PATH_T_INITIALIZE_P("link", "dst", 0, 0, 0, 0);
int src_dir_fd = DEFAULT_DIR_FD;
int dst_dir_fd = DEFAULT_DIR_FD;
int follow_symlinks = 1;
@ -1583,7 +1583,7 @@ os_listdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
#undef KWTUPLE
PyObject *argsbuf[1];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
path_t path = PATH_T_INITIALIZE("listdir", "path", 1, PATH_HAVE_FDOPENDIR);
path_t path = PATH_T_INITIALIZE_P("listdir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
if (!args) {
@ -1699,7 +1699,7 @@ os_listmounts(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObjec
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t volume = PATH_T_INITIALIZE("listmounts", "volume", 0, 0);
path_t volume = PATH_T_INITIALIZE_P("listmounts", "volume", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -1763,7 +1763,7 @@ os__path_isdevdrive(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("_path_isdevdrive", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_path_isdevdrive", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -1800,7 +1800,7 @@ static PyObject *
os__getfullpathname(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
path_t path = PATH_T_INITIALIZE("_getfullpathname", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_getfullpathname", "path", 0, 0, 0, 0);
if (!path_converter(arg, &path)) {
goto exit;
@ -1834,7 +1834,7 @@ static PyObject *
os__getfinalpathname(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
path_t path = PATH_T_INITIALIZE("_getfinalpathname", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_getfinalpathname", "path", 0, 0, 0, 0);
if (!path_converter(arg, &path)) {
goto exit;
@ -1868,7 +1868,7 @@ static PyObject *
os__findfirstfile(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
path_t path = PATH_T_INITIALIZE("_findfirstfile", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_findfirstfile", "path", 0, 0, 0, 0);
if (!path_converter(arg, &path)) {
goto exit;
@ -1928,7 +1928,7 @@ os__getvolumepathname(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("_getvolumepathname", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_getvolumepathname", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -1992,7 +1992,7 @@ os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, Py
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("_path_splitroot", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_path_splitroot", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -2024,21 +2024,28 @@ PyDoc_STRVAR(os__path_exists__doc__,
{"_path_exists", (PyCFunction)os__path_exists, METH_O, os__path_exists__doc__},
static int
os__path_exists_impl(PyObject *module, PyObject *path);
os__path_exists_impl(PyObject *module, path_t *path);
static PyObject *
os__path_exists(PyObject *module, PyObject *path)
os__path_exists(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
path_t path = PATH_T_INITIALIZE_P("_path_exists", "path", 0, 0, 1, 1);
int _return_value;
_return_value = os__path_exists_impl(module, path);
if (!path_converter(arg, &path)) {
goto exit;
}
_return_value = os__path_exists_impl(module, &path);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2056,21 +2063,28 @@ PyDoc_STRVAR(os__path_lexists__doc__,
{"_path_lexists", (PyCFunction)os__path_lexists, METH_O, os__path_lexists__doc__},
static int
os__path_lexists_impl(PyObject *module, PyObject *path);
os__path_lexists_impl(PyObject *module, path_t *path);
static PyObject *
os__path_lexists(PyObject *module, PyObject *path)
os__path_lexists(PyObject *module, PyObject *arg)
{
PyObject *return_value = NULL;
path_t path = PATH_T_INITIALIZE_P("_path_lexists", "path", 0, 0, 1, 1);
int _return_value;
_return_value = os__path_lexists_impl(module, path);
if (!path_converter(arg, &path)) {
goto exit;
}
_return_value = os__path_lexists_impl(module, &path);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2088,7 +2102,7 @@ PyDoc_STRVAR(os__path_isdir__doc__,
{"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__},
static int
os__path_isdir_impl(PyObject *module, PyObject *path);
os__path_isdir_impl(PyObject *module, path_t *path);
static PyObject *
os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -2120,21 +2134,26 @@ os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
};
#undef KWTUPLE
PyObject *argsbuf[1];
PyObject *path;
path_t path = PATH_T_INITIALIZE_P("_path_isdir", "path", 0, 0, 1, 1);
int _return_value;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
path = args[0];
_return_value = os__path_isdir_impl(module, path);
if (!path_converter(args[0], &path)) {
goto exit;
}
_return_value = os__path_isdir_impl(module, &path);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2152,7 +2171,7 @@ PyDoc_STRVAR(os__path_isfile__doc__,
{"_path_isfile", _PyCFunction_CAST(os__path_isfile), METH_FASTCALL|METH_KEYWORDS, os__path_isfile__doc__},
static int
os__path_isfile_impl(PyObject *module, PyObject *path);
os__path_isfile_impl(PyObject *module, path_t *path);
static PyObject *
os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -2184,21 +2203,26 @@ os__path_isfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
};
#undef KWTUPLE
PyObject *argsbuf[1];
PyObject *path;
path_t path = PATH_T_INITIALIZE_P("_path_isfile", "path", 0, 0, 1, 1);
int _return_value;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
path = args[0];
_return_value = os__path_isfile_impl(module, path);
if (!path_converter(args[0], &path)) {
goto exit;
}
_return_value = os__path_isfile_impl(module, &path);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2216,7 +2240,7 @@ PyDoc_STRVAR(os__path_islink__doc__,
{"_path_islink", _PyCFunction_CAST(os__path_islink), METH_FASTCALL|METH_KEYWORDS, os__path_islink__doc__},
static int
os__path_islink_impl(PyObject *module, PyObject *path);
os__path_islink_impl(PyObject *module, path_t *path);
static PyObject *
os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -2248,21 +2272,26 @@ os__path_islink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
};
#undef KWTUPLE
PyObject *argsbuf[1];
PyObject *path;
path_t path = PATH_T_INITIALIZE_P("_path_islink", "path", 0, 0, 1, 1);
int _return_value;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
path = args[0];
_return_value = os__path_islink_impl(module, path);
if (!path_converter(args[0], &path)) {
goto exit;
}
_return_value = os__path_islink_impl(module, &path);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2280,7 +2309,7 @@ PyDoc_STRVAR(os__path_isjunction__doc__,
{"_path_isjunction", _PyCFunction_CAST(os__path_isjunction), METH_FASTCALL|METH_KEYWORDS, os__path_isjunction__doc__},
static int
os__path_isjunction_impl(PyObject *module, PyObject *path);
os__path_isjunction_impl(PyObject *module, path_t *path);
static PyObject *
os__path_isjunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -2312,21 +2341,26 @@ os__path_isjunction(PyObject *module, PyObject *const *args, Py_ssize_t nargs, P
};
#undef KWTUPLE
PyObject *argsbuf[1];
PyObject *path;
path_t path = PATH_T_INITIALIZE_P("_path_isjunction", "path", 0, 0, 1, 1);
int _return_value;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
path = args[0];
_return_value = os__path_isjunction_impl(module, path);
if (!path_converter(args[0], &path)) {
goto exit;
}
_return_value = os__path_isjunction_impl(module, &path);
if ((_return_value == -1) && PyErr_Occurred()) {
goto exit;
}
return_value = PyBool_FromLong((long)_return_value);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2335,13 +2369,16 @@ exit:
PyDoc_STRVAR(os__path_splitroot_ex__doc__,
"_path_splitroot_ex($module, /, path)\n"
"--\n"
"\n");
"\n"
"Split a pathname into drive, root and tail.\n"
"\n"
"The tail contains anything after the root.");
#define OS__PATH_SPLITROOT_EX_METHODDEF \
{"_path_splitroot_ex", _PyCFunction_CAST(os__path_splitroot_ex), METH_FASTCALL|METH_KEYWORDS, os__path_splitroot_ex__doc__},
static PyObject *
os__path_splitroot_ex_impl(PyObject *module, PyObject *path);
os__path_splitroot_ex_impl(PyObject *module, path_t *path);
static PyObject *
os__path_splitroot_ex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -2373,20 +2410,21 @@ os__path_splitroot_ex(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
};
#undef KWTUPLE
PyObject *argsbuf[1];
PyObject *path;
path_t path = PATH_T_INITIALIZE("_path_splitroot_ex", "path", 0, 1, 1, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
if (!PyUnicode_Check(args[0])) {
_PyArg_BadArgument("_path_splitroot_ex", "argument 'path'", "str", args[0]);
if (!path_converter(args[0], &path)) {
goto exit;
}
path = args[0];
return_value = os__path_splitroot_ex_impl(module, path);
return_value = os__path_splitroot_ex_impl(module, &path);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2394,13 +2432,13 @@ PyDoc_STRVAR(os__path_normpath__doc__,
"_path_normpath($module, /, path)\n"
"--\n"
"\n"
"Basic path normalization.");
"Normalize path, eliminating double slashes, etc.");
#define OS__PATH_NORMPATH_METHODDEF \
{"_path_normpath", _PyCFunction_CAST(os__path_normpath), METH_FASTCALL|METH_KEYWORDS, os__path_normpath__doc__},
static PyObject *
os__path_normpath_impl(PyObject *module, PyObject *path);
os__path_normpath_impl(PyObject *module, path_t *path);
static PyObject *
os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames)
@ -2432,16 +2470,21 @@ os__path_normpath(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyO
};
#undef KWTUPLE
PyObject *argsbuf[1];
PyObject *path;
path_t path = PATH_T_INITIALIZE("_path_normpath", "path", 0, 1, 1, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
goto exit;
}
path = args[0];
return_value = os__path_normpath_impl(module, path);
if (!path_converter(args[0], &path)) {
goto exit;
}
return_value = os__path_normpath_impl(module, &path);
exit:
/* Cleanup for path */
path_cleanup(&path);
return return_value;
}
@ -2496,7 +2539,7 @@ os_mkdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("mkdir", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("mkdir", "path", 0, 0, 0, 0);
int mode = 511;
int dir_fd = DEFAULT_DIR_FD;
@ -2757,8 +2800,8 @@ os_rename(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
#undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t src = PATH_T_INITIALIZE("rename", "src", 0, 0);
path_t dst = PATH_T_INITIALIZE("rename", "dst", 0, 0);
path_t src = PATH_T_INITIALIZE_P("rename", "src", 0, 0, 0, 0);
path_t dst = PATH_T_INITIALIZE_P("rename", "dst", 0, 0, 0, 0);
int src_dir_fd = DEFAULT_DIR_FD;
int dst_dir_fd = DEFAULT_DIR_FD;
@ -2848,8 +2891,8 @@ os_replace(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
#undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t src = PATH_T_INITIALIZE("replace", "src", 0, 0);
path_t dst = PATH_T_INITIALIZE("replace", "dst", 0, 0);
path_t src = PATH_T_INITIALIZE_P("replace", "src", 0, 0, 0, 0);
path_t dst = PATH_T_INITIALIZE_P("replace", "dst", 0, 0, 0, 0);
int src_dir_fd = DEFAULT_DIR_FD;
int dst_dir_fd = DEFAULT_DIR_FD;
@ -2937,7 +2980,7 @@ os_rmdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("rmdir", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("rmdir", "path", 0, 0, 0, 0);
int dir_fd = DEFAULT_DIR_FD;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
@ -3186,7 +3229,7 @@ os_unlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("unlink", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("unlink", "path", 0, 0, 0, 0);
int dir_fd = DEFAULT_DIR_FD;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
@ -3260,7 +3303,7 @@ os_remove(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("remove", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("remove", "path", 0, 0, 0, 0);
int dir_fd = DEFAULT_DIR_FD;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
@ -3378,7 +3421,7 @@ os_utime(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("utime", "path", 0, PATH_UTIME_HAVE_FD);
path_t path = PATH_T_INITIALIZE_P("utime", "path", 0, 0, 0, PATH_UTIME_HAVE_FD);
PyObject *times = Py_None;
PyObject *ns = NULL;
int dir_fd = DEFAULT_DIR_FD;
@ -3513,7 +3556,7 @@ static PyObject *
os_execv(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
path_t path = PATH_T_INITIALIZE("execv", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("execv", "path", 0, 0, 0, 0);
PyObject *argv;
if (!_PyArg_CheckPositional("execv", nargs, 2, 2)) {
@ -3585,7 +3628,7 @@ os_execve(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
};
#undef KWTUPLE
PyObject *argsbuf[3];
path_t path = PATH_T_INITIALIZE("execve", "path", 0, PATH_HAVE_FEXECVE);
path_t path = PATH_T_INITIALIZE_P("execve", "path", 0, 0, 0, PATH_HAVE_FEXECVE);
PyObject *argv;
PyObject *env;
@ -3681,7 +3724,7 @@ os_posix_spawn(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
#undef KWTUPLE
PyObject *argsbuf[10];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
path_t path = PATH_T_INITIALIZE("posix_spawn", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("posix_spawn", "path", 0, 0, 0, 0);
PyObject *argv;
PyObject *env;
PyObject *file_actions = NULL;
@ -3831,7 +3874,7 @@ os_posix_spawnp(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObj
#undef KWTUPLE
PyObject *argsbuf[10];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
path_t path = PATH_T_INITIALIZE("posix_spawnp", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("posix_spawnp", "path", 0, 0, 0, 0);
PyObject *argv;
PyObject *env;
PyObject *file_actions = NULL;
@ -3935,7 +3978,7 @@ os_spawnv(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
int mode;
path_t path = PATH_T_INITIALIZE("spawnv", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("spawnv", "path", 0, 0, 0, 0);
PyObject *argv;
if (!_PyArg_CheckPositional("spawnv", nargs, 3, 3)) {
@ -3989,7 +4032,7 @@ os_spawnve(PyObject *module, PyObject *const *args, Py_ssize_t nargs)
{
PyObject *return_value = NULL;
int mode;
path_t path = PATH_T_INITIALIZE("spawnve", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("spawnve", "path", 0, 0, 0, 0);
PyObject *argv;
PyObject *env;
@ -6165,7 +6208,7 @@ os_readlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("readlink", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("readlink", "path", 0, 0, 0, 0);
int dir_fd = DEFAULT_DIR_FD;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
@ -6249,8 +6292,8 @@ os_symlink(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
#undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t src = PATH_T_INITIALIZE("symlink", "src", 0, 0);
path_t dst = PATH_T_INITIALIZE("symlink", "dst", 0, 0);
path_t src = PATH_T_INITIALIZE_P("symlink", "src", 0, 0, 0, 0);
path_t dst = PATH_T_INITIALIZE_P("symlink", "dst", 0, 0, 0, 0);
int target_is_directory = 0;
int dir_fd = DEFAULT_DIR_FD;
@ -6892,7 +6935,7 @@ os_open(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwn
#undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t path = PATH_T_INITIALIZE("open", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("open", "path", 0, 0, 0, 0);
int flags;
int mode = 511;
int dir_fd = DEFAULT_DIR_FD;
@ -8480,7 +8523,7 @@ os_mkfifo(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *k
#undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("mkfifo", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("mkfifo", "path", 0, 0, 0, 0);
int mode = 438;
int dir_fd = DEFAULT_DIR_FD;
@ -8580,7 +8623,7 @@ os_mknod(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kw
#undef KWTUPLE
PyObject *argsbuf[4];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t path = PATH_T_INITIALIZE("mknod", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("mknod", "path", 0, 0, 0, 0);
int mode = 384;
dev_t device = 0;
int dir_fd = DEFAULT_DIR_FD;
@ -8834,7 +8877,7 @@ os_truncate(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
};
#undef KWTUPLE
PyObject *argsbuf[2];
path_t path = PATH_T_INITIALIZE("truncate", "path", 0, PATH_HAVE_FTRUNCATE);
path_t path = PATH_T_INITIALIZE_P("truncate", "path", 0, 0, 0, PATH_HAVE_FTRUNCATE);
Py_off_t length;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
@ -9733,7 +9776,7 @@ os_statvfs(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("statvfs", "path", 0, PATH_HAVE_FSTATVFS);
path_t path = PATH_T_INITIALIZE_P("statvfs", "path", 0, 0, 0, PATH_HAVE_FSTATVFS);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -9797,7 +9840,7 @@ os__getdiskusage(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyOb
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("_getdiskusage", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_getdiskusage", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -9911,7 +9954,7 @@ os_pathconf(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
};
#undef KWTUPLE
PyObject *argsbuf[2];
path_t path = PATH_T_INITIALIZE("pathconf", "path", 0, PATH_HAVE_FPATHCONF);
path_t path = PATH_T_INITIALIZE_P("pathconf", "path", 0, 0, 0, PATH_HAVE_FPATHCONF);
int name;
long _return_value;
@ -10101,10 +10144,10 @@ os_startfile(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
#undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 1;
path_t filepath = PATH_T_INITIALIZE("startfile", "filepath", 0, 0);
path_t filepath = PATH_T_INITIALIZE_P("startfile", "filepath", 0, 0, 0, 0);
const wchar_t *operation = NULL;
const wchar_t *arguments = NULL;
path_t cwd = PATH_T_INITIALIZE("startfile", "cwd", 1, 0);
path_t cwd = PATH_T_INITIALIZE_P("startfile", "cwd", 1, 0, 0, 0);
int show_cmd = 1;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 5, 0, argsbuf);
@ -10439,8 +10482,8 @@ os_getxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
#undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t path = PATH_T_INITIALIZE("getxattr", "path", 0, 1);
path_t attribute = PATH_T_INITIALIZE("getxattr", "attribute", 0, 0);
path_t path = PATH_T_INITIALIZE_P("getxattr", "path", 0, 0, 0, 1);
path_t attribute = PATH_T_INITIALIZE_P("getxattr", "attribute", 0, 0, 0, 0);
int follow_symlinks = 1;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
@ -10526,8 +10569,8 @@ os_setxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
#undef KWTUPLE
PyObject *argsbuf[5];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 3;
path_t path = PATH_T_INITIALIZE("setxattr", "path", 0, 1);
path_t attribute = PATH_T_INITIALIZE("setxattr", "attribute", 0, 0);
path_t path = PATH_T_INITIALIZE_P("setxattr", "path", 0, 0, 0, 1);
path_t attribute = PATH_T_INITIALIZE_P("setxattr", "attribute", 0, 0, 0, 0);
Py_buffer value = {NULL, NULL};
int flags = 0;
int follow_symlinks = 1;
@ -10634,8 +10677,8 @@ os_removexattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObje
#undef KWTUPLE
PyObject *argsbuf[3];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 2;
path_t path = PATH_T_INITIALIZE("removexattr", "path", 0, 1);
path_t attribute = PATH_T_INITIALIZE("removexattr", "attribute", 0, 0);
path_t path = PATH_T_INITIALIZE_P("removexattr", "path", 0, 0, 0, 1);
path_t attribute = PATH_T_INITIALIZE_P("removexattr", "attribute", 0, 0, 0, 0);
int follow_symlinks = 1;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 2, 2, 0, argsbuf);
@ -10720,7 +10763,7 @@ os_listxattr(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject
#undef KWTUPLE
PyObject *argsbuf[2];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
path_t path = PATH_T_INITIALIZE("listxattr", "path", 1, 1);
path_t path = PATH_T_INITIALIZE_P("listxattr", "path", 1, 0, 0, 1);
int follow_symlinks = 1;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
@ -11697,7 +11740,7 @@ os_scandir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *
#undef KWTUPLE
PyObject *argsbuf[1];
Py_ssize_t noptargs = nargs + (kwnames ? PyTuple_GET_SIZE(kwnames) : 0) - 0;
path_t path = PATH_T_INITIALIZE("scandir", "path", 1, PATH_HAVE_FDOPENDIR);
path_t path = PATH_T_INITIALIZE_P("scandir", "path", 1, 0, 0, PATH_HAVE_FDOPENDIR);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 0, 1, 0, argsbuf);
if (!args) {
@ -11909,7 +11952,7 @@ os__add_dll_directory(PyObject *module, PyObject *const *args, Py_ssize_t nargs,
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("_add_dll_directory", "path", 0, 0);
path_t path = PATH_T_INITIALIZE_P("_add_dll_directory", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, 1, 1, 0, argsbuf);
if (!args) {
@ -12752,4 +12795,4 @@ os__supports_virtual_terminal(PyObject *module, PyObject *Py_UNUSED(ignored))
#ifndef OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF
#define OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF
#endif /* !defined(OS__SUPPORTS_VIRTUAL_TERMINAL_METHODDEF) */
/*[clinic end generated code: output=af5074c4ce4b19f1 input=a9049054013a1b77]*/
/*[clinic end generated code: output=300bd1c54dc43765 input=a9049054013a1b77]*/

View File

@ -1092,16 +1092,15 @@ get_posix_state(PyObject *module)
*
* path_converter accepts (Unicode) strings and their
* subclasses, and bytes and their subclasses. What
* it does with the argument depends on the platform:
* it does with the argument depends on path.make_wide:
*
* * On Windows, if we get a (Unicode) string we
* extract the wchar_t * and return it; if we get
* bytes we decode to wchar_t * and return that.
* * If path.make_wide is nonzero, if we get a (Unicode)
* string we extract the wchar_t * and return it; if we
* get bytes we decode to wchar_t * and return that.
*
* * On all other platforms, strings are encoded
* to bytes using PyUnicode_FSConverter, then we
* extract the char * from the bytes object and
* return that.
* * If path.make_wide is zero, if we get bytes we extract
* the char_t * and return it; if we get a (Unicode)
* string we encode to char_t * and return that.
*
* path_converter also optionally accepts signed
* integers (representing open file descriptors) instead
@ -1110,6 +1109,15 @@ get_posix_state(PyObject *module)
* Input fields:
* path.nullable
* If nonzero, the path is permitted to be None.
* path.nonstrict
* If nonzero, the path is permitted to contain
* embedded null characters and have any length.
* path.make_wide
* If nonzero, the converter always uses wide, decoding if necessary, else
* it always uses narrow, encoding if necessary. The default value is
* nonzero on Windows, else zero.
* path.suppress_value_error
* If nonzero, raising ValueError is suppressed.
* path.allow_fd
* If nonzero, the path is permitted to be a file handle
* (a signed int) instead of a string.
@ -1125,12 +1133,10 @@ get_posix_state(PyObject *module)
* Output fields:
* path.wide
* Points to the path if it was expressed as Unicode
* and was not encoded. (Only used on Windows.)
* or if it was bytes and decoded to Unicode.
* path.narrow
* Points to the path if it was expressed as bytes,
* or it was Unicode and was encoded to bytes. (On Windows,
* is a non-zero integer if the path was expressed as bytes.
* The type is deliberately incompatible to prevent misuse.)
* or if it was Unicode and encoded to bytes.
* path.fd
* Contains a file descriptor if path.accept_fd was true
* and the caller provided a signed integer instead of any
@ -1140,6 +1146,9 @@ get_posix_state(PyObject *module)
* unspecified, path_converter will never get called.
* So if you set allow_fd, you *MUST* initialize path.fd = -1
* yourself!
* path.value_error
* If nonzero, then suppress_value_error was specified and a ValueError
* occurred.
* path.length
* The length of the path in characters, if specified as
* a string.
@ -1172,28 +1181,38 @@ get_posix_state(PyObject *module)
* path_cleanup(). However it is safe to do so.)
*/
typedef struct {
// Input fields
const char *function_name;
const char *argument_name;
int nullable;
int nonstrict;
int make_wide;
int suppress_value_error;
int allow_fd;
// Output fields
const wchar_t *wide;
#ifdef MS_WINDOWS
BOOL narrow;
#else
const char *narrow;
#endif
int fd;
int value_error;
Py_ssize_t length;
PyObject *object;
PyObject *cleanup;
} path_t;
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, \
make_wide, suppress_value_error, allow_fd) \
{function_name, argument_name, nullable, nonstrict, make_wide, \
suppress_value_error, allow_fd, NULL, NULL, -1, 0, 0, NULL, NULL}
#ifdef MS_WINDOWS
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
{function_name, argument_name, nullable, allow_fd, NULL, FALSE, -1, 0, NULL, NULL}
#define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \
nonstrict, suppress_value_error, allow_fd) \
PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, 1, \
suppress_value_error, allow_fd)
#else
#define PATH_T_INITIALIZE(function_name, argument_name, nullable, allow_fd) \
{function_name, argument_name, nullable, allow_fd, NULL, NULL, -1, 0, NULL, NULL}
#define PATH_T_INITIALIZE_P(function_name, argument_name, nullable, \
nonstrict, suppress_value_error, allow_fd) \
PATH_T_INITIALIZE(function_name, argument_name, nullable, nonstrict, 0, \
suppress_value_error, allow_fd)
#endif
static void
@ -1214,10 +1233,8 @@ path_converter(PyObject *o, void *p)
Py_ssize_t length = 0;
int is_index, is_bytes, is_unicode;
const char *narrow;
#ifdef MS_WINDOWS
PyObject *wo = NULL;
wchar_t *wide = NULL;
#endif
#define FORMAT_EXCEPTION(exc, fmt) \
PyErr_Format(exc, "%s%s" fmt, \
@ -1238,11 +1255,7 @@ path_converter(PyObject *o, void *p)
if ((o == Py_None) && path->nullable) {
path->wide = NULL;
#ifdef MS_WINDOWS
path->narrow = FALSE;
#else
path->narrow = NULL;
#endif
path->fd = -1;
goto success_exit;
}
@ -1286,30 +1299,33 @@ path_converter(PyObject *o, void *p)
}
if (is_unicode) {
if (path->make_wide) {
wide = PyUnicode_AsWideCharString(o, &length);
if (!wide) {
goto error_exit;
}
#ifdef MS_WINDOWS
wide = PyUnicode_AsWideCharString(o, &length);
if (!wide) {
goto error_exit;
}
if (length > 32767) {
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
goto error_exit;
}
if (wcslen(wide) != length) {
FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
goto error_exit;
}
path->wide = wide;
path->narrow = FALSE;
path->fd = -1;
wide = NULL;
goto success_exit;
#else
if (!PyUnicode_FSConverter(o, &bytes)) {
goto error_exit;
}
if (!path->nonstrict && length > 32767) {
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
goto error_exit;
}
#endif
if (!path->nonstrict && wcslen(wide) != (size_t)length) {
FORMAT_EXCEPTION(PyExc_ValueError,
"embedded null character in %s");
goto error_exit;
}
path->wide = wide;
path->narrow = NULL;
path->fd = -1;
wide = NULL;
goto success_exit;
}
bytes = PyUnicode_EncodeFSDefault(o);
if (!bytes) {
goto error_exit;
}
}
else if (is_bytes) {
bytes = Py_NewRef(o);
@ -1319,11 +1335,7 @@ path_converter(PyObject *o, void *p)
goto error_exit;
}
path->wide = NULL;
#ifdef MS_WINDOWS
path->narrow = FALSE;
#else
path->narrow = NULL;
#endif
goto success_exit;
}
else {
@ -1343,52 +1355,54 @@ path_converter(PyObject *o, void *p)
length = PyBytes_GET_SIZE(bytes);
narrow = PyBytes_AS_STRING(bytes);
if ((size_t)length != strlen(narrow)) {
if (!path->nonstrict && strlen(narrow) != (size_t)length) {
FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
goto error_exit;
}
if (path->make_wide) {
wo = PyUnicode_DecodeFSDefaultAndSize(narrow, length);
if (!wo) {
goto error_exit;
}
wide = PyUnicode_AsWideCharString(wo, &length);
Py_DECREF(wo);
if (!wide) {
goto error_exit;
}
#ifdef MS_WINDOWS
wo = PyUnicode_DecodeFSDefaultAndSize(
narrow,
length
);
if (!wo) {
goto error_exit;
}
wide = PyUnicode_AsWideCharString(wo, &length);
Py_DECREF(wo);
if (!wide) {
goto error_exit;
}
if (length > 32767) {
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
goto error_exit;
}
if (wcslen(wide) != length) {
FORMAT_EXCEPTION(PyExc_ValueError, "embedded null character in %s");
goto error_exit;
}
path->wide = wide;
path->narrow = TRUE;
Py_DECREF(bytes);
wide = NULL;
#else
path->wide = NULL;
path->narrow = narrow;
if (bytes == o) {
/* Still a reference owned by path->object, don't have to
worry about path->narrow is used after free. */
if (!path->nonstrict && length > 32767) {
FORMAT_EXCEPTION(PyExc_ValueError, "%s too long for Windows");
goto error_exit;
}
#endif
if (!path->nonstrict && wcslen(wide) != (size_t)length) {
FORMAT_EXCEPTION(PyExc_ValueError,
"embedded null character in %s");
goto error_exit;
}
path->wide = wide;
path->narrow = NULL;
Py_DECREF(bytes);
wide = NULL;
}
else {
path->cleanup = bytes;
path->wide = NULL;
path->narrow = narrow;
if (bytes == o) {
/* Still a reference owned by path->object, don't have to
worry about path->narrow is used after free. */
Py_DECREF(bytes);
}
else {
path->cleanup = bytes;
}
}
#endif
path->fd = -1;
success_exit:
path->value_error = 0;
path->length = length;
path->object = o;
return Py_CLEANUP_SUPPORTED;
@ -1396,10 +1410,20 @@ path_converter(PyObject *o, void *p)
error_exit:
Py_XDECREF(o);
Py_XDECREF(bytes);
#ifdef MS_WINDOWS
PyMem_Free(wide);
#endif
return 0;
if (!path->suppress_value_error ||
!PyErr_ExceptionMatches(PyExc_ValueError))
{
return 0;
}
PyErr_Clear();
path->wide = NULL;
path->narrow = NULL;
path->fd = -1;
path->value_error = 1;
path->length = 0;
path->object = NULL;
return Py_CLEANUP_SUPPORTED;
}
static void
@ -1449,11 +1473,7 @@ follow_symlinks_specified(const char *function_name, int follow_symlinks)
static int
path_and_dir_fd_invalid(const char *function_name, path_t *path, int dir_fd)
{
if (!path->wide && (dir_fd != DEFAULT_DIR_FD)
#ifndef MS_WINDOWS
&& !path->narrow
#endif
) {
if (!path->wide && (dir_fd != DEFAULT_DIR_FD) && !path->narrow) {
PyErr_Format(PyExc_ValueError,
"%s: can't specify dir_fd without matching path",
function_name);
@ -2913,7 +2933,9 @@ class path_t_converter(CConverter):
converter = 'path_converter'
def converter_init(self, *, allow_fd=False, nullable=False):
def converter_init(self, *, allow_fd=False, make_wide=None,
nonstrict=False, nullable=False,
suppress_value_error=False):
# right now path_t doesn't support default values.
# to support a default value, you'll need to override initialize().
if self.default not in (unspecified, None):
@ -2923,6 +2945,9 @@ class path_t_converter(CConverter):
raise RuntimeError("Can't specify a c_default to the path_t converter!")
self.nullable = nullable
self.nonstrict = nonstrict
self.make_wide = make_wide
self.suppress_value_error = suppress_value_error
self.allow_fd = allow_fd
def pre_render(self):
@ -2932,11 +2957,24 @@ class path_t_converter(CConverter):
return str(int(bool(value)))
# add self.py_name here when merging with posixmodule conversion
self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {})'.format(
self.function.name,
self.name,
strify(self.nullable),
strify(self.allow_fd),
if self.make_wide is None:
self.c_default = 'PATH_T_INITIALIZE_P("{}", "{}", {}, {}, {}, {})'.format(
self.function.name,
self.name,
strify(self.nullable),
strify(self.nonstrict),
strify(self.suppress_value_error),
strify(self.allow_fd),
)
else:
self.c_default = 'PATH_T_INITIALIZE("{}", "{}", {}, {}, {}, {}, {})'.format(
self.function.name,
self.name,
strify(self.nullable),
strify(self.nonstrict),
strify(self.make_wide),
strify(self.suppress_value_error),
strify(self.allow_fd),
)
def cleanup(self):
@ -3016,7 +3054,7 @@ class sysconf_confname_converter(path_confname_converter):
converter="conv_sysconf_confname"
[python start generated code]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=3338733161aa7879]*/
/*[python end generated code: output=da39a3ee5e6b4b0d input=577cb476e5d64960]*/
/*[clinic input]
@ -4285,7 +4323,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list)
{
PyObject *v;
HANDLE hFindFile = INVALID_HANDLE_VALUE;
BOOL result;
BOOL result, return_bytes;
wchar_t namebuf[MAX_PATH+4]; /* Overallocate for "\*.*" */
/* only claim to have space for MAX_PATH */
Py_ssize_t len = Py_ARRAY_LENGTH(namebuf)-4;
@ -4297,9 +4335,11 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list)
if (!path->wide) { /* Default arg: "." */
po_wchars = L".";
len = 1;
return_bytes = 0;
} else {
po_wchars = path->wide;
len = wcslen(path->wide);
return_bytes = PyBytes_Check(path->object);
}
/* The +5 is so we can append "\\*.*\0" */
wnamebuf = PyMem_New(wchar_t, len + 5);
@ -4334,7 +4374,7 @@ _listdir_windows_no_opendir(path_t *path, PyObject *list)
wcscmp(wFileData.cFileName, L"..") != 0) {
v = PyUnicode_FromWideChar(wFileData.cFileName,
wcslen(wFileData.cFileName));
if (path->narrow && v) {
if (return_bytes && v) {
Py_SETREF(v, PyUnicode_EncodeFSDefault(v));
}
if (v == NULL) {
@ -4877,7 +4917,7 @@ os__getfullpathname_impl(PyObject *module, path_t *path)
if (str == NULL) {
return NULL;
}
if (path->narrow) {
if (PyBytes_Check(path->object)) {
Py_SETREF(str, PyUnicode_EncodeFSDefault(str));
}
return str;
@ -4950,7 +4990,7 @@ os__getfinalpathname_impl(PyObject *module, path_t *path)
}
result = PyUnicode_FromWideChar(target_path, result_length);
if (result && path->narrow) {
if (result && PyBytes_Check(path->object)) {
Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
}
@ -5033,7 +5073,7 @@ os__getvolumepathname_impl(PyObject *module, path_t *path)
goto exit;
}
result = PyUnicode_FromWideChar(mountpath, wcslen(mountpath));
if (path->narrow)
if (PyBytes_Check(path->object))
Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
exit:
@ -5267,64 +5307,52 @@ _testFileExistsByName(LPCWSTR path, BOOL followLinks)
}
static int
_testFileExists(path_t *_path, PyObject *path, BOOL followLinks)
static BOOL
_testFileExists(path_t *path, BOOL followLinks)
{
BOOL result = FALSE;
if (!path_converter(path, _path)) {
path_cleanup(_path);
if (PyErr_ExceptionMatches(PyExc_ValueError)) {
PyErr_Clear();
return FALSE;
}
return -1;
if (path->value_error) {
return FALSE;
}
Py_BEGIN_ALLOW_THREADS
if (_path->fd != -1) {
HANDLE hfile = _Py_get_osfhandle_noraise(_path->fd);
if (path->fd != -1) {
HANDLE hfile = _Py_get_osfhandle_noraise(path->fd);
if (hfile != INVALID_HANDLE_VALUE) {
if (GetFileType(hfile) != FILE_TYPE_UNKNOWN || !GetLastError()) {
result = TRUE;
}
}
}
else if (_path->wide) {
result = _testFileExistsByName(_path->wide, followLinks);
else if (path->wide) {
result = _testFileExistsByName(path->wide, followLinks);
}
Py_END_ALLOW_THREADS
path_cleanup(_path);
return result;
}
static int
_testFileType(path_t *_path, PyObject *path, int testedType)
static BOOL
_testFileType(path_t *path, int testedType)
{
BOOL result = FALSE;
if (!path_converter(path, _path)) {
path_cleanup(_path);
if (PyErr_ExceptionMatches(PyExc_ValueError)) {
PyErr_Clear();
return FALSE;
}
return -1;
if (path->value_error) {
return FALSE;
}
Py_BEGIN_ALLOW_THREADS
if (_path->fd != -1) {
HANDLE hfile = _Py_get_osfhandle_noraise(_path->fd);
if (path->fd != -1) {
HANDLE hfile = _Py_get_osfhandle_noraise(path->fd);
if (hfile != INVALID_HANDLE_VALUE) {
result = _testFileTypeByHandle(hfile, testedType, TRUE);
}
}
else if (_path->wide) {
result = _testFileTypeByName(_path->wide, testedType);
else if (path->wide) {
result = _testFileTypeByName(path->wide, testedType);
}
Py_END_ALLOW_THREADS
path_cleanup(_path);
return result;
}
@ -5332,7 +5360,7 @@ _testFileType(path_t *_path, PyObject *path, int testedType)
/*[clinic input]
os._path_exists -> bool
path: object
path: path_t(allow_fd=True, suppress_value_error=True)
/
Test whether a path exists. Returns False for broken symbolic links.
@ -5340,18 +5368,17 @@ Test whether a path exists. Returns False for broken symbolic links.
[clinic start generated code]*/
static int
os__path_exists_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=8f784b3abf9f8588 input=2777da15bc4ba5a3]*/
os__path_exists_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=8da13acf666e16ba input=29198507a6082a57]*/
{
path_t _path = PATH_T_INITIALIZE("_path_exists", "path", 0, 1);
return _testFileExists(&_path, path, TRUE);
return _testFileExists(path, TRUE);
}
/*[clinic input]
os._path_lexists -> bool
path: object
path: path_t(allow_fd=True, suppress_value_error=True)
/
Test whether a path exists. Returns True for broken symbolic links.
@ -5359,83 +5386,78 @@ 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]*/
os__path_lexists_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=e7240ed5fc45bff3 input=03d9fed8bc6ce96f]*/
{
path_t _path = PATH_T_INITIALIZE("_path_lexists", "path", 0, 1);
return _testFileExists(&_path, path, FALSE);
return _testFileExists(path, FALSE);
}
/*[clinic input]
os._path_isdir -> bool
s as path: object
s as path: path_t(allow_fd=True, suppress_value_error=True)
Return true if the pathname refers to an existing directory.
[clinic start generated code]*/
static int
os__path_isdir_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=0504fd403f369701 input=2cb54dd97eb970f7]*/
os__path_isdir_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=d5786196f9e2fa7a input=132a3b5301aecf79]*/
{
path_t _path = PATH_T_INITIALIZE("_path_isdir", "s", 0, 1);
return _testFileType(&_path, path, PY_IFDIR);
return _testFileType(path, PY_IFDIR);
}
/*[clinic input]
os._path_isfile -> bool
path: object
path: path_t(allow_fd=True, suppress_value_error=True)
Test whether a path is a regular file
[clinic start generated code]*/
static int
os__path_isfile_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=b40d620efe5a896f input=54b428a310debaea]*/
os__path_isfile_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=5c3073bc212b9863 input=4ac1fd350b30a39e]*/
{
path_t _path = PATH_T_INITIALIZE("_path_isfile", "path", 0, 1);
return _testFileType(&_path, path, PY_IFREG);
return _testFileType(path, PY_IFREG);
}
/*[clinic input]
os._path_islink -> bool
path: object
path: path_t(allow_fd=True, suppress_value_error=True)
Test whether a path is a symbolic link
[clinic start generated code]*/
static int
os__path_islink_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=9d0cf8e4c640dfe6 input=b71fed60b9b2cd73]*/
os__path_islink_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=30da7bda8296adcc input=7510ce05b547debb]*/
{
path_t _path = PATH_T_INITIALIZE("_path_islink", "path", 0, 1);
return _testFileType(&_path, path, PY_IFLNK);
return _testFileType(path, PY_IFLNK);
}
/*[clinic input]
os._path_isjunction -> bool
path: object
path: path_t(allow_fd=True, suppress_value_error=True)
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]*/
os__path_isjunction_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=e1d17a9dd18a9945 input=7dcb8bc4e972fcaf]*/
{
path_t _path = PATH_T_INITIALIZE("_path_isjunction", "path", 0, 1);
return _testFileType(&_path, path, PY_IFMNT);
return _testFileType(path, PY_IFMNT);
}
#undef PY_IFREG
@ -5451,23 +5473,22 @@ os__path_isjunction_impl(PyObject *module, PyObject *path)
/*[clinic input]
os._path_splitroot_ex
path: unicode
path: path_t(make_wide=True, nonstrict=True)
Split a pathname into drive, root and tail.
The tail contains anything after the root.
[clinic start generated code]*/
static PyObject *
os__path_splitroot_ex_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=de97403d3dfebc40 input=f1470e12d899f9ac]*/
os__path_splitroot_ex_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=4b0072b6cdf4b611 input=6eb76e9173412c92]*/
{
Py_ssize_t len, drvsize, rootsize;
Py_ssize_t drvsize, rootsize;
PyObject *drv = NULL, *root = NULL, *tail = NULL, *result = NULL;
wchar_t *buffer = PyUnicode_AsWideCharString(path, &len);
if (!buffer) {
goto exit;
}
_Py_skiproot(buffer, len, &drvsize, &rootsize);
const wchar_t *buffer = path->wide;
_Py_skiproot(buffer, path->length, &drvsize, &rootsize);
drv = PyUnicode_FromWideChar(buffer, drvsize);
if (drv == NULL) {
goto exit;
@ -5477,13 +5498,26 @@ os__path_splitroot_ex_impl(PyObject *module, PyObject *path)
goto exit;
}
tail = PyUnicode_FromWideChar(&buffer[drvsize + rootsize],
len - drvsize - rootsize);
path->length - drvsize - rootsize);
if (tail == NULL) {
goto exit;
}
if (PyBytes_Check(path->object)) {
Py_SETREF(drv, PyUnicode_EncodeFSDefault(drv));
if (drv == NULL) {
goto exit;
}
Py_SETREF(root, PyUnicode_EncodeFSDefault(root));
if (root == NULL) {
goto exit;
}
Py_SETREF(tail, PyUnicode_EncodeFSDefault(tail));
if (tail == NULL) {
goto exit;
}
}
result = PyTuple_Pack(3, drv, root, tail);
exit:
PyMem_Free(buffer);
Py_XDECREF(drv);
Py_XDECREF(root);
Py_XDECREF(tail);
@ -5494,29 +5528,28 @@ exit:
/*[clinic input]
os._path_normpath
path: object
path: path_t(make_wide=True, nonstrict=True)
Basic path normalization.
Normalize path, eliminating double slashes, etc.
[clinic start generated code]*/
static PyObject *
os__path_normpath_impl(PyObject *module, PyObject *path)
/*[clinic end generated code: output=b94d696d828019da input=5e90c39e12549dc0]*/
os__path_normpath_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=d353e7ed9410c044 input=3d4ac23b06332dcb]*/
{
if (!PyUnicode_Check(path)) {
PyErr_Format(PyExc_TypeError, "expected 'str', not '%.200s'",
Py_TYPE(path)->tp_name);
return NULL;
}
Py_ssize_t len;
wchar_t *buffer = PyUnicode_AsWideCharString(path, &len);
if (!buffer) {
return NULL;
}
PyObject *result;
Py_ssize_t norm_len;
wchar_t *norm_path = _Py_normpath_and_size(buffer, len, &norm_len);
PyObject *result = PyUnicode_FromWideChar(norm_path, norm_len);
PyMem_Free(buffer);
wchar_t *norm_path = _Py_normpath_and_size((wchar_t *)path->wide,
path->length, &norm_len);
if (!norm_len) {
result = PyUnicode_FromOrdinal('.');
}
else {
result = PyUnicode_FromWideChar(norm_path, norm_len);
}
if (PyBytes_Check(path->object)) {
Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
}
return result;
}
@ -10243,7 +10276,7 @@ os_readlink_impl(PyObject *module, path_t *path, int dir_fd)
name[1] = L'\\';
}
result = PyUnicode_FromWideChar(name, nameLen);
if (result && path->narrow) {
if (result && PyBytes_Check(path->object)) {
Py_SETREF(result, PyUnicode_EncodeFSDefault(result));
}
}
@ -15864,7 +15897,8 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
entry->name = PyUnicode_FromWideChar(dataW->cFileName, -1);
if (!entry->name)
goto error;
if (path->narrow) {
int return_bytes = path->wide && PyBytes_Check(path->object);
if (return_bytes) {
Py_SETREF(entry->name, PyUnicode_EncodeFSDefault(entry->name));
if (!entry->name)
goto error;
@ -15878,7 +15912,7 @@ DirEntry_from_find_data(PyObject *module, path_t *path, WIN32_FIND_DATAW *dataW)
PyMem_Free(joined_path);
if (!entry->path)
goto error;
if (path->narrow) {
if (return_bytes) {
Py_SETREF(entry->path, PyUnicode_EncodeFSDefault(entry->path));
if (!entry->path)
goto error;