Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit c405b7b

Browse files
committed
Support ".pyc" files: cached compilation results.
(Similar to Emacs ".elc" files.)
1 parent 2cfd356 commit c405b7b

1 file changed

Lines changed: 72 additions & 5 deletions

File tree

Python/import.c

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,13 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3333
#include "errcode.h"
3434
#include "sysmodule.h"
3535
#include "pythonrun.h"
36+
#include "marshal.h"
37+
#include "compile.h"
38+
#include "ceval.h"
39+
40+
#ifdef THINK_C
41+
#define macintosh
42+
#endif
3643

3744
/* Define pathname separator used in file names */
3845

@@ -130,11 +137,15 @@ get_module(m, name, m_ret)
130137
char *name;
131138
object **m_ret;
132139
{
133-
object *d;
134-
FILE *fp;
140+
codeobject *co = NULL;
141+
object *v, *d;
142+
FILE *fp, *fpc;
135143
node *n;
136144
int err;
137-
char namebuf[256];
145+
char namebuf[258];
146+
int namelen;
147+
long mtime;
148+
extern long getmtime();
138149

139150
fp = open_module(name, ".py", namebuf);
140151
if (fp == NULL) {
@@ -144,7 +155,33 @@ get_module(m, name, m_ret)
144155
err_setstr(RuntimeError, "no module source file");
145156
return NULL;
146157
}
147-
err = parse_file(fp, namebuf, file_input, &n);
158+
/* Get mtime -- always useful */
159+
mtime = getmtime(namebuf);
160+
/* Check ".pyc" file first */
161+
namelen = strlen(namebuf);
162+
namebuf[namelen] = 'c';
163+
namebuf[namelen+1] = '\0';
164+
fpc = fopen(namebuf, "rb");
165+
if (fpc != NULL) {
166+
long pyc_mtime;
167+
(void) rd_long(fpc); /* Reserved for magic word */
168+
pyc_mtime = rd_long(fpc);
169+
if (pyc_mtime != 0 && pyc_mtime != -1 && pyc_mtime == mtime) {
170+
v = rd_object(fpc);
171+
if (v == NULL || err_occurred() || !is_codeobject(v)) {
172+
err_clear();
173+
XDECREF(v);
174+
}
175+
else
176+
co = (codeobject *)v;
177+
}
178+
fclose(fpc);
179+
}
180+
namebuf[namelen] = '\0';
181+
if (co == NULL)
182+
err = parse_file(fp, namebuf, file_input, &n);
183+
else
184+
err = E_DONE;
148185
fclose(fp);
149186
if (err != E_DONE) {
150187
err_input(err);
@@ -159,7 +196,37 @@ get_module(m, name, m_ret)
159196
*m_ret = m;
160197
}
161198
d = getmoduledict(m);
162-
return run_node(n, namebuf, d, d);
199+
if (co == NULL) {
200+
co = compile(n, namebuf);
201+
freetree(n);
202+
if (co == NULL)
203+
return NULL;
204+
/* Now write the code object to the ".pyc" file */
205+
namebuf[namelen] = 'c';
206+
namebuf[namelen+1] = '\0';
207+
fpc = fopen(namebuf, "wb");
208+
if (fpc != NULL) {
209+
wr_long(0L, fpc); /* Reserved for magic word */
210+
/* First write a 0 for mtime */
211+
wr_long(0L, fpc);
212+
wr_object((object *)co, fpc);
213+
if (ferror(fpc)) {
214+
/* Don't keep partial file */
215+
fclose(fpc);
216+
(void) unlink(namebuf);
217+
}
218+
else {
219+
/* Now write the true mtime */
220+
fseek(fpc, 4L, 0);
221+
wr_long(mtime, fpc);
222+
fflush(fpc);
223+
fclose(fpc);
224+
}
225+
}
226+
}
227+
v = eval_code(co, d, d, (object *)NULL);
228+
DECREF(co);
229+
return v;
163230
}
164231

165232
static object *

0 commit comments

Comments
 (0)