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