This issue tracker has been migrated to GitHub, and is currently read-only.
For more information, see the GitHub FAQs in the Python's Developer Guide.

Author ncoghlan
Recipients bronger, dcjim, jhylton, loewis, ncoghlan, tim.peters
Date 2008-04-13.05:57:39
SpamBayes Score 0.0003365516
Marked as misclassified No
Message-id <1208066263.19.0.219512312848.issue992389@psf.upfronthosting.co.za>
In-reply-to
Content
This is actually a pretty tough problem - fixing it would involve some
fairly subtle changes to the way imports from packages are handled.
Given that I'm of the opinion that permitting circular imports in a code
base is an extraordinarily bad coding practice (if I'm ever tempted to
create a circular import, I consider it a sign that I need to separate
out some of the common code into a utility module), I'm not personally
going to be putting any effort into solving it (although I wouldn't
necessarily oppose anyone else trying to fix it).

However, I'll give a detailed description of the problem and a possible
solution in case anyone else wants to tackle it (since I believe there's
already a similar trick done for the sys.modules cache).

At the moment, when resolving an import chain __import__ only sets the
parent package's attribute for the submodule after the submodule import
is complete. This is what Jim describes in his original post, and is the
cause of the failure to resolve the name. Deferring the lookups solves
the problem because it means the package attributes are checked only
after the whole import chain is complete, instead of trying to get
access to a half-executed module during the import itself.

The most likely solution to the problem would be to change the attribute
on the parent package to be handled in a fashion closer to the way the
sys.modules cache is handled: set the attribute on the parent package
*before* executing the module's code, and delete that attribute if a
problem is encountered with the import.

The consequence of this would be that circular imports would be
permitted, although the module's imported in this fashion would be seen
in a half constructed state. So instead of the import failing with an
exception (which is what happens now), you would instead get a module
which you can't actually use (since most its attributes won't actually
be filled in yet, as the circular imports will normally occur near the
top of the file). Attempts to use methods, attributes and functions from
the module may or may not work depending on the order in which the
original module does things.

A clean failure indicating "You have a circular import, get rid of it"
seems better to me than possible hard to diagnose bugs due to being able
to retrieve things from a half-constructed module, but opinions
obviously differ on that. However, I really don't see this changing
without a PEP.
History
Date User Action Args
2008-04-13 05:57:43ncoghlansetspambayes_score: 0.000336552 -> 0.0003365516
recipients: + ncoghlan, tim.peters, loewis, jhylton, dcjim, bronger
2008-04-13 05:57:43ncoghlansetspambayes_score: 0.000336552 -> 0.000336552
messageid: <1208066263.19.0.219512312848.issue992389@psf.upfronthosting.co.za>
2008-04-13 05:57:41ncoghlanlinkissue992389 messages
2008-04-13 05:57:39ncoghlancreate