diff -rupN Python-2.7.13/Include/pythonrun.h Python-2.7.13-new/Include/pythonrun.h
--- Python-2.7.13/Include/pythonrun.h 2016-12-17 21:05:05.000000000 +0100
+++ Python-2.7.13-new/Include/pythonrun.h 2017-01-21 01:46:10.891560739 +0100
@@ -104,6 +104,7 @@ PyAPI_FUNC(char *) Py_GetProgramFullPath
PyAPI_FUNC(char *) Py_GetPrefix(void);
PyAPI_FUNC(char *) Py_GetExecPrefix(void);
PyAPI_FUNC(char *) Py_GetPath(void);
+PyAPI_FUNC(void) Py_NormalizeSepsA(char *name);
/* In their own files */
PyAPI_FUNC(const char *) Py_GetVersion(void);
diff -rupN Python-2.7.13/Lib/ntpath.py Python-2.7.13-new/Lib/ntpath.py
--- Python-2.7.13/Lib/ntpath.py 2016-12-17 21:05:06.000000000 +0100
+++ Python-2.7.13-new/Lib/ntpath.py 2017-01-21 01:46:10.893560717 +0100
@@ -25,9 +25,22 @@ __all__ = ["normcase","isabs","join","sp
curdir = '.'
pardir = '..'
extsep = '.'
-sep = '\\'
+# Generally we prefer forwards slashes for MinGW-w64 Python,
+# but should probably defer to the C code and a set of #defines
+# with the following precedence and logic:
+# DIRSEP_MSYSTEM = If MSYSTEM env. var is set then / otherwise \.
+# DIRSEP_ARGV0 = Whichever of / and \ is more prevalent in argv0
+# (if equal DIRSEP_FORWARDS or DIRSEP_BACKWARDS)
+# DIRSEP_FORWARDS = Always /
+# DIRSEP_BACKWARDS = Always \
+# .. note, UNC paths are always converted to backslashes.
+if sys.platform == "win32" and "MSYSTEM" in os.environ:
+ sep = '/'
+ altsep = '\\'
+else:
+ sep = '\\'
+ altsep = '/'
pathsep = ';'
-altsep = '/'
defpath = '.;C:\\bin'
if 'ce' in sys.builtin_module_names:
defpath = '\\Windows'
@@ -43,8 +56,8 @@ devnull = 'nul'
def normcase(s):
"""Normalize case of pathname.
- Makes all characters lowercase and all slashes into backslashes."""
- return s.replace("/", "\\").lower()
+ Makes all characters lowercase and all os.altsep into os.sep."""
+ return s.replace(os.altsep, os.sep).lower()
# Return whether a path is absolute.
@@ -61,7 +74,7 @@ def isabs(s):
# Join two (or more) paths.
def join(path, *paths):
- """Join two or more pathname components, inserting "\\" as needed."""
+ """Join two or more pathname components, inserting sep as needed."""
result_drive, result_path = splitdrive(path)
for p in paths:
p_drive, p_path = splitdrive(p)
@@ -81,7 +94,7 @@ def join(path, *paths):
result_drive = p_drive
# Second path is relative to the first
if result_path and result_path[-1] not in '\\/':
- result_path = result_path + '\\'
+ result_path = result_path + sep
result_path = result_path + p_path
## add separator between UNC and non-absolute path
if (result_path and result_path[0] not in '\\/' and
@@ -416,13 +429,19 @@ def normpath(path):
"""Normalize path, eliminating double slashes, etc."""
# Preserve unicode (if path is unicode)
backslash, dot = (u'\\', u'.') if isinstance(path, _unicode) else ('\\', '.')
+ isUNC = path.startswith('\\\\')
+ this_sep = sep
+ other_sep = altsep
+ if isUNC:
+ this_sep = backslash
+ other_sep = '/'
if path.startswith(('\\\\.\\', '\\\\?\\')):
# in the case of paths with these prefixes:
# \\.\ -> device names
# \\?\ -> literal paths
# do not do any normalization, but return the path unchanged
return path
- path = path.replace("/", "\\")
+ path = path.replace(other_sep, this_sep)
prefix, path = splitdrive(path)
# We need to be careful here. If the prefix is empty, and the path starts
# with a backslash, it could either be an absolute path on the current
@@ -435,15 +454,15 @@ def normpath(path):
# is any better behaviour for such edge cases.
if prefix == '':
# No drive letter - preserve initial backslashes
- while path[:1] == "\\":
- prefix = prefix + backslash
+ while path[:1] == this_sep:
+ prefix = prefix + this_sep
path = path[1:]
else:
# We have a drive letter - collapse initial backslashes
- if path.startswith("\\"):
- prefix = prefix + backslash
- path = path.lstrip("\\")
- comps = path.split("\\")
+ if path.startswith(sep):
+ prefix = prefix + this_sep
+ path = path.lstrip(this_sep)
+ comps = path.split(this_sep)
i = 0
while i < len(comps):
if comps[i] in ('.', ''):
@@ -452,7 +471,7 @@ def normpath(path):
if i > 0 and comps[i-1] != '..':
del comps[i-1:i+1]
i -= 1
- elif i == 0 and prefix.endswith("\\"):
+ elif i == 0 and prefix.endswith(this_sep):
del comps[i]
else:
i += 1
@@ -461,7 +480,7 @@ def normpath(path):
# If the path is now empty, substitute '.'
if not prefix and not comps:
comps.append(dot)
- return prefix + backslash.join(comps)
+ return prefix + this_sep.join(comps)
# Return an absolute path.
diff -rupN Python-2.7.13/Modules/posixmodule.c Python-2.7.13-new/Modules/posixmodule.c
--- Python-2.7.13/Modules/posixmodule.c 2017-01-21 01:46:10.317566867 +0100
+++ Python-2.7.13-new/Modules/posixmodule.c 2017-01-21 01:46:10.892560728 +0100
@@ -2213,6 +2213,8 @@ posix_getcwd(PyObject *self, PyObject *n
if (res == NULL)
return posix_error();
+ Py_NormalizeSepsA(tmpbuf);
+
dynamic_return = PyString_FromString(tmpbuf);
free(tmpbuf);
diff -rupN Python-2.7.13/Python/pythonrun.c Python-2.7.13-new/Python/pythonrun.c
--- Python-2.7.13/Python/pythonrun.c 2016-12-17 21:05:07.000000000 +0100
+++ Python-2.7.13-new/Python/pythonrun.c 2017-01-21 01:46:10.891560739 +0100
@@ -666,13 +666,67 @@ Py_EndInterpreter(PyThreadState *tstate)
PyInterpreterState_Delete(interp);
}
-static char *progname = "python";
+ static char progname[PATH_MAX+1] = "python";
+
+char
+Py_GetSepA(char *name)
+{
+ char* msystem = (char*)2; /* So that non Windows use / as sep */
+ static char sep = '\0';
+#ifdef _WIN32
+ /* https://msdn.microsoft.com/en-gb/library/windows/desktop/aa365247%28v=vs.85%29.aspx
+ * The "\\?\" prefix .. indicate that the path should be passed to the system with minimal
+ * modification, which means that you cannot use forward slashes to represent path separators
+ */
+ if (name != NULL && memcmp(name, "\\\\?\\", sizeof("\\\\?\\") - sizeof(char)) == 0)
+ {
+ return '\\';
+ }
+#endif
+ if (sep != '\0')
+ return sep;
+#if defined(__MINGW32__)
+ msystem = Py_GETENV("MSYSTEM");
+#endif
+ if (msystem != NULL)
+ sep = '/';
+ else
+ sep = '\\';
+ return sep;
+}
+
+static wchar_t
+Py_GetAltSepA(char *name)
+{
+ char sep = Py_GetSepA(name);
+ if (sep == '/')
+ return '\\';
+ return '/';
+}
void
-Py_SetProgramName(char *pn)
+Py_NormalizeSepsA(char *name)
{
- if (pn && *pn)
- progname = pn;
+ char sep = Py_GetSepA(name);
+ char altsep = Py_GetAltSepA(name);
+ char* seps;
+ if (strlen(name) > 1 && name[1] == ':') {
+ name[0] = toupper(name[0]);
+ }
+ seps = strchr(name, altsep);
+ while(seps) {
+ *seps = sep;
+ seps = strchr(seps, altsep);
+ }
+}
+
+ void
+ Py_SetProgramName(char *pn)
+ {
+ if (pn && *pn)
+ strncpy(progname, pn, PATH_MAX);
+ pn = &progname[0];
+ Py_NormalizeSepsA(pn);
}
char *