Mercurial > cpython-lru_cache-weakref
annotate Python/import.c @ 66:46cb14aec10a legacy-trunk
Reformulated err_badarg error message.
| author | Guido van Rossum <guido@python.org> |
|---|---|
| date | Fri, 09 Nov 1990 15:05:53 +0000 |
| parents | f28ac7f621c7 |
| children | bc244df20251 |
| rev | line source |
|---|---|
| 6 | 1 /* Module definition and import implementation */ |
| 2 | |
| 3 #include <stdio.h> | |
| 4 #include "string.h" | |
| 5 | |
| 6 #include "PROTO.h" | |
| 7 #include "object.h" | |
| 8 #include "stringobject.h" | |
| 9 #include "listobject.h" | |
| 10 #include "dictobject.h" | |
| 11 #include "moduleobject.h" | |
| 12 #include "node.h" | |
| 13 #include "context.h" | |
| 14 #include "token.h" | |
| 15 #include "graminit.h" | |
| 16 #include "run.h" | |
| 17 #include "support.h" | |
| 18 #include "import.h" | |
| 19 #include "errcode.h" | |
| 20 #include "sysmodule.h" | |
| 21 | |
| 22 /* Define pathname separator and delimiter in $PYTHONPATH */ | |
| 23 | |
| 24 #ifdef THINK_C | |
| 25 #define SEP ':' | |
| 26 #define DELIM ' ' | |
| 27 #endif | |
| 28 | |
| 29 #ifndef SEP | |
| 30 #define SEP '/' | |
| 31 #endif | |
| 32 | |
| 33 #ifndef DELIM | |
| 34 #define DELIM ':' | |
| 35 #endif | |
| 36 | |
| 37 void | |
| 38 initimport() | |
| 39 { | |
| 40 object *v; | |
| 41 if ((v = newdictobject()) == NULL) | |
| 42 fatal("no mem for module table"); | |
| 43 if (sysset("modules", v) != 0) | |
| 44 fatal("can't assign sys.modules"); | |
| 45 } | |
| 46 | |
| 47 object * | |
| 48 new_module(name) | |
| 49 char *name; | |
| 50 { | |
| 51 object *m; | |
| 52 object *mtab; | |
| 53 mtab = sysget("modules"); | |
| 54 if (mtab == NULL || !is_dictobject(mtab)) { | |
| 55 errno = EBADF; | |
| 56 return NULL; | |
| 57 } | |
| 58 m = newmoduleobject(name); | |
| 59 if (m == NULL) | |
| 60 return NULL; | |
| 61 if (dictinsert(mtab, name, m) != 0) { | |
| 62 DECREF(m); | |
| 63 return NULL; | |
| 64 } | |
| 65 return m; | |
| 66 } | |
| 67 | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
68 static void |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
69 use_module(ctx, d) |
| 6 | 70 context *ctx; |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
71 object *d; |
| 6 | 72 { |
| 73 INCREF(d); | |
| 74 DECREF(ctx->ctx_locals); | |
| 75 ctx->ctx_locals = d; | |
| 76 INCREF(d); | |
| 77 DECREF(ctx->ctx_globals); | |
| 78 ctx->ctx_globals = d; | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
79 } |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
80 |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
81 static void |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
82 define_module(ctx, name) |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
83 context *ctx; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
84 char *name; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
85 { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
86 object *m; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
87 m = new_module(name); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
88 if (m == NULL) { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
89 puterrno(ctx); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
90 return; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
91 } |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
92 use_module(ctx, getmoduledict(m)); |
| 6 | 93 DECREF(m); |
| 94 } | |
| 95 | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
96 static object * |
| 6 | 97 parsepath(path, delim) |
| 98 char *path; | |
| 99 int delim; | |
| 100 { | |
| 101 int i, n; | |
| 102 char *p; | |
| 103 object *v, *w; | |
| 104 | |
| 105 n = 1; | |
| 106 p = path; | |
| 107 while ((p = strchr(p, delim)) != NULL) { | |
| 108 n++; | |
| 109 p++; | |
| 110 } | |
| 111 v = newlistobject(n); | |
| 112 if (v == NULL) | |
| 113 return NULL; | |
| 114 for (i = 0; ; i++) { | |
| 115 p = strchr(path, delim); | |
| 116 if (p == NULL) | |
| 117 p = strchr(path, '\0'); /* End of string */ | |
| 118 w = newsizedstringobject(path, (int) (p - path)); | |
| 119 if (w == NULL) { | |
| 120 DECREF(v); | |
| 121 return NULL; | |
| 122 } | |
| 123 setlistitem(v, i, w); | |
| 124 if (*p == '\0') | |
| 125 break; | |
| 126 path = p+1; | |
| 127 } | |
| 128 return v; | |
| 129 } | |
| 130 | |
| 131 void | |
| 132 setpythonpath(path) | |
| 133 char *path; | |
| 134 { | |
| 135 object *v; | |
| 136 if ((v = parsepath(path, DELIM)) != NULL) { | |
| 137 if (sysset("path", v) != 0) | |
| 138 fatal("can't assign sys.path"); | |
| 139 DECREF(v); | |
| 140 } | |
| 141 } | |
| 142 | |
| 143 static FILE * | |
| 144 open_module(name, suffix) | |
| 145 char *name; | |
| 146 char *suffix; | |
| 147 { | |
| 148 object *path; | |
| 149 char namebuf[256]; | |
| 150 FILE *fp; | |
| 151 | |
| 152 path = sysget("path"); | |
| 153 if (path == NULL || !is_listobject(path)) { | |
| 154 strcpy(namebuf, name); | |
| 155 strcat(namebuf, suffix); | |
| 156 fp = fopen(namebuf, "r"); | |
| 157 } | |
| 158 else { | |
| 159 int npath = getlistsize(path); | |
| 160 int i; | |
| 161 fp = NULL; | |
| 162 for (i = 0; i < npath; i++) { | |
| 163 object *v = getlistitem(path, i); | |
| 164 int len; | |
| 165 if (!is_stringobject(v)) | |
| 166 continue; | |
| 167 strcpy(namebuf, getstringvalue(v)); | |
| 168 len = getstringsize(v); | |
| 169 if (len > 0 && namebuf[len-1] != SEP) | |
| 170 namebuf[len++] = SEP; | |
| 171 strcpy(namebuf+len, name); /* XXX check for overflow */ | |
| 172 strcat(namebuf, suffix); /* XXX ditto */ | |
| 173 fp = fopen(namebuf, "r"); | |
| 174 if (fp != NULL) | |
| 175 break; | |
| 176 } | |
| 177 } | |
| 178 return fp; | |
| 179 } | |
| 180 | |
| 181 static object * | |
| 182 load_module(ctx, name) | |
| 183 context *ctx; | |
| 184 char *name; | |
| 185 { | |
| 186 object *m; | |
| 187 char **p; | |
| 188 FILE *fp; | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
189 node *n; |
| 6 | 190 int err; |
| 191 object *mtab; | |
| 192 object *save_locals, *save_globals; | |
| 193 | |
| 194 mtab = sysget("modules"); | |
| 195 if (mtab == NULL || !is_dictobject(mtab)) { | |
| 196 errno = EBADF; | |
| 197 return NULL; | |
| 198 } | |
| 199 fp = open_module(name, ".py"); | |
| 200 if (fp == NULL) { | |
| 201 name_error(ctx, name); | |
| 202 return NULL; | |
| 203 } | |
| 204 err = parseinput(fp, file_input, &n); | |
| 205 fclose(fp); | |
| 206 if (err != E_DONE) { | |
| 207 input_error(ctx, err); | |
| 208 return NULL; | |
| 209 } | |
| 210 save_locals = ctx->ctx_locals; | |
| 211 INCREF(save_locals); | |
| 212 save_globals = ctx->ctx_globals; | |
| 213 INCREF(save_globals); | |
| 214 define_module(ctx, name); | |
| 215 exec_node(ctx, n); | |
| 216 DECREF(ctx->ctx_locals); | |
| 217 ctx->ctx_locals = save_locals; | |
| 218 DECREF(ctx->ctx_globals); | |
| 219 ctx->ctx_globals = save_globals; | |
| 220 /* XXX need to free the tree n here; except referenced defs */ | |
| 221 if (ctx->ctx_exception) { | |
| 222 dictremove(mtab, name); /* Undefine the module */ | |
| 223 return NULL; | |
| 224 } | |
| 225 m = dictlookup(mtab, name); | |
| 226 if (m == NULL) { | |
| 227 error(ctx, "module not defined after loading"); | |
| 228 return NULL; | |
| 229 } | |
| 230 return m; | |
| 231 } | |
| 232 | |
| 233 object * | |
| 234 import_module(ctx, name) | |
| 235 context *ctx; | |
| 236 char *name; | |
| 237 { | |
| 238 object *m; | |
| 239 object *mtab; | |
| 240 mtab = sysget("modules"); | |
| 241 if (mtab == NULL || !is_dictobject(mtab)) { | |
| 242 error(ctx, "bad sys.modules"); | |
| 243 return NULL; | |
| 244 } | |
| 245 if ((m = dictlookup(mtab, name)) == NULL) { | |
| 246 m = load_module(ctx, name); | |
| 247 } | |
| 248 return m; | |
| 249 } | |
|
40
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
250 |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
251 object * |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
252 reload_module(ctx, m) |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
253 context *ctx; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
254 object *m; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
255 { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
256 char *name; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
257 FILE *fp; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
258 node *n; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
259 int err; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
260 object *d; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
261 object *save_locals, *save_globals; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
262 if (m == NULL || !is_moduleobject(m)) { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
263 type_error(ctx, "reload() argument must be module"); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
264 return NULL; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
265 } |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
266 /* XXX Ought to check for builtin module */ |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
267 name = getmodulename(m); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
268 fp = open_module(name, ".py"); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
269 if (fp == NULL) { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
270 error(ctx, "reload() cannot find module source file"); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
271 return NULL; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
272 } |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
273 err = parseinput(fp, file_input, &n); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
274 fclose(fp); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
275 if (err != E_DONE) { |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
276 input_error(ctx, err); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
277 return NULL; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
278 } |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
279 d = newdictobject(); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
280 if (d == NULL) |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
281 return NULL; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
282 setmoduledict(m, d); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
283 save_locals = ctx->ctx_locals; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
284 INCREF(save_locals); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
285 save_globals = ctx->ctx_globals; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
286 INCREF(save_globals); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
287 use_module(ctx, d); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
288 exec_node(ctx, n); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
289 DECREF(ctx->ctx_locals); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
290 ctx->ctx_locals = save_locals; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
291 DECREF(ctx->ctx_globals); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
292 ctx->ctx_globals = save_globals; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
293 if (ctx->ctx_exception) |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
294 return NULL; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
295 INCREF(None); |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
296 return None; |
|
f28ac7f621c7
Added reload() functionality.
Guido van Rossum <guido@python.org>
parents:
6
diff
changeset
|
297 } |
