[Python-Dev] Relative Package Imports
M.-A. Lemburg
mal@lemburg.com
Fri, 10 Sep 1999 21:06:28 +0200
This is a multi-part message in MIME format.
--------------60F2EF1167E1920659766E3D
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit
Hi everybody,
I've spent the last two hours trying to get relative package
imports to work because I need them for my extension packages
which will soon all move under a new top-level package name
to overcome the conflicts with PIL and Zope.
Here are the results...
Demo Package Structure: (see the attached demopkg.zip)
[a]
[b]
bc.py
ab.py
With the attached patch you can do the following:
# Pretty useless...
import a.b.__.ab
# From inside bc.py:
from __ import ab
# At top-level (also useless, but shows how this situation is handled):
import __.sys
# __ is bound to None since we are at top-level; sys is still
# being loaded though.
Of course, common usage will be of the form:
form __.__ import submodule_at_higher_level
Please tell me what you think and give it a try. It's a first
try and may have some design errors. Especially the way
head and tail are treated in Python/import.c:import_module_ex
may cause trouble -- I need help here.
Note: The patch is against the CVS version. If you run Python
in verbose mode, the patch will produce some verbose output
of what it's doing.
Enjoy,
--
Marc-Andre Lemburg
______________________________________________________________________
Y2000: 113 days left
Business: http://www.lemburg.com/
Python Pages: http://www.lemburg.com/python/
--------------60F2EF1167E1920659766E3D
Content-Type: text/plain; charset=us-ascii; name="parentimport.patch"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline; filename="parentimport.patch"
--- /home/lemburg/orig/Python/Python/import.c Fri Apr 9 19:00:51 1999
+++ Python/import.c Fri Sep 10 20:51:02 1999
@@ -1572,10 +1572,14 @@ load_next(mod, altmod, p_name, buf, p_bu
char *dot = strchr(name, '.');
int len;
char *p;
PyObject *result;
+ if (Py_VerboseFlag)
+ printf("# load_next: (1) name='%s', buf='%.*s'\n",
+ name,*p_buflen,buf);
+
if (dot == NULL) {
*p_name = NULL;
len = strlen(name);
}
else {
@@ -1586,10 +1590,39 @@ load_next(mod, altmod, p_name, buf, p_bu
PyErr_SetString(PyExc_ValueError,
"Empty module name");
return NULL;
}
+ /* Handle "__" indicator telling the import mechanism to
+ continue the search one level higher in the package
+ hierarchy */
+ if (strncmp(name,"__",len) == 0) {
+ PyObject *modules = PyImport_GetModuleDict();
+
+ /* Strip the final dotted name from buf */
+ dot = strrchr(buf, '.');
+ if (dot == NULL)
+ *p_buflen = 0;
+ else
+ *p_buflen = dot - buf;
+ buf[*p_buflen] = '\0';
+
+ /* Fetch the parent module or revert to a top-level search */
+ if (*p_buflen > 0) {
+ mod = PyDict_GetItemString(modules,buf);
+ if (mod == NULL) {
+ PyErr_SetString(PyExc_SystemError,
+ "Parent module missing");
+ return NULL;
+ }
+ }
+ else
+ mod = Py_None;
+ Py_INCREF(mod);
+ return mod;
+ }
+
p = buf + *p_buflen;
if (p != buf)
*p++ = '.';
if (p+len-buf >= MAXPATHLEN) {
PyErr_SetString(PyExc_ValueError,
@@ -1597,10 +1630,14 @@ load_next(mod, altmod, p_name, buf, p_bu
return NULL;
}
strncpy(p, name, len);
p[len] = '\0';
*p_buflen = p+len-buf;
+
+ if (Py_VerboseFlag)
+ printf("# load_next: (2) modname='%s', fullname=buf='%s'\n",
+ p,buf);
result = import_submodule(mod, p, buf);
if (result == Py_None && altmod != mod) {
Py_DECREF(result);
/* Here, altmod must be None and mod must not be None */
--------------60F2EF1167E1920659766E3D
Content-Type: application/x-zip-compressed; name="demopkg.zip"
Content-Transfer-Encoding: base64
Content-Disposition: inline; filename="demopkg.zip"
UEsDBAoAAgAAAASgKiejNvGqNwAAADcAAAANABUAYS9fX2luaXRfXy5weVVUCQADJ0fZN01H
2TdVeAQA9AFkAApwcmludCAnSW5pdCBtb2R1bGUgJXMsIHBhdGg9JXMnICUgKF9fbmFtZV9f
LF9fcGF0aF9fKQpQSwMECgACAAAALaAqJ+7ynLElAAAAJQAAAAcAFQBhL2FiLnB5VVQJAAN2
R9k3hEfZN1V4BAD0AWQACnByaW50ICdJbml0IG1vZHVsZSAlcycgJSAoX19uYW1lX18pClBL
AwQKAAIAAAAHoConozbxqjcAAAA3AAAADwAVAGEvYi9fX2luaXRfXy5weVVUCQADLkfZN09H
2TdVeAQA9AFkAApwcmludCAnSW5pdCBtb2R1bGUgJXMsIHBhdGg9JXMnICUgKF9fbmFtZV9f
LF9fcGF0aF9fKQpQSwMEFAACAAgAFqYqJzw5S0GaAAAAAgEAAAkAFQBhL2IvYmMucHlVVAkA
A4tS2TeTUtk3VXgEAPQBZABljkEKgzAQRfc5xYcitpscoOABuumqpcsQddSAyUgSld6+amMR
uprFf2/+F4M3LiK/ORNhuR57QhZyZDgr5bQlpS5CJOjh38a1MHZgH8HNLigldYmigF6vlDIX
idmSn/8ihI7HvobjGZ2eCLqqKARETk82+Ysn94Q7e6t7jEG3hHnzS7qKxrNdoH3OoecZ1pl/
OWZCS/HYsUgfUEsBAhYDCgACAAAABKAqJ6M28ao3AAAANwAAAA0ADQAAAAAAAQAAAKSBAAAA
AGEvX19pbml0X18ucHlVVAUAAydH2TdVeAAAUEsBAhYDCgACAAAALaAqJ+7ynLElAAAAJQAA
AAcADQAAAAAAAQAAAKSBdwAAAGEvYWIucHlVVAUAA3ZH2TdVeAAAUEsBAhYDCgACAAAAB6Aq
J6M28ao3AAAANwAAAA8ADQAAAAAAAQAAAKSB1gAAAGEvYi9fX2luaXRfXy5weVVUBQADLkfZ
N1V4AABQSwECFgMUAAIACAAWpionPDlLQZoAAAACAQAACQANAAAAAAABAAAApIFPAQAAYS9i
L2JjLnB5VVQFAAOLUtk3VXgAAFBLBQYAAAAABAAEABgBAAAlAgAAAAA=
--------------60F2EF1167E1920659766E3D--