--- Python-3.7.3.orig/Modules/getpath.c
+++ Python-3.7.3/Modules/getpath.c
@@ -121,6 +121,7 @@
     wchar_t *pythonpath;               /* PYTHONPATH define */
     wchar_t *prefix;                   /* PREFIX define */
     wchar_t *exec_prefix;              /* EXEC_PREFIX define */
+    wchar_t *smlinux_staging_dir;        /* SMLINUX_STAGING_DIR define */
 
     wchar_t *lib_python;               /* "lib/pythonX.Y" */
     wchar_t argv0_path[MAXPATHLEN+1];
@@ -155,9 +156,16 @@
 reduce(wchar_t *dir)
 {
     size_t i = wcslen(dir);
+    if (i == 1 && dir[0] == SEP) {
+        /* L"/" becomes L"" */
+        dir[0] = L'\0';
+        return;
+    }
     while (i > 0 && dir[i] != SEP)
         --i;
-    dir[i] = '\0';
+    if (i == 0 && dir[0] == SEP)
+        i = 1; /* L"/blah" becomes L"/" */
+    dir[i] = L'\0';
 }
 
 
@@ -374,6 +382,15 @@
         }
     }
 
+    /* If argv[0] appears to be in smlinux's staging directory,
+     * then skip to the following PREFIX check,
+     * otherwise proceed as normal to preserve virtual environments.
+     */
+    if (!wcsncmp(calculate->smlinux_staging_dir, calculate->argv0_path,
+                 wcslen(calculate->smlinux_staging_dir)) ||
+        !wcsncmp(calculate->argv0_path, L"/bin/../", 8))
+        goto skip_argv0_path;
+
     /* Search from argv0_path, until root is found */
     copy_absolute(prefix, calculate->argv0_path, MAXPATHLEN+1);
     do {
@@ -386,9 +403,15 @@
         prefix[n] = L'\0';
         reduce(prefix);
     } while (prefix[0]);
+    skip_argv0_path:
 
     /* Look at configure's PREFIX */
-    wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
+    if (wcslen(calculate->prefix))
+        wcsncpy(prefix, calculate->prefix, MAXPATHLEN);
+    else {
+        prefix[0] = '/';
+        prefix[1] = 0;
+    }
     prefix[MAXPATHLEN] = L'\0';
     joinpath(prefix, calculate->lib_python);
     joinpath(prefix, LANDMARK);
@@ -495,6 +518,15 @@
         }
     }
 
+    /* If argv[0] appears to be in smlinux's staging directory,
+     * then skip to the following EXEC_PREFIX check,
+     * otherwise proceed as normal to preserve virtual environments.
+     */
+    if (!wcsncmp(calculate->smlinux_staging_dir, calculate->argv0_path,
+                 wcslen(calculate->smlinux_staging_dir)) ||
+        !wcsncmp(calculate->argv0_path, L"/bin/../", 8))
+        goto skip_argv0_path;
+
     /* Search from argv0_path, until root is found */
     copy_absolute(exec_prefix, calculate->argv0_path, MAXPATHLEN+1);
     do {
@@ -507,9 +539,16 @@
         exec_prefix[n] = L'\0';
         reduce(exec_prefix);
     } while (exec_prefix[0]);
+    skip_argv0_path:
 
     /* Look at configure's EXEC_PREFIX */
-    wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
+    if (strlen(EXEC_PREFIX)) {
+        wcsncpy(exec_prefix, calculate->exec_prefix, MAXPATHLEN);
+    }
+    else {
+        exec_prefix[0] = L'/';
+        exec_prefix[1] = L'\0';
+    }
     exec_prefix[MAXPATHLEN] = L'\0';
     joinpath(exec_prefix, calculate->lib_python);
     joinpath(exec_prefix, L"lib-dynload");
@@ -829,7 +868,9 @@
     }
 
     bufsz += wcslen(calculate->zip_path) + 1;
-    bufsz += wcslen(exec_prefix) + 1;
+    if (wcslen(exec_prefix)) {
+        bufsz += wcslen(exec_prefix) + 1;
+    }
 
     /* Allocate the buffer */
     wchar_t *buf = PyMem_RawMalloc(bufsz * sizeof(wchar_t));
@@ -880,7 +921,10 @@
     wcscat(buf, delimiter);
 
     /* Finally, on goes the directory for dynamic-load modules */
-    wcscat(buf, exec_prefix);
+    if (wcslen(exec_prefix)) {
+        wcscat(buf, delimiter);
+        wcscat(buf, exec_prefix);
+    }
 
     config->module_search_path = buf;
     return _Py_INIT_OK();
@@ -908,6 +952,10 @@
     if (!calculate->prefix) {
         return DECODE_LOCALE_ERR("PREFIX define", len);
     }
+    calculate->smlinux_staging_dir = Py_DecodeLocale(SMLINUX_STAGING_DIR, &len);
+    if (!calculate->smlinux_staging_dir) {
+        return DECODE_LOCALE_ERR("SMLINUX_STAGING_DIR define", len);
+    }
     calculate->exec_prefix = Py_DecodeLocale(EXEC_PREFIX, &len);
     if (!calculate->prefix) {
         return DECODE_LOCALE_ERR("EXEC_PREFIX define", len);
