Skip to content

Instantly share code, notes, and snippets.

@JNRowe
Created December 6, 2018 02:21
Show Gist options
  • Save JNRowe/502f8772861cdd21bff5144c416e4b31 to your computer and use it in GitHub Desktop.
Save JNRowe/502f8772861cdd21bff5144c416e4b31 to your computer and use it in GitHub Desktop.
kushaldas’s pypackages cpython branch mashed in to Python 3.7 for *easier* testing
diff --git i/Include/pystate.h w/Include/pystate.h
index 29d7148..7446df7 100644
--- i/Include/pystate.h
+++ w/Include/pystate.h
@@ -62,6 +62,8 @@ typedef struct {
wchar_t *home; /* PYTHONHOME environment variable,
see also Py_SetPythonHome(). */
+ wchar_t *pypackages_path; /* For __pypackages__ directory */
+
/* Path configuration outputs */
int nmodule_search_path; /* Number of sys.path paths,
-1 means unset */
diff --git i/Modules/getpath.c w/Modules/getpath.c
index e6a3e8e..8363949 100644
--- i/Modules/getpath.c
+++ w/Modules/getpath.c
@@ -763,6 +763,10 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
bufsz += wcslen(core_config->module_search_path_env) + 1;
}
+ if (core_config->pypackages_path != NULL) {
+ bufsz += wcslen(core_config->pypackages_path) + 1;
+ }
+
wchar_t *defpath = calculate->pythonpath;
size_t prefixsz = wcslen(prefix) + 1;
while (1) {
@@ -799,6 +803,12 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
wcscat(buf, delimiter);
}
+ /* Add __pypackages__ directory */
+ if (core_config->pypackages_path) {
+ wcscpy(buf, core_config->pypackages_path);
+ wcscat(buf, delimiter);
+ }
+
/* Next is the default zip path */
wcscat(buf, calculate->zip_path);
wcscat(buf, delimiter);
diff --git i/Modules/main.c w/Modules/main.c
index 286ad41..ef6f29f 100644
--- i/Modules/main.c
+++ w/Modules/main.c
@@ -732,6 +732,53 @@ pymain_wstrlist_append(_PyMain *pymain, int *len, wchar_t ***list, const wchar_t
return 0;
}
+static wchar_t *
+py_dirname(const wchar_t *filename)
+{
+ wchar_t *dir = _PyMem_RawWcsdup(filename);
+ if (dir == NULL) {
+ return NULL;
+ }
+ size_t i = wcslen(dir);
+
+#ifdef ALTSEP
+ while (i > 0 && dir[i] != SEP && dir[i] != ALTSEP)
+ --i;
+#else
+ while (i > 0 && dir[i] != SEP)
+ --i;
+#endif
+ if (i == 0) {
+ dir[0] = L'.';
+ i++;
+ }
+ dir[i] = '\0';
+
+ char buffer[100];
+ PyOS_snprintf(buffer, sizeof(buffer), "%c__pypackages__%c%d.%d%clib", SEP, SEP, PY_MAJOR_VERSION, PY_MINOR_VERSION, SEP);
+ wchar_t *pybuffer = Py_DecodeLocale(buffer, NULL);
+ if (pybuffer == NULL) {
+ PyMem_RawFree(dir);
+ return NULL;
+ }
+ size_t buffer_len = wcslen(dir) + wcslen(pybuffer) + 1;
+
+ wchar_t *final_path = PyMem_RawMalloc(buffer_len * sizeof(wchar_t));
+ if (final_path == NULL) {
+ PyMem_RawFree(dir);
+ PyMem_RawFree(pybuffer);
+ return NULL;
+ }
+
+ wcscpy(final_path, dir);
+ wcscat(final_path, pybuffer);
+
+ PyMem_RawFree(dir);
+ PyMem_RawFree(pybuffer);
+
+
+ return final_path;
+}
/* Parse the command line arguments
Return 0 on success.
@@ -1911,6 +1958,24 @@ pymain_read_conf_impl(_PyMain *pymain, _Py_CommandLineDetails *cmdline)
return -1;
}
+ /* In case of script files */
+ if (pymain->filename != NULL) {
+ config->pypackages_path = py_dirname(pymain->filename);
+ if (config->pypackages_path == NULL) {
+ pymain->err = _Py_INIT_NO_MEMORY();
+ return -1;
+ }
+ } else {
+ /* For the rest of the cases. */
+ char buffer[10];
+ PyOS_snprintf(buffer, sizeof(buffer), ".%c.", SEP);
+ config->pypackages_path = py_dirname(Py_DecodeLocale(buffer, NULL));
+ if (config->pypackages_path == NULL) {
+ pymain->err = _Py_INIT_NO_MEMORY();
+ return -1;
+ }
+ }
+
/* On Windows, _PyPathConfig_Init() modifies Py_IsolatedFlag and
Py_NoSiteFlag variables if a "._pth" file is found. */
int init_isolated = Py_IsolatedFlag;
@@ -2239,6 +2304,7 @@ _PyCoreConfig_Clear(_PyCoreConfig *config)
CLEAR(config->module_search_path_env);
CLEAR(config->home);
+ CLEAR(config->pypackages_path);
CLEAR(config->program_name);
CLEAR(config->program);
@@ -2303,6 +2369,7 @@ _PyCoreConfig_Copy(_PyCoreConfig *config, const _PyCoreConfig *config2)
COPY_STR_ATTR(module_search_path_env);
COPY_STR_ATTR(home);
+ COPY_STR_ATTR(pypackages_path);
COPY_STR_ATTR(program_name);
COPY_STR_ATTR(program);
diff --git i/PC/getpathp.c w/PC/getpathp.c
index 9382843..aceb6af 100644
--- i/PC/getpathp.c
+++ w/PC/getpathp.c
@@ -800,6 +800,9 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
if (calculate->user_path) {
bufsz += wcslen(calculate->user_path) + 1;
}
+ if (core_config->pypackages_path) {
+ bufsz += wcslen(core_config->pypackages_path) + 1;
+ }
if (calculate->machine_path) {
bufsz += wcslen(calculate->machine_path) + 1;
}
@@ -833,6 +836,15 @@ calculate_module_search_path(const _PyCoreConfig *core_config,
buf = wcschr(buf, L'\0');
*buf++ = DELIM;
}
+ /* Adds the __pypackages__ directory */
+ if (core_config->pypackages_path) {
+ if (wcscpy_s(buf, bufsz - (buf - start_buf),
+ core_config->pypackages_path)) {
+ return INIT_ERR_BUFFER_OVERFLOW();
+ }
+ buf = wcschr(buf, L'\0');
+ *buf++ = DELIM;
+ }
if (calculate->zip_path[0]) {
if (wcscpy_s(buf, bufsz - (buf - start_buf), calculate->zip_path)) {
return INIT_ERR_BUFFER_OVERFLOW();
@JNRowe
Copy link
Author

JNRowe commented Dec 6, 2018

Note to self: From pypackages branch, see PEP-582.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment