[Python-Dev] Python/import.c
Thomas Heller
theller at python.net
Tue Jun 8 06:32:40 EDT 2004
"Fred L. Drake, Jr." <fdrake at acm.org> writes:
> On Monday 07 June 2004 01:21 pm, Jiwon Seo wrote:
> > It looks like it's because even if the package failed to be loaded, it
> > should be added to its parent module dict, IMHO.
> > The comment in the import.c::add_submodule describes the behavior. I
> > don't know how it could be useful, but I think it's the way import
> > behaves.
>
> This is to support caching; if some module in the "foo" package imports the
> "bar" module, and there isn't a "foo.bar" module, sys.modules grows a
> "foo.bar": None entry so that further attempts to import sys within the "foo"
> package don't have to do as much work to know that there isn't one, and can
> fall back to a top-level "bar" module (which can still fail if there isn't
> one).
I knew this already ;-), but it doesn't apply to my question. The code
I quoted was commited in import.c rev 2.82 (6 years, 9 months ago), but
adding dummy entries to sys.modules was added in rev 2.85.
Here's the code again, with the refcount bug fixed (which I already
applied in CVS):
Thomas Heller <theller at python.net> writes:
> In the context of http://www.python.org/sf/845802 I'm looking at the
> code in Python/import.c, function load_package().
>
> The latter part of the function is this code, which tries to import the
> __init__.py file, after building the module object in 'm', and
> initializing it's __file__ and __path__ attributes:
>
> fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
> if (fdp == NULL) {
> if (PyErr_ExceptionMatches(PyExc_ImportError)) {
> PyErr_Clear();
Py_INCREF(m);
> }
> else
> m = NULL;
> goto cleanup;
> }
> m = load_module(name, fp, buf, fdp->type, NULL);
> if (fp != NULL)
> fclose(fp);
> cleanup:
> Py_XDECREF(path);
> Py_XDECREF(file);
> return m;
> }
>
>
> I do not understand why the function doesn't fail when find_module
> returns NULL because of an PyExc_ImportError. For the above mentioned
> bug, when __init__.py is a directory instead of a file, find_module
> returns NULL.
As far as I can tell, the code in the 'if (fdp == NULL)' part is never
executed by the whole test suite, and I believe the refcount bug would
have been found much earlier otherwise. This code *is* executed (and
the bug was triggered, at least in a debug build) when you try to import
a package where '__init__.py' is a directory instead of a file.
I believe the code should read:
> fdp = find_module(name, "__init__", path, buf, sizeof(buf), &fp, NULL);
> if (fdp == NULL) {
> m = NULL;
> goto cleanup;
> }
> m = load_module(name, fp, buf, fdp->type, NULL);
> if (fp != NULL)
> fclose(fp);
> cleanup:
> Py_XDECREF(path);
> Py_XDECREF(file);
> return m;
> }
I'll upload a patch.
Thomas
More information about the Python-Dev
mailing list