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},