{ "info": { "author": "Zope Corporation and Contributors", "author_email": "zope-dev@zope.org", "bugtrack_url": null, "classifiers": [ "Development Status :: 5 - Production/Stable", "Environment :: Web Environment", "Framework :: Zope3", "Intended Audience :: Developers", "License :: OSI Approved :: Zope Public License", "Natural Language :: English", "Operating System :: OS Independent", "Programming Language :: Python", "Topic :: Internet :: WWW/HTTP" ], "description": "Persistent Python modules allow us to develop and store Python modules in the\nZODB in contrast to storing them on the filesystem. You might want to look at\nthe `zodbcode` package for the details of the implementation. In Zope 3 we\nimplemented persistent modules as utilities. These utilities are known as\nmodule managers that manage the source code, compiled module and name of the\nmodule. We then provide a special module registry that looks up the utilities\nto find modules.\n\n\nDetailed Documentation\n----------------------\n\n\n=========================\nPersistent Python Modules\n=========================\n\nPersistent Python modules allow us to develop and store Python modules in the\nZODB in contrast to storing them on the filesystem. You might want to look at\nthe `zodbcode` package for the details of the implementation. In Zope 3 we\nimplemented persistent modules as utilities. These utilities are known as\nmodule managers that manage the source code, compiled module and name of the\nmodule. We then provide a special module registry that looks up the utilities\nto find modules.\n\n\nThe Module Manager\n------------------\n\nOne can simply create a new module manager by instantiating it:\n\n >>> from zope.app.module.manager import ModuleManager\n >>> manager = ModuleManager()\n\nIf I create the manager without an argument, there is no source code:\n\n >>> manager.source\n ''\n\nWhen we add some code\n\n >>> manager.source = \"\"\"\\n\n ... foo = 1\n ... def bar(): return foo\n ... class Blah(object):\n ... def __init__(self, id): self.id = id\n ... def __repr__(self): return 'Blah(id=%s)' % self.id\n ... \"\"\"\n\nwe can get the compiled module and use the created objects:\n\n >>> module = manager.getModule()\n >>> module.foo\n 1\n >>> module.bar()\n 1\n >>> module.Blah('blah')\n Blah(id=blah)\n\nWe can also ask for the name of the module:\n\n >>> manager.name\n >>> module.__name__\n\nBut why is it `None`? Because we have no registered it yet. Once we register\nand activate the registration a name will be set:\n\n >>> from zope.app.testing import setup\n >>> root = setup.buildSampleFolderTree()\n >>> root_sm = setup.createSiteManager(root)\n\n >>> from zope.app.module import interfaces\n >>> manager = setup.addUtility(root_sm, 'mymodule',\n ... interfaces.IModuleManager, manager)\n\n >>> manager.name\n 'mymodule'\n\n >>> manager.getModule().__name__\n 'mymodule'\n\nNext, let's ensure that the module's persistence works correctly. To do that\nlet's create a database and add the root folder to it:\n\n >>> from ZODB.tests.util import DB\n >>> db = DB()\n >>> conn = db.open()\n >>> conn.root()['Application'] = root\n\n >>> import transaction\n >>> transaction.commit()\n\nLet's now reopen the database to test that the module can be seen from a\ndifferent connection.\n\n >>> conn2 = db.open()\n >>> root2 = conn2.root()['Application']\n >>> module2 = root2.getSiteManager().queryUtility(\n ... interfaces.IModuleManager, 'mymodule').getModule()\n >>> module2.foo\n 1\n >>> module2.bar()\n 1\n >>> module2.Blah('blah')\n Blah(id=blah)\n\n\nModule Lookup API\n-----------------\n\nThe way the persistent module framework hooks into Python is via module\nregistires that behave pretty much like `sys.modules`. Zope 3 provides its own\nmodule registry that uses the registered utilities to look up modules:\n\n >>> from zope.app.module import ZopeModuleRegistry\n >>> ZopeModuleRegistry.findModule('mymodule')\n\nBut why did we not get the module back? Because we have not set the site yet:\n\n >>> from zope.app.component import hooks\n >>> hooks.setSite(root)\n\nNow it will find the module and we can retrieve a list of all persistent\nmodule names:\n\n >>> ZopeModuleRegistry.findModule('mymodule') is module\n True\n >>> ZopeModuleRegistry.modules()\n [u'mymodule']\n\nAdditionally, the package provides two API functions that look up a module in\nthe registry and then in `sys.modules`:\n\n >>> import zope.app.module\n >>> zope.app.module.findModule('mymodule') is module\n True\n >>> zope.app.module.findModule('zope.app.module') is zope.app.module\n True\n\nThe second function can be used to lookup objects inside any module:\n\n >>> zope.app.module.resolve('mymodule.foo')\n 1\n >>> zope.app.module.resolve('zope.app.module.foo.resolve')\n\nIn order to use this framework in real Python code import statements, we need\nto install the importer hook, which is commonly done with an event subscriber:\n\n >>> import __builtin__\n >>> event = object()\n >>> zope.app.module.installPersistentModuleImporter(event)\n >>> __builtin__.__import__ # doctest: +ELLIPSIS\n \n\nNow we can simply import the persistent module:\n\n >>> import mymodule\n >>> mymodule.Blah('my id')\n Blah(id=my id)\n\nFinally, we unregister the hook again:\n\n >>> zope.app.module.uninstallPersistentModuleImporter(event)\n >>> __builtin__.__import__\n \n\n\n=====================\nPersistent Interfaces\n=====================\n\nzope.app.module's ModuleManagers behave a little differently when\ninterfaces are involved::\n\n >>> from zope.app.module.manager import ModuleManager\n >>> manager = ModuleManager()\n >>> source = \"\"\"\\n\n ... from zope.interface import Interface\n ... class IFoo(Interface): pass\n ... class IBar(IFoo): pass\n ... \"\"\"\n >>> manager.source = source\n\nA ModuleManager doesn't get a name until it's registered and the\nzodbcode wrappers break without a name, so we can't retrieve our\nmodule until our manager is registered::\n\n >>> from zope.app.testing import setup\n >>> from zope.app.module import interfaces\n >>> root = setup.buildSampleFolderTree()\n >>> root_sm = setup.createSiteManager(root)\n >>> manager = setup.addUtility(root_sm, u'foo',\n ... interfaces.IModuleManager, manager)\n\nNow we can compile a module with interfaces and access everything\nappropriately::\n\n >>> module = manager.getModule()\n >>> module\n \n >>> module.IFoo\n \n >>> module.IBar\n \n\n\n=======\nCHANGES\n=======\n\n3.5.0 (2009-02-01)\n------------------\n\n- Use zope.container instead of zope.app.container.\n\n3.4.0 (2007-10-25)\n------------------\n\n- Initial release independent of the main Zope tree.", "description_content_type": null, "docs_url": null, "download_url": "UNKNOWN", "downloads": { "last_day": -1, "last_month": -1, "last_week": -1 }, "home_page": "http://pypi.python.org/pypi/zope.app.module", "keywords": "zope3 code module zodb local", "license": "ZPL 2.1", "maintainer": null, "maintainer_email": null, "name": "zope.app.module", "package_url": "https://pypi.org/project/zope.app.module/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/zope.app.module/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/zope.app.module" }, "release_url": "https://pypi.org/project/zope.app.module/3.5.0/", "requires_dist": null, "requires_python": null, "summary": "Zope 3 persistent code/module support", "version": "3.5.0" }, "last_serial": 805214, "releases": { "3.4.0": [ { "comment_text": "", "digests": { "md5": "c9e45fdcb5b958a9ed23c47e7c2d17ad", "sha256": "92ae5b593b1c96be0f566219c3411fd113a1621975d24fe01033a5d1d0b6fea8" }, "downloads": -1, "filename": "zope.app.module-3.4.0.tar.gz", "has_sig": false, "md5_digest": "c9e45fdcb5b958a9ed23c47e7c2d17ad", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 9070, "upload_time": "2007-10-25T16:01:33", "url": "https://files.pythonhosted.org/packages/8b/02/f2c132a551566d209c484e19f0a66eb62665e774a938cf519a8151fd987e/zope.app.module-3.4.0.tar.gz" } ], "3.5.0": [ { "comment_text": "", "digests": { "md5": "7abc72631ef055bb2e5c7906a891dc39", "sha256": "ef3c1ec5de3b2f86d8fc250e9b7b28faaed3482d699e27915eec68aac2dd944b" }, "downloads": -1, "filename": "zope.app.module-3.5.0.tar.gz", "has_sig": false, "md5_digest": "7abc72631ef055bb2e5c7906a891dc39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10143, "upload_time": "2009-02-01T16:32:06", "url": "https://files.pythonhosted.org/packages/1e/d2/270fcc50bd8922ffd62d569e4f804f5523929e97cc63f0f3a1769a9d7130/zope.app.module-3.5.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "7abc72631ef055bb2e5c7906a891dc39", "sha256": "ef3c1ec5de3b2f86d8fc250e9b7b28faaed3482d699e27915eec68aac2dd944b" }, "downloads": -1, "filename": "zope.app.module-3.5.0.tar.gz", "has_sig": false, "md5_digest": "7abc72631ef055bb2e5c7906a891dc39", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 10143, "upload_time": "2009-02-01T16:32:06", "url": "https://files.pythonhosted.org/packages/1e/d2/270fcc50bd8922ffd62d569e4f804f5523929e97cc63f0f3a1769a9d7130/zope.app.module-3.5.0.tar.gz" } ] }