Metadata-Version: 1.1
Name: zope.app.module
Version: 3.5.0
Summary: Zope 3 persistent code/module support
Home-page: http://pypi.python.org/pypi/zope.app.module
Author: Zope Corporation and Contributors
Author-email: zope-dev@zope.org
License: ZPL 2.1
Description: Persistent Python modules allow us to develop and store Python modules in the
        ZODB in contrast to storing them on the filesystem. You might want to look at
        the `zodbcode` package for the details of the implementation. In Zope 3 we
        implemented persistent modules as utilities. These utilities are known as
        module managers that manage the source code, compiled module and name of the
        module. We then provide a special module registry that looks up the utilities
        to find modules.
        
        
        Detailed Documentation
        ----------------------
        
        
        =========================
        Persistent Python Modules
        =========================
        
        Persistent Python modules allow us to develop and store Python modules in the
        ZODB in contrast to storing them on the filesystem. You might want to look at
        the `zodbcode` package for the details of the implementation. In Zope 3 we
        implemented persistent modules as utilities. These utilities are known as
        module managers that manage the source code, compiled module and name of the
        module. We then provide a special module registry that looks up the utilities
        to find modules.
        
        
        The Module Manager
        ------------------
        
        One can simply create a new module manager by instantiating it:
        
          >>> from zope.app.module.manager import ModuleManager
          >>> manager = ModuleManager()
        
        If I create the manager without an argument, there is no source code:
        
          >>> manager.source
          ''
        
        When we add some code
        
          >>> manager.source = """\n
          ... foo = 1
          ... def bar(): return foo
          ... class Blah(object):
          ...     def __init__(self, id): self.id = id
          ...     def __repr__(self): return 'Blah(id=%s)' % self.id
          ... """
        
        we can get the compiled module and use the created objects:
        
          >>> module = manager.getModule()
          >>> module.foo
          1
          >>> module.bar()
          1
          >>> module.Blah('blah')
          Blah(id=blah)
        
        We can also ask for the name of the module:
        
          >>> manager.name
          >>> module.__name__
        
        But why is it `None`? Because we have no registered it yet. Once we register
        and activate the registration a name will be set:
        
          >>> from zope.app.testing import setup
          >>> root = setup.buildSampleFolderTree()
          >>> root_sm = setup.createSiteManager(root)
        
          >>> from zope.app.module import interfaces
          >>> manager = setup.addUtility(root_sm, 'mymodule',
          ...                            interfaces.IModuleManager, manager)
        
          >>> manager.name
          'mymodule'
        
          >>> manager.getModule().__name__
          'mymodule'
        
        Next, let's ensure that the module's persistence works correctly. To do that
        let's create a database and add the root folder to it:
        
          >>> from ZODB.tests.util import DB
          >>> db = DB()
          >>> conn = db.open()
          >>> conn.root()['Application'] = root
        
          >>> import transaction
          >>> transaction.commit()
        
        Let's now reopen the database to test that the module can be seen from a
        different connection.
        
          >>> conn2 = db.open()
          >>> root2 = conn2.root()['Application']
          >>> module2 = root2.getSiteManager().queryUtility(
          ...     interfaces.IModuleManager, 'mymodule').getModule()
          >>> module2.foo
          1
          >>> module2.bar()
          1
          >>> module2.Blah('blah')
          Blah(id=blah)
        
        
        Module Lookup API
        -----------------
        
        The way the persistent module framework hooks into Python is via module
        registires that behave pretty much like `sys.modules`. Zope 3 provides its own
        module registry that uses the registered utilities to look up modules:
        
          >>> from zope.app.module import ZopeModuleRegistry
          >>> ZopeModuleRegistry.findModule('mymodule')
        
        But why did we not get the module back? Because we have not set the site yet:
        
          >>> from zope.app.component import hooks
          >>> hooks.setSite(root)
        
        Now it will find the module and we can retrieve a list of all persistent
        module names:
        
          >>> ZopeModuleRegistry.findModule('mymodule') is module
          True
          >>> ZopeModuleRegistry.modules()
          [u'mymodule']
        
        Additionally, the package provides two API functions that look up a module in
        the registry and then in `sys.modules`:
        
          >>> import zope.app.module
          >>> zope.app.module.findModule('mymodule') is module
          True
          >>> zope.app.module.findModule('zope.app.module') is zope.app.module
          True
        
        The second function can be used to lookup objects inside any module:
        
          >>> zope.app.module.resolve('mymodule.foo')
          1
          >>> zope.app.module.resolve('zope.app.module.foo.resolve')
        
        In order to use this framework in real Python code import statements, we need
        to install the importer hook, which is commonly done with an event subscriber:
        
          >>> import __builtin__
          >>> event = object()
          >>> zope.app.module.installPersistentModuleImporter(event)
          >>> __builtin__.__import__ # doctest: +ELLIPSIS
          <bound method ZopePersistentModuleImporter.__import__ of ...>
        
        Now we can simply import the persistent module:
        
          >>> import mymodule
          >>> mymodule.Blah('my id')
          Blah(id=my id)
        
        Finally, we unregister the hook again:
        
          >>> zope.app.module.uninstallPersistentModuleImporter(event)
          >>> __builtin__.__import__
          <built-in function __import__>
        
        
        =====================
        Persistent Interfaces
        =====================
        
        zope.app.module's ModuleManagers behave a little differently when
        interfaces are involved::
        
          >>> from zope.app.module.manager import ModuleManager
          >>> manager = ModuleManager()
          >>> source = """\n
          ... from zope.interface import Interface
          ... class IFoo(Interface): pass
          ... class IBar(IFoo): pass
          ... """
          >>> manager.source = source
        
        A ModuleManager doesn't get a name until it's registered and the
        zodbcode wrappers break without a name, so we can't retrieve our
        module until our manager is registered::
        
          >>> from zope.app.testing import setup
          >>> from zope.app.module import interfaces
          >>> root = setup.buildSampleFolderTree()
          >>> root_sm = setup.createSiteManager(root)
          >>> manager = setup.addUtility(root_sm, u'foo',
          ...                            interfaces.IModuleManager, manager)
        
        Now we can compile a module with interfaces and access everything
        appropriately::
        
          >>> module = manager.getModule()
          >>> module
          <PersistentModule foo>
          >>> module.IFoo
          <PersistentInterfaceClass foo.IFoo>
          >>> module.IBar
          <PersistentInterfaceClass foo.IBar>
        
        
        =======
        CHANGES
        =======
        
        3.5.0 (2009-02-01)
        ------------------
        
        - Use zope.container instead of zope.app.container.
        
        3.4.0 (2007-10-25)
        ------------------
        
        - Initial release independent of the main Zope tree.
        
Keywords: zope3 code module zodb local
Platform: UNKNOWN
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Web Environment
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
Classifier: Natural Language :: English
Classifier: Operating System :: OS Independent
Classifier: Topic :: Internet :: WWW/HTTP
Classifier: Framework :: Zope3
