gh-136437: Make several functions in os.path pos-only (#136949)

This commit is contained in:
sobolevn 2025-07-23 14:56:02 +03:00 committed by GitHub
parent e41c1ce585
commit 99cdf1deb6
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 51 additions and 147 deletions

View file

@ -81,28 +81,28 @@ def isdevdrive(path):
return False return False
def getsize(filename): def getsize(filename, /):
"""Return the size of a file, reported by os.stat().""" """Return the size of a file, reported by os.stat()."""
return os.stat(filename).st_size return os.stat(filename).st_size
def getmtime(filename): def getmtime(filename, /):
"""Return the last modification time of a file, reported by os.stat().""" """Return the last modification time of a file, reported by os.stat()."""
return os.stat(filename).st_mtime return os.stat(filename).st_mtime
def getatime(filename): def getatime(filename, /):
"""Return the last access time of a file, reported by os.stat().""" """Return the last access time of a file, reported by os.stat()."""
return os.stat(filename).st_atime return os.stat(filename).st_atime
def getctime(filename): def getctime(filename, /):
"""Return the metadata change time of a file, reported by os.stat().""" """Return the metadata change time of a file, reported by os.stat()."""
return os.stat(filename).st_ctime return os.stat(filename).st_ctime
# Return the longest prefix of all list elements. # Return the longest prefix of all list elements.
def commonprefix(m): def commonprefix(m, /):
"Given a list of pathnames, returns the longest common leading component" "Given a list of pathnames, returns the longest common leading component"
if not m: return '' if not m: return ''
# Some people pass in a list of pathname parts to operate in an OS-agnostic # Some people pass in a list of pathname parts to operate in an OS-agnostic
@ -120,14 +120,14 @@ def commonprefix(m):
# Are two stat buffers (obtained from stat, fstat or lstat) # Are two stat buffers (obtained from stat, fstat or lstat)
# describing the same file? # describing the same file?
def samestat(s1, s2): def samestat(s1, s2, /):
"""Test whether two stat buffers reference the same file""" """Test whether two stat buffers reference the same file"""
return (s1.st_ino == s2.st_ino and return (s1.st_ino == s2.st_ino and
s1.st_dev == s2.st_dev) s1.st_dev == s2.st_dev)
# Are two filenames really pointing to the same file? # Are two filenames really pointing to the same file?
def samefile(f1, f2): def samefile(f1, f2, /):
"""Test whether two pathnames reference the same actual file or directory """Test whether two pathnames reference the same actual file or directory
This is determined by the device number and i-node number and This is determined by the device number and i-node number and

View file

@ -47,7 +47,7 @@ def _get_bothseps(path):
LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT, LOCALE_NAME_INVARIANT as _LOCALE_NAME_INVARIANT,
LCMAP_LOWERCASE as _LCMAP_LOWERCASE) LCMAP_LOWERCASE as _LCMAP_LOWERCASE)
def normcase(s): def normcase(s, /):
"""Normalize case of pathname. """Normalize case of pathname.
Makes all characters lowercase and all slashes into backslashes. Makes all characters lowercase and all slashes into backslashes.
@ -66,7 +66,7 @@ def normcase(s):
_LCMAP_LOWERCASE, _LCMAP_LOWERCASE,
s.replace('/', '\\')) s.replace('/', '\\'))
except ImportError: except ImportError:
def normcase(s): def normcase(s, /):
"""Normalize case of pathname. """Normalize case of pathname.
Makes all characters lowercase and all slashes into backslashes. Makes all characters lowercase and all slashes into backslashes.
@ -77,7 +77,7 @@ def normcase(s):
return s.replace('/', '\\').lower() return s.replace('/', '\\').lower()
def isabs(s): def isabs(s, /):
"""Test whether a path is absolute""" """Test whether a path is absolute"""
s = os.fspath(s) s = os.fspath(s)
if isinstance(s, bytes): if isinstance(s, bytes):
@ -96,7 +96,7 @@ def isabs(s):
# Join two (or more) paths. # Join two (or more) paths.
def join(path, *paths): def join(path, /, *paths):
path = os.fspath(path) path = os.fspath(path)
if isinstance(path, bytes): if isinstance(path, bytes):
sep = b'\\' sep = b'\\'
@ -143,7 +143,7 @@ def join(path, *paths):
# Split a path in a drive specification (a drive letter followed by a # Split a path in a drive specification (a drive letter followed by a
# colon) and the path specification. # colon) and the path specification.
# It is always true that drivespec + pathspec == p # It is always true that drivespec + pathspec == p
def splitdrive(p): def splitdrive(p, /):
"""Split a pathname into drive/UNC sharepoint and relative path specifiers. """Split a pathname into drive/UNC sharepoint and relative path specifiers.
Returns a 2-tuple (drive_or_unc, path); either part may be empty. Returns a 2-tuple (drive_or_unc, path); either part may be empty.
@ -169,7 +169,7 @@ def splitdrive(p):
try: try:
from nt import _path_splitroot_ex as splitroot from nt import _path_splitroot_ex as splitroot
except ImportError: except ImportError:
def splitroot(p): def splitroot(p, /):
"""Split a pathname into drive, root and tail. """Split a pathname into drive, root and tail.
The tail contains anything after the root.""" The tail contains anything after the root."""
@ -219,7 +219,7 @@ def splitroot(p):
# join(head, tail) == p holds. # join(head, tail) == p holds.
# The resulting head won't end in '/' unless it is the root. # The resulting head won't end in '/' unless it is the root.
def split(p): def split(p, /):
"""Split a pathname. """Split a pathname.
Return tuple (head, tail) where tail is everything after the final slash. Return tuple (head, tail) where tail is everything after the final slash.
@ -240,7 +240,7 @@ def split(p):
# pathname component; the root is everything before that. # pathname component; the root is everything before that.
# It is always true that root + ext == p. # It is always true that root + ext == p.
def splitext(p): def splitext(p, /):
p = os.fspath(p) p = os.fspath(p)
if isinstance(p, bytes): if isinstance(p, bytes):
return genericpath._splitext(p, b'\\', b'/', b'.') return genericpath._splitext(p, b'\\', b'/', b'.')
@ -251,14 +251,14 @@ def splitext(p):
# Return the tail (basename) part of a path. # Return the tail (basename) part of a path.
def basename(p): def basename(p, /):
"""Returns the final component of a pathname""" """Returns the final component of a pathname"""
return split(p)[1] return split(p)[1]
# Return the head (dirname) part of a path. # Return the head (dirname) part of a path.
def dirname(p): def dirname(p, /):
"""Returns the directory component of a pathname""" """Returns the directory component of a pathname"""
return split(p)[0] return split(p)[0]
@ -601,7 +601,7 @@ def abspath(path):
from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink from nt import _findfirstfile, _getfinalpathname, readlink as _nt_readlink
except ImportError: except ImportError:
# realpath is a no-op on systems without _getfinalpathname support. # realpath is a no-op on systems without _getfinalpathname support.
def realpath(path, *, strict=False): def realpath(path, /, *, strict=False):
return abspath(path) return abspath(path)
else: else:
def _readlink_deep(path, ignored_error=OSError): def _readlink_deep(path, ignored_error=OSError):
@ -702,7 +702,7 @@ def _getfinalpathname_nonstrict(path, ignored_error=OSError):
tail = join(name, tail) if tail else name tail = join(name, tail) if tail else name
return tail return tail
def realpath(path, *, strict=False): def realpath(path, /, *, strict=False):
path = normpath(path) path = normpath(path)
if isinstance(path, bytes): if isinstance(path, bytes):
prefix = b'\\\\?\\' prefix = b'\\\\?\\'

View file

@ -50,7 +50,7 @@ def _get_sep(path):
# normalizations (such as optimizing '../' away) are not allowed # normalizations (such as optimizing '../' away) are not allowed
# (another function should be defined to do that). # (another function should be defined to do that).
def normcase(s): def normcase(s, /):
"""Normalize case of pathname. Has no effect under Posix""" """Normalize case of pathname. Has no effect under Posix"""
return os.fspath(s) return os.fspath(s)
@ -58,7 +58,7 @@ def normcase(s):
# Return whether a path is absolute. # Return whether a path is absolute.
# Trivial in Posix, harder on the Mac or MS-DOS. # Trivial in Posix, harder on the Mac or MS-DOS.
def isabs(s): def isabs(s, /):
"""Test whether a path is absolute""" """Test whether a path is absolute"""
s = os.fspath(s) s = os.fspath(s)
sep = _get_sep(s) sep = _get_sep(s)
@ -69,7 +69,7 @@ def isabs(s):
# Ignore the previous parts if a part is absolute. # Ignore the previous parts if a part is absolute.
# Insert a '/' unless the first part is empty or already ends in '/'. # Insert a '/' unless the first part is empty or already ends in '/'.
def join(a, *p): def join(a, /, *p):
"""Join two or more pathname components, inserting '/' as needed. """Join two or more pathname components, inserting '/' as needed.
If any component is an absolute path, all previous path components If any component is an absolute path, all previous path components
will be discarded. An empty last part will result in a path that will be discarded. An empty last part will result in a path that
@ -97,7 +97,7 @@ def join(a, *p):
# '/' in the path, head will be empty. # '/' in the path, head will be empty.
# Trailing '/'es are stripped from head unless it is the root. # Trailing '/'es are stripped from head unless it is the root.
def split(p): def split(p, /):
"""Split a pathname. Returns tuple "(head, tail)" where "tail" is """Split a pathname. Returns tuple "(head, tail)" where "tail" is
everything after the final slash. Either part may be empty.""" everything after the final slash. Either part may be empty."""
p = os.fspath(p) p = os.fspath(p)
@ -114,7 +114,7 @@ def split(p):
# pathname component; the root is everything before that. # pathname component; the root is everything before that.
# It is always true that root + ext == p. # It is always true that root + ext == p.
def splitext(p): def splitext(p, /):
p = os.fspath(p) p = os.fspath(p)
if isinstance(p, bytes): if isinstance(p, bytes):
sep = b'/' sep = b'/'
@ -128,7 +128,7 @@ def splitext(p):
# Split a pathname into a drive specification and the rest of the # Split a pathname into a drive specification and the rest of the
# path. Useful on DOS/Windows/NT; on Unix, the drive is always empty. # path. Useful on DOS/Windows/NT; on Unix, the drive is always empty.
def splitdrive(p): def splitdrive(p, /):
"""Split a pathname into drive and path. On Posix, drive is always """Split a pathname into drive and path. On Posix, drive is always
empty.""" empty."""
p = os.fspath(p) p = os.fspath(p)
@ -138,7 +138,7 @@ def splitdrive(p):
try: try:
from posix import _path_splitroot_ex as splitroot from posix import _path_splitroot_ex as splitroot
except ImportError: except ImportError:
def splitroot(p): def splitroot(p, /):
"""Split a pathname into drive, root and tail. """Split a pathname into drive, root and tail.
The tail contains anything after the root.""" The tail contains anything after the root."""
@ -163,7 +163,7 @@ def splitroot(p):
# Return the tail (basename) part of a path, same as split(path)[1]. # Return the tail (basename) part of a path, same as split(path)[1].
def basename(p): def basename(p, /):
"""Returns the final component of a pathname""" """Returns the final component of a pathname"""
p = os.fspath(p) p = os.fspath(p)
sep = _get_sep(p) sep = _get_sep(p)
@ -173,7 +173,7 @@ def basename(p):
# Return the head (dirname) part of a path, same as split(path)[0]. # Return the head (dirname) part of a path, same as split(path)[0].
def dirname(p): def dirname(p, /):
"""Returns the directory component of a pathname""" """Returns the directory component of a pathname"""
p = os.fspath(p) p = os.fspath(p)
sep = _get_sep(p) sep = _get_sep(p)
@ -388,7 +388,7 @@ def abspath(path):
# Return a canonical path (i.e. the absolute location of a file on the # Return a canonical path (i.e. the absolute location of a file on the
# filesystem). # filesystem).
def realpath(filename, *, strict=False): def realpath(filename, /, *, strict=False):
"""Return the canonical path of the specified filename, eliminating any """Return the canonical path of the specified filename, eliminating any
symbolic links encountered in the path.""" symbolic links encountered in the path."""
filename = os.fspath(filename) filename = os.fspath(filename)

View file

@ -2044,57 +2044,24 @@ exit:
#if defined(MS_WINDOWS) #if defined(MS_WINDOWS)
PyDoc_STRVAR(os__path_splitroot__doc__, PyDoc_STRVAR(os__path_splitroot__doc__,
"_path_splitroot($module, /, path)\n" "_path_splitroot($module, path, /)\n"
"--\n" "--\n"
"\n" "\n"
"Removes everything after the root on Win32."); "Removes everything after the root on Win32.");
#define OS__PATH_SPLITROOT_METHODDEF \ #define OS__PATH_SPLITROOT_METHODDEF \
{"_path_splitroot", _PyCFunction_CAST(os__path_splitroot), METH_FASTCALL|METH_KEYWORDS, os__path_splitroot__doc__}, {"_path_splitroot", (PyCFunction)os__path_splitroot, METH_O, os__path_splitroot__doc__},
static PyObject * static PyObject *
os__path_splitroot_impl(PyObject *module, path_t *path); os__path_splitroot_impl(PyObject *module, path_t *path);
static PyObject * static PyObject *
os__path_splitroot(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) os__path_splitroot(PyObject *module, PyObject *arg)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 1
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
Py_hash_t ob_hash;
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_hash = -1,
.ob_item = { &_Py_ID(path), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
static const char * const _keywords[] = {"path", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "_path_splitroot",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE_P("_path_splitroot", "path", 0, 0, 0, 0); path_t path = PATH_T_INITIALIZE_P("_path_splitroot", "path", 0, 0, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, if (!path_converter(arg, &path)) {
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
if (!args) {
goto exit;
}
if (!path_converter(args[0], &path)) {
goto exit; goto exit;
} }
return_value = os__path_splitroot_impl(module, &path); return_value = os__path_splitroot_impl(module, &path);
@ -2255,58 +2222,25 @@ exit:
#if defined(MS_WINDOWS) #if defined(MS_WINDOWS)
PyDoc_STRVAR(os__path_isdir__doc__, PyDoc_STRVAR(os__path_isdir__doc__,
"_path_isdir($module, /, s)\n" "_path_isdir($module, path, /)\n"
"--\n" "--\n"
"\n" "\n"
"Return true if the pathname refers to an existing directory."); "Return true if the pathname refers to an existing directory.");
#define OS__PATH_ISDIR_METHODDEF \ #define OS__PATH_ISDIR_METHODDEF \
{"_path_isdir", _PyCFunction_CAST(os__path_isdir), METH_FASTCALL|METH_KEYWORDS, os__path_isdir__doc__}, {"_path_isdir", (PyCFunction)os__path_isdir, METH_O, os__path_isdir__doc__},
static int static int
os__path_isdir_impl(PyObject *module, path_t *path); os__path_isdir_impl(PyObject *module, path_t *path);
static PyObject * static PyObject *
os__path_isdir(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) os__path_isdir(PyObject *module, PyObject *arg)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 1
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
Py_hash_t ob_hash;
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_hash = -1,
.ob_item = { _Py_LATIN1_CHR('s'), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
static const char * const _keywords[] = {"s", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "_path_isdir",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE_P("_path_isdir", "path", 0, 0, 1, 1); path_t path = PATH_T_INITIALIZE_P("_path_isdir", "path", 0, 0, 1, 1);
int _return_value; int _return_value;
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, if (!path_converter(arg, &path)) {
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
if (!args) {
goto exit;
}
if (!path_converter(args[0], &path)) {
goto exit; goto exit;
} }
_return_value = os__path_isdir_impl(module, &path); _return_value = os__path_isdir_impl(module, &path);
@ -2541,7 +2475,7 @@ exit:
#endif /* defined(MS_WINDOWS) */ #endif /* defined(MS_WINDOWS) */
PyDoc_STRVAR(os__path_splitroot_ex__doc__, PyDoc_STRVAR(os__path_splitroot_ex__doc__,
"_path_splitroot_ex($module, /, p)\n" "_path_splitroot_ex($module, path, /)\n"
"--\n" "--\n"
"\n" "\n"
"Split a pathname into drive, root and tail.\n" "Split a pathname into drive, root and tail.\n"
@ -2549,51 +2483,18 @@ PyDoc_STRVAR(os__path_splitroot_ex__doc__,
"The tail contains anything after the root."); "The tail contains anything after the root.");
#define OS__PATH_SPLITROOT_EX_METHODDEF \ #define OS__PATH_SPLITROOT_EX_METHODDEF \
{"_path_splitroot_ex", _PyCFunction_CAST(os__path_splitroot_ex), METH_FASTCALL|METH_KEYWORDS, os__path_splitroot_ex__doc__}, {"_path_splitroot_ex", (PyCFunction)os__path_splitroot_ex, METH_O, os__path_splitroot_ex__doc__},
static PyObject * static PyObject *
os__path_splitroot_ex_impl(PyObject *module, path_t *path); os__path_splitroot_ex_impl(PyObject *module, path_t *path);
static PyObject * static PyObject *
os__path_splitroot_ex(PyObject *module, PyObject *const *args, Py_ssize_t nargs, PyObject *kwnames) os__path_splitroot_ex(PyObject *module, PyObject *arg)
{ {
PyObject *return_value = NULL; PyObject *return_value = NULL;
#if defined(Py_BUILD_CORE) && !defined(Py_BUILD_CORE_MODULE)
#define NUM_KEYWORDS 1
static struct {
PyGC_Head _this_is_not_used;
PyObject_VAR_HEAD
Py_hash_t ob_hash;
PyObject *ob_item[NUM_KEYWORDS];
} _kwtuple = {
.ob_base = PyVarObject_HEAD_INIT(&PyTuple_Type, NUM_KEYWORDS)
.ob_hash = -1,
.ob_item = { _Py_LATIN1_CHR('p'), },
};
#undef NUM_KEYWORDS
#define KWTUPLE (&_kwtuple.ob_base.ob_base)
#else // !Py_BUILD_CORE
# define KWTUPLE NULL
#endif // !Py_BUILD_CORE
static const char * const _keywords[] = {"p", NULL};
static _PyArg_Parser _parser = {
.keywords = _keywords,
.fname = "_path_splitroot_ex",
.kwtuple = KWTUPLE,
};
#undef KWTUPLE
PyObject *argsbuf[1];
path_t path = PATH_T_INITIALIZE("_path_splitroot_ex", "path", 0, 1, 1, 0, 0); path_t path = PATH_T_INITIALIZE("_path_splitroot_ex", "path", 0, 1, 1, 0, 0);
args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser, if (!path_converter(arg, &path)) {
/*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
if (!args) {
goto exit;
}
if (!path_converter(args[0], &path)) {
goto exit; goto exit;
} }
return_value = os__path_splitroot_ex_impl(module, &path); return_value = os__path_splitroot_ex_impl(module, &path);
@ -13518,4 +13419,4 @@ exit:
#ifndef OS__EMSCRIPTEN_LOG_METHODDEF #ifndef OS__EMSCRIPTEN_LOG_METHODDEF
#define OS__EMSCRIPTEN_LOG_METHODDEF #define OS__EMSCRIPTEN_LOG_METHODDEF
#endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */ #endif /* !defined(OS__EMSCRIPTEN_LOG_METHODDEF) */
/*[clinic end generated code: output=608e9bc5f631f688 input=a9049054013a1b77]*/ /*[clinic end generated code: output=b1e2615384347102 input=a9049054013a1b77]*/

View file

@ -5226,14 +5226,15 @@ os__getvolumepathname_impl(PyObject *module, path_t *path)
/*[clinic input] /*[clinic input]
os._path_splitroot os._path_splitroot
path: path_t path: path_t,
/
Removes everything after the root on Win32. Removes everything after the root on Win32.
[clinic start generated code]*/ [clinic start generated code]*/
static PyObject * static PyObject *
os__path_splitroot_impl(PyObject *module, path_t *path) os__path_splitroot_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=ab7f1a88b654581c input=dc93b1d3984cffb6]*/ /*[clinic end generated code: output=ab7f1a88b654581c input=42831e41f8458f6d]*/
{ {
wchar_t *buffer; wchar_t *buffer;
wchar_t *end; wchar_t *end;
@ -5535,7 +5536,8 @@ os__path_lexists_impl(PyObject *module, path_t *path)
/*[clinic input] /*[clinic input]
os._path_isdir -> bool os._path_isdir -> bool
s as path: path_t(allow_fd=True, suppress_value_error=True) path: path_t(allow_fd=True, suppress_value_error=True),
/
Return true if the pathname refers to an existing directory. Return true if the pathname refers to an existing directory.
@ -5543,7 +5545,7 @@ Return true if the pathname refers to an existing directory.
static int static int
os__path_isdir_impl(PyObject *module, path_t *path) os__path_isdir_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=d5786196f9e2fa7a input=132a3b5301aecf79]*/ /*[clinic end generated code: output=d5786196f9e2fa7a input=0d3fd790564d244b]*/
{ {
return _testFileType(path, PY_IFDIR); return _testFileType(path, PY_IFDIR);
} }
@ -5612,7 +5614,8 @@ os__path_isjunction_impl(PyObject *module, path_t *path)
/*[clinic input] /*[clinic input]
os._path_splitroot_ex os._path_splitroot_ex
p as path: path_t(make_wide=True, nonstrict=True) path: path_t(make_wide=True, nonstrict=True),
/
Split a pathname into drive, root and tail. Split a pathname into drive, root and tail.
@ -5621,7 +5624,7 @@ The tail contains anything after the root.
static PyObject * static PyObject *
os__path_splitroot_ex_impl(PyObject *module, path_t *path) os__path_splitroot_ex_impl(PyObject *module, path_t *path)
/*[clinic end generated code: output=4b0072b6cdf4b611 input=4556b615c7cc13f2]*/ /*[clinic end generated code: output=4b0072b6cdf4b611 input=4ac47b394d68bd21]*/
{ {
Py_ssize_t drvsize, rootsize; Py_ssize_t drvsize, rootsize;
PyObject *drv = NULL, *root = NULL, *tail = NULL, *result = NULL; PyObject *drv = NULL, *root = NULL, *tail = NULL, *result = NULL;