{ "info": { "author": "Ross Patterson", "author_email": "me@rpatterson.net", "bugtrack_url": null, "classifiers": [ "Programming Language :: Python", "Topic :: Software Development :: Libraries :: Python Modules" ], "description": "=========================\ncollective.blueprint.base\n=========================\n\nProvides transmogrifier blueprint base classes and several useful\nblueprints.\n\n.. contents:: Table of Contents\n\n.. -*-doctest-*-\n\nBlueprint Base Classes\n======================\n\nThe collective.blueprint.base package provides base classes for\nclear and easy transmogrifier blueprints.\n\nChanging Keys\n-------------\n\nFor blueprints that add or change keys in items, it can be very useful\nto make the keys used by the blueprint configurable.\n\nThe getKeys functions translates the keys and values passed as keyword\narguments into a dictionary with keys as specified in the options if\npresent.\n\n >>> from collective.blueprint.base import keys\n >>> options = {'foo-key': 'baz'}\n >>> sorted(keys.getKeys(\n ... options, foo='bar', bah='qux').iteritems())\n [('bah', 'qux'), ('baz', 'bar')]\n\nA base class is provided for easily making readable blueprints that\nadd keys to items or change keys obeying any key names in the\noptions.\n\n >>> from collective.blueprint.base import blueprint\n >>> class FooBlueprint(blueprint.KeyChanger):\n ... keys = ('foo', 'bah')\n ... def processItem(self, item):\n ... return dict(foo='bar', bah='qux')\n\n >>> from collective.blueprint.base import testing\n >>> transmogrifier = testing.Transmogrifier()\n >>> previous = ({'other': 'stuff'},)\n >>> foo_blueprint = FooBlueprint(\n ... transmogrifier, 'foosection', options, previous)\n >>> item, = foo_blueprint\n >>> sorted(item.iteritems())\n [('bah', 'qux'), ('baz', 'bar'), ('other', 'stuff')]\n\nSource blueprints are by their very nature key changers. Intead of\nadding keys to items from further up the pipeline, they generate\nitems. The source base class extends the behavior above to this usage\npattern.\n\n >>> class BarBlueprint(blueprint.Source):\n ... keys = ('foo', 'bah')\n ... def getItems(self):\n ... yield dict(foo='bar', bah='qux')\n ... yield dict(foo='bar2', bah='qux2')\n\n >>> previous = ({'other': 'stuff'},)\n >>> bar_blueprint = BarBlueprint(\n ... transmogrifier, 'barsection', options, previous)\n >>> other, first, second = bar_blueprint\n >>> other\n {'other': 'stuff'}\n >>> sorted(first.iteritems())\n [('bah', 'qux'), ('baz', 'bar')]\n >>> sorted(second.iteritems())\n [('bah', 'qux2'), ('baz', 'bar2')]\n\nUsing Keys\n----------\n\nFor blueprints that access keys in items and process them somehow,\ntransmogrifier provides support for matchers that will access keys\non items according to a policy of precedence.\n\nThe makeMatchers function does this for multiple keys at once.\n\n >>> options = {'blueprint': 'foo.blueprint', 'bah-key': 'bar'}\n >>> matchers = keys.makeMatchers(\n ... options, 'barsection', 'baz', 'bah', blah=('qux', 'quux'))\n >>> sorted(matchers.iteritems())\n [('bah', ),\n ('baz', ),\n ('blah', )]\n \n >>> item = {'_baz': 'baz-value',\n ... 'bar': 'bah-value',\n ... 'quux': 'blah-value'}\n >>> matchers['baz'](*item)\n ('_baz', True)\n >>> matchers['bah'](*item)\n ('bar', True)\n >>> matchers['blah'](*item)\n ('quux', True)\n\nTo make implementing blueprints easier and clearer, a base class is\nprovided that allows the blueprint author to worry only about the keys\nin the item they require.\n\n >>> class BazKeyUser(blueprint.KeyUser):\n ... keys = ('baz', 'bah')\n ... extras = dict(blah=('qux', 'quux'))\n ... def processItem(self, item, baz, bah, blah):\n ... print baz, bah, blah\n\n >>> previous = (item,)\n >>> baz_blueprint = BazKeyUser(\n ... transmogrifier, 'bazsection', options, previous)\n >>> only, = baz_blueprint\n baz-value bah-value blah-value\n >>> sorted(only.iteritems())\n [('_baz', 'baz-value'),\n ('bar', 'bah-value'),\n ('quux', 'blah-value')]\n\nA KeyUser can pass over items that don't have keys for all the\nmatchers if the required option is not True.\n\n >>> class QuxKeyUser(blueprint.KeyUser):\n ... keys = ('baz', 'bah', 'foo')\n ... extras = dict(blah=('qux', 'quux'))\n ... def processItem(self, item, baz, bah, blah, foo):\n ... print baz, bah, blah\n\n >>> options['required'] = 'False'\n >>> previous = (item,)\n >>> qux_blueprint = QuxKeyUser(\n ... transmogrifier, 'quxsection', options, previous)\n >>> only, = qux_blueprint\n >>> sorted(only.iteritems())\n [('_baz', 'baz-value'),\n ('bar', 'bah-value'),\n ('quux', 'blah-value')]\n\n.. -*-doctest-*-\n\nDelete Blueprint\n================\n\nThe collective.blueprint.base.delete transmogrifier blueprint can be used\nto make pipleine sections that delete existing objects at the item\npath.\n\nSome objects exist before running the transmogrifier, others don't.\n\n >>> hasattr(folder, 'foo')\n True\n >>> folder.foo\n \n >>> hasattr(folder, 'bar')\n False\n\nAssemble and register a transmogrifier with a deleter section.\n\n >>> deleter = \"\"\"\n ... [transmogrifier]\n ... pipeline =\n ... foosource\n ... barsource\n ... deleter\n ... printer\n ... \n ... [foosource]\n ... blueprint = collective.blueprint.base.configsource\n ... _path = /foo\n ... \n ... [barsource]\n ... blueprint = collective.blueprint.base.configsource\n ... _path = /bar\n ... \n ... [deleter]\n ... blueprint = collective.blueprint.base.deleter\n ... \n ... [printer]\n ... blueprint = collective.transmogrifier.sections.tests.pprinter\n ... \"\"\"\n >>> registerConfig(\n ... u'collective.blueprint.base.delete.testing.deleter',\n ... deleter)\n\nRun the transmogrifier. The blueprint ignores items with paths that\ndon't point to existing objects.\n\n >>> from collective.transmogrifier import transmogrifier\n >>> transmogrifier.Transmogrifier(folder)(\n ... u'collective.blueprint.base.delete.testing.deleter')\n {'_path': '/foo'}\n {'_path': '/bar'}\n\nThe object has been deleted.\n\n >>> hasattr(folder, 'foo')\n False\n >>> hasattr(folder, 'bar')\n False\n\n.. -*-doctest-*-\n\nSection Configuration Source\n============================\n\nThe collective.blueprint.base.configsource transmogrifier blueprint can be used\nto inject an item into the pipeline with keys and values taken from\nthe section configuration.\n\nAssemble and register a transmogrifier with a deleter section.\n\n >>> configsource = \"\"\"\n ... [transmogrifier]\n ... pipeline =\n ... configsource\n ... printer\n ... \n ... [configsource]\n ... blueprint = collective.blueprint.base.configsource\n ... configsource-lists = baz qux\n ... foo =\n ... bar blah\n ... baz =\n ... bah\n ... qux =\n ... quux\n ... foo bar\n ... baz blah\n ... \n ... [printer]\n ... blueprint = collective.transmogrifier.sections.tests.pprinter\n ... \"\"\"\n >>> registerConfig(\n ... u'collective.blueprint.base.delete.testing.configsource',\n ... configsource)\n\nRun the transmogrifier. An item with contents corresponding the\nsection config is injected. All values are stripped of whitespace. A\nvariable whose name is listed in the configsource-lists variable will\nbe broken up on newlines into a list.\n\n >>> transmogrifier(\n ... u'collective.blueprint.base.delete.testing.configsource')\n {'qux': ['quux', 'foo bar', 'baz blah'],\n 'foo': 'bar blah',\n 'baz': ['bah']}\n\n.. -*-doctest-*-\n\nKey Splitter\n============\n\nThe collective.blueprint.base.keysplitter transmogrifier blueprint can\nbe used to insert an arbitrary number of items into the pipeline from\na key in the original item. This can be useful, for example, when an\narbitrary number of objects must be constricted (or any other pipeline\naction) based on a key in the upstream item.\n\nThe values to iterate over and insert new items will be retrieved from\n(in order)\n``_collective.blueprint.base.keysplitter_[sectionname]_keysplitter``,\n``_collective.blueprint.base.keysplitter_keysplitter``,\n``_[sectionname]_keysplitter``, and ``_keysplitter``, where\n``[sectionname]`` is replaced with the name given to the current\nsection. This allows you to target the right section precisely if\nneeded. Alternatively, you can specify what key to use for the\nkeysplitter by specifying the ``keysplitter-key`` option, which should\nbe a list of keys to try (one key per line, use a ``re:`` or\n``regexp:`` prefix to specify regular expressions).\n\nThe 'pipeline' option may be used to specify a list of sections which\nwill be run for new items only. The original items will not be put\nthrough this pipeline. Unless the 'include' option is set, the new\nitems will not be put through the rest of the originating pipeline.\n\nBy default the new items are inserted into the pipeline before the\noriginal item is yielded. This is useful when the results of\nprocessing the new items are required to finish processing the\noriginal item. For example, several objects may need to be created\nbased on the key values so that the object created for the original\nitem can set references to them. If, however, the original item must\nbe processed before the new items, then setting the \"after\" option in\nthe keysplitter section will cause the new items to be inserted after\nthe original item is yielded and processed.\n\nAssemble and register a transmogrifier with a key splitter section.\n\n >>> keysplitter = \"\"\"\n ... [transmogrifier]\n ... pipeline =\n ... initsource\n ... keysplitter\n ... qux\n ... printer\n ... \n ... [initsource]\n ... blueprint = collective.blueprint.base.configsource\n ... configsource-lists = _keysplitter\n ... _keysplitter =\n ... bar\n ... baz\n ... \n ... [keysplitter]\n ... blueprint = collective.blueprint.base.keysplitter\n ... pipeline =\n ... foo\n ... printer\n ... \n ... [foo]\n ... blueprint = collective.transmogrifier.sections.inserter\n ... key = string:foo\n ... value = item/_keysplitter\n ... \n ... [qux]\n ... blueprint = collective.transmogrifier.sections.inserter\n ... key = string:qux\n ... value = item/_keysplitter\n ... \n ... [printer]\n ... blueprint = collective.transmogrifier.sections.tests.pprinter\n ... \"\"\"\n >>> registerConfig(\n ... u'collective.blueprint.base.keysplitter.testing',\n ... keysplitter)\n\nRun the transmogrifier. An item with two values targeted for the\nkeysplitter section is inserted into the pipeline. When this item\nreaches the keysplitter section, the values in the '_keysplitter' key\nare iterated over to insert new items.\n\n >>> transmogrifier(\n ... u'collective.blueprint.base.keysplitter.testing')\n {'_keysplitter': 'bar', 'foo': 'bar'}\n {'_keysplitter': 'baz', 'foo': 'baz'}\n {'_keysplitter': ['bar', 'baz'], 'qux': ['bar', 'baz']}\n\nThis transmogrifier uses the after and include options and doesn't\ninclude a sub-pipeline.\n\n >>> keysplitter = \"\"\"\n ... [transmogrifier]\n ... pipeline =\n ... initsource\n ... keysplitter\n ... printer\n ... \n ... [initsource]\n ... blueprint = collective.blueprint.base.configsource\n ... configsource-lists = _keysplitter\n ... _keysplitter =\n ... bar\n ... baz\n ... \n ... [keysplitter]\n ... blueprint = collective.blueprint.base.keysplitter\n ... after = True\n ... include = True\n ... \n ... [printer]\n ... blueprint = collective.transmogrifier.sections.tests.pprinter\n ... \"\"\"\n >>> registerConfig(\n ... u'collective.blueprint.base.keysplitter.testing2',\n ... keysplitter)\n\n >>> transmogrifier(\n ... u'collective.blueprint.base.keysplitter.testing2')\n {'_keysplitter': ['bar', 'baz']}\n {'_keysplitter': 'bar'}\n {'_keysplitter': 'baz'}\n\n.. -*-doctest-*-\n\nRecursive Splitter\n==================\n\nThe collective.blueprint.base.recurser transmogrifier blueprint can be\nused to add recursion to a pipeline.\n\nThe values to recurse into will be retrieved from (in order)\n``_collective.blueprint.base.recurser_[sectionname]_recurser``,\n``_collective.blueprint.base.recurser_recurser``,\n``_[sectionname]_recurser``, and ``_recurser``, where\n``[sectionname]`` is replaced with the name given to the current\nsection. This allows you to target the right section precisely if\nneeded. Alternatively, you can specify what key to use for the\nrecurser by specifying the ``recurser-key`` option, which should\nbe a list of keys to try (one key per line, use a ``re:`` or\n``regexp:`` prefix to specify regular expressions).\n\nThe 'pipeline' option is used to specify a list of sections which will\nbe run recursively. By default, recursive items are inserted into the\npipeline after the original item is yielded. If, however, the\n'before' option is set, the recursive items will be inserted before\nthe original item is yielded and processed.\n\nWhen recursing into a value, the value will be inserted into the item\nunder the key specified in the 'key' option. The recursive pipeline\nis responsible for processing the 'key' value and inserting the\n'_recurser' key if it's a appropriate to recurse.\n\nAssemble and register a transmogrifier with a list splitter section.\n\n >>> recurser = \"\"\"\n ... [transmogrifier]\n ... pipeline =\n ... initsource\n ... inserter\n ... recurser\n ... printer\n ... \n ... [initsource]\n ... blueprint = collective.blueprint.base.configsource\n ... \n ... [inserter]\n ... blueprint = collective.transmogrifier.sections.inserter\n ... key = string:foo\n ... value = python:[['bar', 'baz'], ['qux', 'quux']]\n ... \n ... [recurser]\n ... blueprint = collective.blueprint.base.recurser\n ... key = foo\n ... pipeline = foo\n ... \n ... [foo]\n ... blueprint = collective.transmogrifier.sections.inserter\n ... condition = python:isinstance(item['foo'], list)\n ... key = string:_recurser\n ... value = item/foo\n ... \n ... [printer]\n ... blueprint = collective.transmogrifier.sections.tests.pprinter\n ... \"\"\"\n >>> registerConfig(\n ... u'collective.blueprint.base.recurser.testing',\n ... recurser)\n\nRun the transmogrifier.\n\n >>> transmogrifier(\n ... u'collective.blueprint.base.recurser.testing')\n {'_recurser': [['bar', 'baz'], ['qux', 'quux']],\n 'foo': [['bar', 'baz'], ['qux', 'quux']]}\n {'_recurser': ['bar', 'baz'], 'foo': ['bar', 'baz']}\n {'foo': 'bar'}\n {'foo': 'baz'}\n {'_recurser': ['qux', 'quux'], 'foo': ['qux', 'quux']}\n {'foo': 'qux'}\n {'foo': 'quux'}\n\nThis transmogrifier uses the before option.\n\n >>> recurser = \"\"\"\n ... [transmogrifier]\n ... pipeline =\n ... initsource\n ... inserter\n ... recurser\n ... printer\n ... \n ... [initsource]\n ... blueprint = collective.blueprint.base.configsource\n ... \n ... [inserter]\n ... blueprint = collective.transmogrifier.sections.inserter\n ... key = string:foo\n ... value = python:[['bar', 'baz'], ['qux', 'quux']]\n ... \n ... [recurser]\n ... blueprint = collective.blueprint.base.recurser\n ... key = foo\n ... pipeline = foo\n ... before = True\n ... \n ... [foo]\n ... blueprint = collective.transmogrifier.sections.inserter\n ... condition = python:isinstance(item['foo'], list)\n ... key = string:_recurser\n ... value = item/foo\n ... \n ... [printer]\n ... blueprint = collective.transmogrifier.sections.tests.pprinter\n ... \"\"\"\n >>> registerConfig(\n ... u'collective.blueprint.base.recurser.testing2',\n ... recurser)\n\n >>> transmogrifier(\n ... u'collective.blueprint.base.recurser.testing2')\n {'foo': 'bar'}\n {'foo': 'baz'}\n {'_recurser': ['bar', 'baz'], 'foo': ['bar', 'baz']}\n {'foo': 'qux'}\n {'foo': 'quux'}\n {'_recurser': ['qux', 'quux'], 'foo': ['qux', 'quux']}\n {'_recurser': [['bar', 'baz'], ['qux', 'quux']],\n 'foo': [['bar', 'baz'], ['qux', 'quux']]}\n\nChangelog\n=========\n\n1.0 - 2010-04-23\n----------------\n\n* Initial release", "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/collective.blueprint.base", "keywords": "", "license": "GPL", "maintainer": null, "maintainer_email": null, "name": "collective.blueprint.base", "package_url": "https://pypi.org/project/collective.blueprint.base/", "platform": "UNKNOWN", "project_url": "https://pypi.org/project/collective.blueprint.base/", "project_urls": { "Download": "UNKNOWN", "Homepage": "http://pypi.python.org/pypi/collective.blueprint.base" }, "release_url": "https://pypi.org/project/collective.blueprint.base/1.0/", "requires_dist": null, "requires_python": null, "summary": "Some core transmogrifier blueprints and base classes", "version": "1.0" }, "last_serial": 640840, "releases": { "1.0": [ { "comment_text": "", "digests": { "md5": "2f1310b8d13eff3fc4b6e7cadad506dc", "sha256": "d76e6389318ab885d9046da491b08f0973a22c9f970c23618abdfaf3f7d550f0" }, "downloads": -1, "filename": "collective.blueprint.base-1.0.tar.gz", "has_sig": false, "md5_digest": "2f1310b8d13eff3fc4b6e7cadad506dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13167, "upload_time": "2010-04-23T11:12:14", "url": "https://files.pythonhosted.org/packages/cb/f8/7836c0dc76888da44117ce42bcc01d670890cbd65c27860183b50791e8f5/collective.blueprint.base-1.0.tar.gz" } ] }, "urls": [ { "comment_text": "", "digests": { "md5": "2f1310b8d13eff3fc4b6e7cadad506dc", "sha256": "d76e6389318ab885d9046da491b08f0973a22c9f970c23618abdfaf3f7d550f0" }, "downloads": -1, "filename": "collective.blueprint.base-1.0.tar.gz", "has_sig": false, "md5_digest": "2f1310b8d13eff3fc4b6e7cadad506dc", "packagetype": "sdist", "python_version": "source", "requires_python": null, "size": 13167, "upload_time": "2010-04-23T11:12:14", "url": "https://files.pythonhosted.org/packages/cb/f8/7836c0dc76888da44117ce42bcc01d670890cbd65c27860183b50791e8f5/collective.blueprint.base-1.0.tar.gz" } ] }