Mercurial > cpython-lru_cache-weakref
comparison Python/import.c @ 76450:b773a751c2e7
Issue #13959: Re-implement imp.cache_from_source() in Lib/imp.py.
| author | Brett Cannon <brett@python.org> |
|---|---|
| date | Fri, 20 Apr 2012 21:44:46 -0400 |
| parents | db5e3431ee4c |
| children | ea46ebba8a0f |
comparison
equal
deleted
inserted
replaced
| 76449:163360370ad2 | 76450:b773a751c2e7 |
|---|---|
| 781 "sys.modules failed"); | 781 "sys.modules failed"); |
| 782 } | 782 } |
| 783 | 783 |
| 784 static PyObject * get_sourcefile(PyObject *filename); | 784 static PyObject * get_sourcefile(PyObject *filename); |
| 785 static PyObject *make_source_pathname(PyObject *pathname); | 785 static PyObject *make_source_pathname(PyObject *pathname); |
| 786 static PyObject* make_compiled_pathname(PyObject *pathname, int debug); | |
| 787 | 786 |
| 788 /* Execute a code object in a module and return the module object | 787 /* Execute a code object in a module and return the module object |
| 789 * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is | 788 * WITH INCREMENTED REFERENCE COUNT. If an error occurs, name is |
| 790 * removed from sys.modules, to avoid leaving damaged module objects | 789 * removed from sys.modules, to avoid leaving damaged module objects |
| 791 * in sys.modules. The caller may wish to restore the original | 790 * in sys.modules. The caller may wish to restore the original |
| 920 { | 919 { |
| 921 found = i; | 920 found = i; |
| 922 } | 921 } |
| 923 } | 922 } |
| 924 return found; | 923 return found; |
| 925 } | |
| 926 | |
| 927 /* Given a pathname for a Python source file, fill a buffer with the | |
| 928 pathname for the corresponding compiled file. Return the pathname | |
| 929 for the compiled file, or NULL if there's no space in the buffer. | |
| 930 Doesn't set an exception. | |
| 931 | |
| 932 foo.py -> __pycache__/foo.<tag>.pyc | |
| 933 | |
| 934 pathstr is assumed to be "ready". | |
| 935 */ | |
| 936 | |
| 937 static PyObject* | |
| 938 make_compiled_pathname(PyObject *pathstr, int debug) | |
| 939 { | |
| 940 PyObject *result; | |
| 941 Py_ssize_t fname, ext, len, i, pos, taglen; | |
| 942 Py_ssize_t pycache_len = sizeof(CACHEDIR) - 1; | |
| 943 int kind; | |
| 944 void *data; | |
| 945 Py_UCS4 lastsep; | |
| 946 | |
| 947 /* Compute the output string size. */ | |
| 948 len = PyUnicode_GET_LENGTH(pathstr); | |
| 949 /* If there is no separator, this returns -1, so | |
| 950 fname will be 0. */ | |
| 951 fname = rightmost_sep_obj(pathstr, 0, len) + 1; | |
| 952 /* Windows: re-use the last separator character (/ or \\) when | |
| 953 appending the __pycache__ path. */ | |
| 954 if (fname > 0) | |
| 955 lastsep = PyUnicode_READ_CHAR(pathstr, fname -1); | |
| 956 else | |
| 957 lastsep = SEP; | |
| 958 ext = fname - 1; | |
| 959 for(i = fname; i < len; i++) | |
| 960 if (PyUnicode_READ_CHAR(pathstr, i) == '.') | |
| 961 ext = i + 1; | |
| 962 if (ext < fname) | |
| 963 /* No dot in filename; use entire filename */ | |
| 964 ext = len; | |
| 965 | |
| 966 /* result = pathstr[:fname] + "__pycache__" + SEP + | |
| 967 pathstr[fname:ext] + tag + ".py[co]" */ | |
| 968 taglen = strlen(pyc_tag); | |
| 969 result = PyUnicode_New(ext + pycache_len + 1 + taglen + 4, | |
| 970 PyUnicode_MAX_CHAR_VALUE(pathstr)); | |
| 971 if (!result) | |
| 972 return NULL; | |
| 973 kind = PyUnicode_KIND(result); | |
| 974 data = PyUnicode_DATA(result); | |
| 975 PyUnicode_CopyCharacters(result, 0, pathstr, 0, fname); | |
| 976 pos = fname; | |
| 977 for (i = 0; i < pycache_len; i++) | |
| 978 PyUnicode_WRITE(kind, data, pos++, CACHEDIR[i]); | |
| 979 PyUnicode_WRITE(kind, data, pos++, lastsep); | |
| 980 PyUnicode_CopyCharacters(result, pos, pathstr, | |
| 981 fname, ext - fname); | |
| 982 pos += ext - fname; | |
| 983 for (i = 0; pyc_tag[i]; i++) | |
| 984 PyUnicode_WRITE(kind, data, pos++, pyc_tag[i]); | |
| 985 PyUnicode_WRITE(kind, data, pos++, '.'); | |
| 986 PyUnicode_WRITE(kind, data, pos++, 'p'); | |
| 987 PyUnicode_WRITE(kind, data, pos++, 'y'); | |
| 988 PyUnicode_WRITE(kind, data, pos++, debug ? 'c' : 'o'); | |
| 989 return result; | |
| 990 } | 924 } |
| 991 | 925 |
| 992 | 926 |
| 993 /* Given a pathname to a Python byte compiled file, return the path to the | 927 /* Given a pathname to a Python byte compiled file, return the path to the |
| 994 source file, if the path matches the PEP 3147 format. This does not check | 928 source file, if the path matches the PEP 3147 format. This does not check |
| 2989 PyDoc_STRVAR(doc_reload, | 2923 PyDoc_STRVAR(doc_reload, |
| 2990 "reload(module) -> module\n\ | 2924 "reload(module) -> module\n\ |
| 2991 \n\ | 2925 \n\ |
| 2992 Reload the module. The module must have been successfully imported before."); | 2926 Reload the module. The module must have been successfully imported before."); |
| 2993 | 2927 |
| 2994 static PyObject * | |
| 2995 imp_cache_from_source(PyObject *self, PyObject *args, PyObject *kws) | |
| 2996 { | |
| 2997 static char *kwlist[] = {"path", "debug_override", NULL}; | |
| 2998 | |
| 2999 PyObject *pathname, *cpathname; | |
| 3000 PyObject *debug_override = NULL; | |
| 3001 int debug = !Py_OptimizeFlag; | |
| 3002 | |
| 3003 if (!PyArg_ParseTupleAndKeywords( | |
| 3004 args, kws, "O&|O", kwlist, | |
| 3005 PyUnicode_FSDecoder, &pathname, &debug_override)) | |
| 3006 return NULL; | |
| 3007 | |
| 3008 if (debug_override != NULL && | |
| 3009 (debug = PyObject_IsTrue(debug_override)) < 0) { | |
| 3010 Py_DECREF(pathname); | |
| 3011 return NULL; | |
| 3012 } | |
| 3013 | |
| 3014 if (PyUnicode_READY(pathname) < 0) | |
| 3015 return NULL; | |
| 3016 | |
| 3017 cpathname = make_compiled_pathname(pathname, debug); | |
| 3018 Py_DECREF(pathname); | |
| 3019 | |
| 3020 if (cpathname == NULL) { | |
| 3021 PyErr_Format(PyExc_SystemError, "path buffer too short"); | |
| 3022 return NULL; | |
| 3023 } | |
| 3024 return cpathname; | |
| 3025 } | |
| 3026 | |
| 3027 PyDoc_STRVAR(doc_cache_from_source, | |
| 3028 "cache_from_source(path, [debug_override]) -> path\n\ | |
| 3029 Given the path to a .py file, return the path to its .pyc/.pyo file.\n\ | |
| 3030 \n\ | |
| 3031 The .py file does not need to exist; this simply returns the path to the\n\ | |
| 3032 .pyc/.pyo file calculated as if the .py file were imported. The extension\n\ | |
| 3033 will be .pyc unless __debug__ is not defined, then it will be .pyo.\n\ | |
| 3034 \n\ | |
| 3035 If debug_override is not None, then it must be a boolean and is taken as\n\ | |
| 3036 the value of __debug__ instead."); | |
| 3037 | 2928 |
| 3038 static PyObject * | 2929 static PyObject * |
| 3039 imp_source_from_cache(PyObject *self, PyObject *args, PyObject *kws) | 2930 imp_source_from_cache(PyObject *self, PyObject *args, PyObject *kws) |
| 3040 { | 2931 { |
| 3041 static char *kwlist[] = {"path", NULL}; | 2932 static char *kwlist[] = {"path", NULL}; |
| 3114 {"get_suffixes", imp_get_suffixes, METH_NOARGS, doc_get_suffixes}, | 3005 {"get_suffixes", imp_get_suffixes, METH_NOARGS, doc_get_suffixes}, |
| 3115 {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, | 3006 {"lock_held", imp_lock_held, METH_NOARGS, doc_lock_held}, |
| 3116 {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, | 3007 {"acquire_lock", imp_acquire_lock, METH_NOARGS, doc_acquire_lock}, |
| 3117 {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, | 3008 {"release_lock", imp_release_lock, METH_NOARGS, doc_release_lock}, |
| 3118 {"reload", imp_reload, METH_O, doc_reload}, | 3009 {"reload", imp_reload, METH_O, doc_reload}, |
| 3119 {"cache_from_source", (PyCFunction)imp_cache_from_source, | |
| 3120 METH_VARARGS | METH_KEYWORDS, doc_cache_from_source}, | |
| 3121 {"source_from_cache", (PyCFunction)imp_source_from_cache, | 3010 {"source_from_cache", (PyCFunction)imp_source_from_cache, |
| 3122 METH_VARARGS | METH_KEYWORDS, doc_source_from_cache}, | 3011 METH_VARARGS | METH_KEYWORDS, doc_source_from_cache}, |
| 3123 /* The rest are obsolete */ | 3012 /* The rest are obsolete */ |
| 3124 {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, | 3013 {"get_frozen_object", imp_get_frozen_object, METH_VARARGS}, |
| 3125 {"is_frozen_package", imp_is_frozen_package, METH_VARARGS}, | 3014 {"is_frozen_package", imp_is_frozen_package, METH_VARARGS}, |
