[PEAK] imports (Re: Package organization)
alexander smishlajev
alex at ank-sia.com
Thu Dec 4 04:13:30 EST 2003
Phillip J. Eby wrote, at 03.12.2003 20:30:
> Also, a discussion came up on IRC lately about 'from peak.api import *'
> and what it returns. Some folks argued (in effect) that it should only
> import core APIs and primitives, not framework APIs. I'm not sure I
> agree with this, and would like to see more discussion on it here.
>
> Personally, I like peak.api exporting framework APIs, core APIs, and
> primitives. Since most of the code I write either *is* PEAK, or uses
> PEAK, these are the API's I'm going to be using. Thus, to me, having to
> write, e.g.:
>
> from peak.api import * # get the core
> from peak.api import logs, storage, query
>
> when I'm creating a DM module, seems like overkill. Indeed, I'm pretty
> positive that if I did this, I'd have obscure runtime breakage if for
> example I used self.log.log(logs.TRACE) somewhere after forgetting to
> import 'logs'.
i would prefer peak.api (or whatever name is chosen for such module) to
export only core - no primitives, no frameworks.
however, this issue does not affect me or my colleagues since the coding
policy in our company is to avoid 'from module import *' in favor of
'import module' (better) or 'from module import symbol1, symbol2'. so
we never do 'from peak.api import *'.
by the way, i would like to mention some problems i discovered in
peak.util.imports.
first, there is inconsistence between LazyModule and _loadAndRunHooks:
if any of the hooks fail, _loadAndRunHooks still believes that the
module is imported (by disabling all postLoadHooks for that module), but
LazyModule thinks that the module is *not* imported, and tries to
_loadAndRunHooks again upon the next attribute access. this leads to
AlreadyRead exception.
second, _loadAndRunHooks may be executed before the module code. if any
of the hooks refer to an attribute of the module being imported, it fail:
Python 2.3.2 (#49, Oct 2 2003, 20:02:00) [MSC v.1200 32 bit (Intel)] on
win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from peak.config.interfaces import IConfigKey
Traceback (most recent call last):
File "<stdin>", line 1, in ?
File "E:\Python23\Lib\site-packages\peak\config\interfaces.py", line
1, in ?
from peak.api import protocols, exceptions, PropertyName, NOT_GIVEN
File "E:\Python23\Lib\site-packages\peak\api\__init__.py", line 275, in ?
lambda interfaces: (
File "E:\Python23\lib\site-packages\peak\util\imports.py", line 231,
in whenImported
hook(module)
File "E:\Python23\Lib\site-packages\peak\api\__init__.py", line 275,
in <lambda>
lambda interfaces: (
AttributeError: 'module' object has no attribute 'IConfigKey'
>>>
this makes lazy modules incompatible with non-basic import mechanisms,
like imputil. essentially, they do
module = imp.new_module(fqname)
exec code in module.__dict__
this launches _loadAndRunHooks upon access to module.__dict__ (or any
special import attribute, like '__importer__' or '__ispkg__'), when the
module code has not been executed, and always leads to the problem shown
in above example.
for my application packaging, i found a workaround to overcome peak
module lazyness, so these problems do not bite me much yet.
i just think: do lazy core modules make sense at all? i.e. how common
is it for core modules to not instantiate at the very start of the
application?
best wishes,
alex.
More information about the PEAK
mailing list