[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