grokcore.component-2.5/ 0000775 0001750 0001750 00000000000 11750014424 014256 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/buildout.cfg 0000664 0001750 0001750 00000000711 11750014416 016566 0 ustar jw jw 0000000 0000000 [buildout]
develop = .
parts = interpreter test
extends = http://svn.zope.org/repos/main/groktoolkit/trunk/grok.cfg
versions = versions
extensions = buildout.dumppickedversions
[versions]
grokcore.component =
[interpreter]
recipe = zc.recipe.egg
eggs = grokcore.component
interpreter = python
[test]
recipe = zc.recipe.testrunner
eggs = grokcore.component
grokcore.component[test]
defaults = ['--tests-pattern', '^f?tests$', '-v', '--auto-color']
grokcore.component-2.5/PKG-INFO 0000664 0001750 0001750 00000046017 11750014424 015363 0 ustar jw jw 0000000 0000000 Metadata-Version: 1.0
Name: grokcore.component
Version: 2.5
Summary: Grok-like configuration for basic components (adapters, utilities, subscribers)
Home-page: http://grok.zope.org
Author: Grok Team
Author-email: grok-dev@zope.org
License: ZPL
Download-URL: http://pypi.python.org/pypi/grokcore.component
Description: This package provides base classes of basic component types for the
Zope Component Architecture, as well as means for configuring and
registering them directly in Python (without ZCML).
.. contents::
How to set up ``grokcore.component``
====================================
In the following we assume you're writing or extending an application
that does bootstrap configuration using ZCML. There's always a single
ZCML file that is executed when the application is started, which then
includes everything else. Let's assume this file is called
``site.zcml`` (that's what it's called in Zope), so that file is what
we'll be editing.
In order to register the components that you wrote using the base
classes and directives available from ``grokcore.component``, we'll
use the ```` ZCML directive. But before we can use it,
we need to make sure it's available to the ZCML machinery. We do this
by including the meta configuration from ``grokcore.component``::
Put this line somewhere to the top of ``site.zcml``, next to other
meta configuration includes. Now, further down the line, we can tell
the machinery in ``grokcore.component`` to register all components in
your package (let's say it's called ``helloworld``)::
To sum up, your ``site.zcml`` file should look like something like this::
Examples
========
Adapter
-------
Here's a simple adapter that may be useful in Zope. It extracts the
languages that a user prefers from the request::
import grokcore.component
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.i18n.interfaces import IUserPreferredLanguages
class CookieLanguage(grokcore.component.Adapter):
"""Extract the preferred language from a cookie"""
grokcore.component.context(IBrowserRequest)
grokcore.component.implements(IUserPreferredLanguages)
# No need to implement __init__, it's already provided by the base class.
def getPreferredLanguages(self):
# This an adapter for the request, so self.context is the request.
request = self.context
# Extract the preferred language from a cookie:
lang = request.cookies.get('language', 'en')
# According to IUserPreferredLanguages, we must return a list.
return [lang]
Multi-adapter
-------------
Here's a multi-adapter that functions as a content provider as known
from the ``zope.contentprovider`` library. Content providers are
components that return snippets of HTML. They're multi-adapters for
the content object (model), the request and the view that they're
supposed to be a part of::
import grokcore.component
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IBrowserPage
from zope.contentprovider.interfaces import IContentProvider
class HelloWorldProvider(grokcore.component.MultiAdapter):
"""Display Hello World!"""
grokcore.component.adapts(Interface, IBrowserRequest, IBrowserPage)
grokcore.component.implements(IContentProvider)
def __init__(self, context, request, view):
pass
def update(self):
pass
def render(self):
return u'
Hello World!
'
Global utility
--------------
Here's a simple named utility, again from the Zope world. It's a
translation domain. In other words, it contains translations of user
messages and is invoked when the i18n machinery needs to translate
something::
import grokcore.component
from zope.i18n.interfaces import ITranslationDomain
class HelloWorldTranslationDomain(grokcore.component.GlobalUtility):
grokcore.component.implements(ITranslationDomain)
grokcore.component.name('helloworld')
domain = u'helloworld'
def translate(self, msgid, mapping=None, context=None,
target_language=None, default=None):
if target_language is None:
preferred = IUserPreferredLanguages(context)
target_language = preferred.getPreferredLanguages()[0]
translations = {'de': u'Hallo Welt',
'nl': u'Hallo Wereld'}
return translations.get(target_language, u'Hello World')
Of course, it's silly to implement your own translation domain utility
if there are already implementations available in ``zope.i18n`` (one
that reads translations from a GNU gettext message catalog and a
simple implementation for tests). Let's try to reuse that
implementation and register an instance::
import grokcore.component
from zope.i18n.interfaces import ITranslationDomain
from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
messages = {('de', u'Hello World'): u'Hallo Welt',
('nl', u'Hello World'): u'Hallo Wereld'}
helloworld_domain = SimpleTranslationDomain(u'helloworld', messages)
grokcore.component.global_utility(helloworld_domain,
provides=ITranslationDomain,
name='helloworld',
direct=True)
Global adapter
--------------
Sometimes, you may have an object that should be registered as an adapter
factory. It may have come from some other framework that configured that
adapter for you, say, or you may have a class that you instantiate many
times to get different variations on a particular adapter factory. In these
cases, subclassing grokcore.component.Adapter or MultiAdapter is not
possible. Instead, you can use the global_adapter() directive. Here is an
example drawing on the ``z3c.form`` library, which provides an adapter factory
factory for named widget attributes::
import zope.interface
import zope.schema
import grokcore.component
import z3c.form.widget import ComputedWidgetAttribute
class ISchema(Interface):
"""This schema will be used to power a z3c.form form"""
field = zope.schema.TextLine(title=u"Sample field")
...
label_override = z3c.form.widget.StaticWidgetAttribute(
u"Override label", field=ISchema['field'])
grokcore.component.global_adapter(label_override, name=u"label")
In the example above, the provided and adapted interfaces are deduced from the
object returned by the ``StaticWidgetAttribute`` factory. The full syntax
for global_adapter is::
global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
The factory must be a callable (the adapter factory). Adapted interfaces are
given as a tuple. You may use a single interface instead of a one-element
tuple for single adapters. The provided interface is given as shown. The name
defaults to u"" (an unnamed adapter).
Handling events
---------------
Here we see an event handler much like it occurs within Zope itself. It
subscribes to the modified event for all annotatable objects (in other words,
objects that can have metadata associated with them). When invoked, it updates
the Dublin Core 'Modified' property accordingly::
import datetime
import grokcore.component
from zope.annotation.interfaces import IAnnotatable
from zope.lifecycleevent.interfaces import IObjectModifiedEvent
from zope.dublincore.interfaces import IZopeDublinCore
@grokcore.component.subscribe(IAnnotatable, IObjectModifiedEvent)
def updateDublinCoreAfterModification(obj, event):
"""Updated the Dublin Core 'Modified' property when a modified
event is sent for an object."""
IZopeDublinCore(obj).modified = datetime.datetime.utcnow()
Subscriptions
-------------
Subscriptions look similar to Adapter, however, unlike regular adapters,
subscription adapters are used when we want all of the adapters that adapt an
object to a particular adapter.
Analogous to MultiAdapter, there is a MultiSubscription component that "adapts"
multiple objects.
Changes
=======
2.5 (2012-05-01)
----------------
- Introduce provideUtility, providerAdapter, provideSubscriptionAdapter,
provideHandler and provideInterface in grokcore.component. These by default
delegate the registration of components to the global site manager like
was done before, but provide the possibility for custom registries for the
grokked components.
- Fix the `global_adapter` to properly use information annotated by
``grok.adapter``, and using the IContext object if it was not
specified. (Fix Launchpad issue #960097).
- Add a ``key`` option to ``sort_components`` that behave like ``key``
options available on standard Python sort methods.
2.4 (2011-04-27)
----------------
- Fix the `global_adapter` directive implementation to accept an explicit
"empty" name for nameless adapter registrations (as it used to be that
providing an empty name in the registration would actually result in
registering a named adapter in case the factory has a `grok.name`).
2.3 (2011-02-14)
----------------
- Implement the generic (Multi)Subscriptions components.
2.2 (2010-11-03)
----------------
- The default values computation for the context directive and the provides
directive is now defined in the directives themselves. This means that where
the values for these directives is being retrieved, the "default_context"
function does not need to be passed along anymore for general cases.
Analogous to this, when getting values for the provides directive the
"default_provides" function does not need to be passed along in the general
case.
2.1 (2010-11-01)
----------------
* Made package comply to zope.org repository policy.
* Moved directives 'order' from grokcore.viewlet and 'path' from
grokcore.view to this very package.
* Tiny dependency adjustment: moved zope.event to test dependencies.
* Port from 1.x branch exclude parameter to the Grok ZCML directive.
* Port from 1.x branch the ignore of testing.py modules.
2.0 (2009-09-16)
----------------
* Use a newer version of Martian that has better support for
inheritance. This is demonstrated in ``tests/inherit``.
* The ``ContextGrokker`` and the ``scan.py`` module have gone away
thanks the newer Martian.
* Directive implementations (in their factory method) should *not*
bind directives. Directive binding cannot take place at import time,
but only at grok time. Binding directives during import time (when
directives are executed) can lead to change problems. (we noticed
this during our refactoring to use the new Martian).
* Use 1.0b1 versions.cfg in Grok's release info instead of a local
copy; a local copy for all grokcore packages is just too hard to
maintain.
1.7 (2009-06-01)
----------------
* Add missing provider, global_adapter, implementsOnly, classProvides() to
the module interface so that they are included in __all__
1.6 (2009-04-10)
----------------
* Add convenience imports for implementsOnly() and classProvides() class
declarations form zope.interface.
* Add support for registering global adapters at module level::
grok.global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
Only 'factory' is required. If only a single interface is adapted, the
second argument may be a single interface instead of a tuple. If the
component has declared adapted/provided interfaces, the second and third
arguments may be omitted.
* Add support for an @provider decorator to let a function directly provide
an interface::
@grok.provider(IFoo, IBar)
def some_function():
...
This is equivalent to doing alsoProvides(some_function, IFoo, IBar).
* Add support for named adapters with the @adapter decorator::
@grok.adapter(IAdaptedOne, IAdaptedTwo, name=u"foo")
def some_function(one, two):
...
1.5.1 (2008-07-28)
------------------
* The ``IGrokcoreComponentAPI`` interface was missing declarations for
the ``title`` and ``description`` directives.
1.5 (2008-07-22)
----------------
* Fix https://bugs.launchpad.net/grok/+bug/242353: grokcore.component
contains old-style test setup. There is no `register_all_tests`
method in grokcore.component.testing anymore. Use z3c.testsetup
instead.
* Allow functions that have been marked with @grok.subscribe also be
registered with ``zope.component.provideHandler()`` manually. This
is useful for unit tests where you may not want to grok a whole
module.
* Document grokcore.component's public API in an interface,
``IGrokcoreComponentAPI``. When you now do::
from grokcore.component import *
only the items documented in that interface will be imported into
your local namespace.
1.4 (2008-06-11)
----------------
* Ported class grokkers to make use of further improvements in Martian.
This requires Martian 0.10.
1.3 (2008-05-14)
----------------
* Ported class grokkers to make use of the new declarative way of
retrieving directive information from a class. This requires
Martian 0.9.6.
1.2.1 (2008-05-04)
------------------
* Upgrade to Martian 0.9.5, which has a slight change in the signature of
``scan_for_classes``.
* Remove an unnecessary import ``methods_from_class`` from
``grokcore.component.scan``.
1.2 (2008-05-04)
----------------
* Ported directives to Martian's new directive implementation. As a
result, nearly all helper functions that were available from
``grokcore.component.util`` have been removed. The functionality is
mostly available from the directives themselves now.
* The ``baseclass`` directive has been moved to Martian.
* The ``order`` directive and its helper functions have been moved
back to Grok, as it was of no general use, but very specific to
viewlets.
1.1 (2008-05-03)
----------------
* ``determine_module_component`` now looks for classes that implement
a certain interface (such as ``IContext``), instead of taking a list
of classes. If looking for ``IContext``, it still will find
``Context`` subclasses, as these were also made to implement
``IContext``.
* Move the ``public_methods_from_class`` helper function back to Grok,
it isn't used at all in ``grokcore.component``.
1.0.1 (2008-05-02)
------------------
* The grokkers for adapters and global utilities did not use the
correct value for the *provided* interface in the configuration
action discriminator. Because of this, uninformative and
potentially wrong conflict errors would occur, as well as no
conflict where a conflict should have occurred.
* The grokker for the ``global_utility()`` directive did immediate
registrations instead of generating configuration actions.
Therefore it did not provoke ``ConflictErrors`` for conflicting
registrations.
* Improved documentation
1.0 (2008-05-01)
----------------
* Created ``grokcore.component`` in March 2008 by factoring basic
component base classes and their directives and grokkers out of
Grok.
Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
grokcore.component-2.5/setup.py 0000664 0001750 0001750 00000002636 11750014416 016000 0 ustar jw jw 0000000 0000000 from setuptools import setup, find_packages
import os
def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
long_description = (
read('README.txt')
+ '\n' +
read('CHANGES.txt')
)
tests_require = [
'zope.event',
]
setup(
name='grokcore.component',
version='2.5',
author='Grok Team',
author_email='grok-dev@zope.org',
url='http://grok.zope.org',
download_url='http://pypi.python.org/pypi/grokcore.component',
description='Grok-like configuration for basic components '
'(adapters, utilities, subscribers)',
long_description=long_description,
license='ZPL',
classifiers=['Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
],
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['grokcore'],
include_package_data=True,
zip_safe=False,
install_requires=['setuptools',
'martian >= 0.14',
'zope.component',
'zope.configuration',
'zope.interface',
# Note: zope.testing is NOT just a test dependency here.
'zope.testing',
],
tests_require=tests_require,
extras_require={'test': tests_require},
)
grokcore.component-2.5/bootstrap.py 0000664 0001750 0001750 00000023366 11750014416 016660 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Bootstrap a buildout-based project
Simply run this script in a directory containing a buildout.cfg.
The script accepts buildout command-line options, so you can
use the -c option to specify an alternate configuration file.
"""
import os, shutil, sys, tempfile, textwrap, urllib, urllib2, subprocess
from optparse import OptionParser
if sys.platform == 'win32':
def quote(c):
if ' ' in c:
return '"%s"' % c # work around spawn lamosity on windows
else:
return c
else:
quote = str
# See zc.buildout.easy_install._has_broken_dash_S for motivation and comments.
stdout, stderr = subprocess.Popen(
[sys.executable, '-Sc',
'try:\n'
' import ConfigParser\n'
'except ImportError:\n'
' print 1\n'
'else:\n'
' print 0\n'],
stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
has_broken_dash_S = bool(int(stdout.strip()))
# In order to be more robust in the face of system Pythons, we want to
# run without site-packages loaded. This is somewhat tricky, in
# particular because Python 2.6's distutils imports site, so starting
# with the -S flag is not sufficient. However, we'll start with that:
if not has_broken_dash_S and 'site' in sys.modules:
# We will restart with python -S.
args = sys.argv[:]
args[0:0] = [sys.executable, '-S']
args = map(quote, args)
os.execv(sys.executable, args)
# Now we are running with -S. We'll get the clean sys.path, import site
# because distutils will do it later, and then reset the path and clean
# out any namespace packages from site-packages that might have been
# loaded by .pth files.
clean_path = sys.path[:]
import site
sys.path[:] = clean_path
for k, v in sys.modules.items():
if (hasattr(v, '__path__') and
len(v.__path__)==1 and
not os.path.exists(os.path.join(v.__path__[0],'__init__.py'))):
# This is a namespace package. Remove it.
sys.modules.pop(k)
is_jython = sys.platform.startswith('java')
setuptools_source = 'http://peak.telecommunity.com/dist/ez_setup.py'
distribute_source = 'http://python-distribute.org/distribute_setup.py'
# parsing arguments
def normalize_to_url(option, opt_str, value, parser):
if value:
if '://' not in value: # It doesn't smell like a URL.
value = 'file://%s' % (
urllib.pathname2url(
os.path.abspath(os.path.expanduser(value))),)
if opt_str == '--download-base' and not value.endswith('/'):
# Download base needs a trailing slash to make the world happy.
value += '/'
else:
value = None
name = opt_str[2:].replace('-', '_')
setattr(parser.values, name, value)
usage = '''\
[DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
Bootstraps a buildout-based project.
Simply run this script in a directory containing a buildout.cfg, using the
Python that you want bin/buildout to use.
Note that by using --setup-source and --download-base to point to
local resources, you can keep this script from going over the network.
'''
parser = OptionParser(usage=usage)
parser.add_option("-v", "--version", dest="version",
help="use a specific zc.buildout version")
parser.add_option("-d", "--distribute",
action="store_true", dest="use_distribute", default=False,
help="Use Distribute rather than Setuptools.")
parser.add_option("--setup-source", action="callback", dest="setup_source",
callback=normalize_to_url, nargs=1, type="string",
help=("Specify a URL or file location for the setup file. "
"If you use Setuptools, this will default to " +
setuptools_source + "; if you use Distribute, this "
"will default to " + distribute_source +"."))
parser.add_option("--download-base", action="callback", dest="download_base",
callback=normalize_to_url, nargs=1, type="string",
help=("Specify a URL or directory for downloading "
"zc.buildout and either Setuptools or Distribute. "
"Defaults to PyPI."))
parser.add_option("--eggs",
help=("Specify a directory for storing eggs. Defaults to "
"a temporary directory that is deleted when the "
"bootstrap script completes."))
parser.add_option("-t", "--accept-buildout-test-releases",
dest='accept_buildout_test_releases',
action="store_true", default=False,
help=("Normally, if you do not specify a --version, the "
"bootstrap script and buildout gets the newest "
"*final* versions of zc.buildout and its recipes and "
"extensions for you. If you use this flag, "
"bootstrap and buildout will get the newest releases "
"even if they are alphas or betas."))
parser.add_option("-c", None, action="store", dest="config_file",
help=("Specify the path to the buildout configuration "
"file to be used."))
options, args = parser.parse_args()
# if -c was provided, we push it back into args for buildout's main function
if options.config_file is not None:
args += ['-c', options.config_file]
if options.eggs:
eggs_dir = os.path.abspath(os.path.expanduser(options.eggs))
else:
eggs_dir = tempfile.mkdtemp()
if options.setup_source is None:
if options.use_distribute:
options.setup_source = distribute_source
else:
options.setup_source = setuptools_source
if options.accept_buildout_test_releases:
args.append('buildout:accept-buildout-test-releases=true')
args.append('bootstrap')
try:
import pkg_resources
import setuptools # A flag. Sometimes pkg_resources is installed alone.
if not hasattr(pkg_resources, '_distribute'):
raise ImportError
except ImportError:
ez_code = urllib2.urlopen(
options.setup_source).read().replace('\r\n', '\n')
ez = {}
exec ez_code in ez
setup_args = dict(to_dir=eggs_dir, download_delay=0)
if options.download_base:
setup_args['download_base'] = options.download_base
if options.use_distribute:
setup_args['no_fake'] = True
ez['use_setuptools'](**setup_args)
reload(sys.modules['pkg_resources'])
import pkg_resources
# This does not (always?) update the default working set. We will
# do it.
for path in sys.path:
if path not in pkg_resources.working_set.entries:
pkg_resources.working_set.add_entry(path)
cmd = [quote(sys.executable),
'-c',
quote('from setuptools.command.easy_install import main; main()'),
'-mqNxd',
quote(eggs_dir)]
if not has_broken_dash_S:
cmd.insert(1, '-S')
find_links = options.download_base
if not find_links:
find_links = os.environ.get('bootstrap-testing-find-links')
if find_links:
cmd.extend(['-f', quote(find_links)])
if options.use_distribute:
setup_requirement = 'distribute'
else:
setup_requirement = 'setuptools'
ws = pkg_resources.working_set
setup_requirement_path = ws.find(
pkg_resources.Requirement.parse(setup_requirement)).location
env = dict(
os.environ,
PYTHONPATH=setup_requirement_path)
requirement = 'zc.buildout'
version = options.version
if version is None and not options.accept_buildout_test_releases:
# Figure out the most recent final version of zc.buildout.
import setuptools.package_index
_final_parts = '*final-', '*final'
def _final_version(parsed_version):
for part in parsed_version:
if (part[:1] == '*') and (part not in _final_parts):
return False
return True
index = setuptools.package_index.PackageIndex(
search_path=[setup_requirement_path])
if find_links:
index.add_find_links((find_links,))
req = pkg_resources.Requirement.parse(requirement)
if index.obtain(req) is not None:
best = []
bestv = None
for dist in index[req.project_name]:
distv = dist.parsed_version
if _final_version(distv):
if bestv is None or distv > bestv:
best = [dist]
bestv = distv
elif distv == bestv:
best.append(dist)
if best:
best.sort()
version = best[-1].version
if version:
requirement = '=='.join((requirement, version))
cmd.append(requirement)
if is_jython:
import subprocess
exitcode = subprocess.Popen(cmd, env=env).wait()
else: # Windows prefers this, apparently; otherwise we would prefer subprocess
exitcode = os.spawnle(*([os.P_WAIT, sys.executable] + cmd + [env]))
if exitcode != 0:
sys.stdout.flush()
sys.stderr.flush()
print ("An error occurred when trying to install zc.buildout. "
"Look above this message for any errors that "
"were output by easy_install.")
sys.exit(exitcode)
ws.add_entry(eggs_dir)
ws.require(requirement)
import zc.buildout.buildout
zc.buildout.buildout.main(args)
if not options.eggs: # clean up temporary egg directory
shutil.rmtree(eggs_dir)
grokcore.component-2.5/src/ 0000775 0001750 0001750 00000000000 11750014424 015045 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/ 0000775 0001750 0001750 00000000000 11750014424 016660 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/ 0000775 0001750 0001750 00000000000 11750014424 020662 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/components.py 0000664 0001750 0001750 00000010036 11750014416 023422 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok components"""
from zope.interface import implements
from grokcore.component.interfaces import IContext
class Adapter(object):
"""Base class for an adapter that adapts a single object (commonly referred
to as the *context*).
Use the ``context`` directive to specify which object to adapt and the
``implements`` directive to specify which interface the adapter will
provide. If it's a named adapter, you may use the ``name`` directive to
specify the name.
.. attribute:: context
The adapted object.
"""
def __init__(self, context):
self.context = context
class MultiAdapter(object):
"""Base class for an adapter that adapts *n* objects (where *n>=1*).
Use the ``adapts`` directive to specify which kinds of objects are adapted
and the ``implements`` directive to specify which interface the adapter
will provide. If it's a named multi-adapter, you may use the ``name``
directive to specify the name.
Note that contrary to the Adapter, the MultiAdapter base class does not
provide an `__init__` method. An `__init__` needs to accept the same number
of arguments as are used in the `adapts` directive.
"""
pass
class GlobalUtility(object):
"""Base class to define a globally registered utility.
Base class for a globally registered utility. Unless you use the ``direct``
directive to indicate that the class itself should be registered as a
utility, the class will automatically be instantiated, therefore the
constructor may not take any arguments. Use the ``implements`` directive to
specify which interface the utility provides, or if that is not
unambiguous, also use the ``provides`` directive to specify which of the
implemented interfaces should be used when registering the utility. If it's
a named utility, you may use the ``name`` directive to specify the name.
"""
pass
class Subscription(object):
"""Base class for a subscription adapter.
Subscriptions are similar to adapters, except that it is possible to
register multiple unnamed subscriptions for identical ``context`` and
``provides``.
Use the ``context`` directive to explicitly set the interface to adapt
from. When omitted the current context is assumed. Use the ``implements``
directive to specify which interface the subscription provides, or if that
is not unambiguous, also use the ``provides`` directive to specify which of
the implemented interfaces should be used when registering the subscription.
"""
def __init__(self, context):
self.context = context
class MultiSubscription(object):
"""Base class for a subscription multi-adapter.
MultiSubscriptions are similar to multi adapters, except that it is
possible to register multiple unnamed subscriptions for identical
``adapts`` and ``provides``.
Use the ``adapts`` directive to explicitly set the multiple interfaces to
adapt from. Use the ``implements`` directive to specify which interface the
subscription provides, or if that is not unambiguous, also use the
``provides`` directive to specify which of the implemented interfaces
should be used when registering the multi subscription.
"""
class Context(object):
"""Subclasses of this will automatically be found as potential contexts for
adapters and other types of context-dependent components.
"""
implements(IContext)
grokcore.component-2.5/src/grokcore/component/__init__.py 0000664 0001750 0001750 00000004110 11750014416 022770 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok
"""
from zope.component import adapts
adapts.__doc__ = "Declares the types of objects that a multi-adapter adapts."
from zope.interface import implements, implementsOnly, classProvides
from martian import baseclass
from martian.error import GrokError, GrokImportError
from martian import ClassGrokker, InstanceGrokker, GlobalGrokker
from grokcore.component.components import (
Adapter,
Context,
GlobalUtility,
MultiAdapter,
MultiSubscription,
Subscription,
)
from grokcore.component.directive import (
context,
description,
direct,
global_adapter,
global_utility,
name,
order,
path,
provides,
title,
)
from grokcore.component.decorators import (
adapter,
implementer,
provider,
subscribe,
)
from grokcore.component.subscription import (
queryMultiSubscriptions,
queryOrderedMultiSubscriptions,
queryOrderedSubscriptions,
querySubscriptions,
)
from grokcore.component.util import (
getSiteManager,
provideAdapter,
provideHandler,
provideInterface,
provideSubscriptionAdapter,
provideUtility,
sort_components,
)
# Import this module so that it's available as soon as you import the
# 'grokcore.component' package. Useful for tests and interpreter examples.
import grokcore.component.testing
# Only export public API
from grokcore.component.interfaces import IGrokcoreComponentAPI
__all__ = list(IGrokcoreComponentAPI)
grokcore.component-2.5/src/grokcore/component/testing.py 0000664 0001750 0001750 00000003424 11750014416 022715 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok test helpers
"""
import grokcore.component
from zope.configuration.config import ConfigurationMachine
from martian import scan
from grokcore.component import zcml
def grok(module_name):
config = ConfigurationMachine()
zcml.do_grok('grokcore.component.meta', config)
zcml.do_grok(module_name, config)
config.execute_actions()
def grok_component(name, component,
context=None, module_info=None, templates=None):
if module_info is None:
obj_module = getattr(component, '__grok_module__', None)
if obj_module is None:
obj_module = getattr(component, '__module__', None)
module_info = scan.module_info_from_dotted_name(obj_module)
module = module_info.getModule()
if context is not None:
grokcore.component.context.set(module, context)
if templates is not None:
module.__grok_templates__ = templates
config = ConfigurationMachine()
result = zcml.the_multi_grokker.grok(name, component,
module_info=module_info,
config=config)
config.execute_actions()
return result
grokcore.component-2.5/src/grokcore/component/meta.zcml 0000664 0001750 0001750 00000000673 11750014416 022506 0 ustar jw jw 0000000 0000000
grokcore.component-2.5/src/grokcore/component/util.py 0000664 0001750 0001750 00000010733 11750014416 022216 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok utility functions.
"""
import types
import zope.component.hooks
from zope.interface.interfaces import IInterface
from zope.interface import alsoProvides
from grokcore.component import directive
def _sort_key(component):
# If components have a grok.order directive, sort by that.
explicit_order, implicit_order = directive.order.bind().get(component)
return (explicit_order,
component.__module__,
implicit_order,
component.__class__.__name__)
def sort_components(components, key=None):
"""Sort a list of components using the information provided by
`grok.order`.
"""
sort_key = _sort_key
if key is not None:
sort_key = lambda item: _sort_key(key(item))
return sorted(components, key=sort_key)
def getSiteManager():
site = zope.component.hooks.getSite()
if site is None:
sm = zope.component.getGlobalSiteManager()
else:
sm = site.getSiteManager()
return sm
def provideUtility(component, provides=None, name=u''):
sm = getSiteManager()
sm.registerUtility(component, provides, name, event=False)
def provideAdapter(factory, adapts=None, provides=None, name=''):
sm = getSiteManager()
sm.registerAdapter(factory, adapts, provides, name, event=False)
def provideSubscriptionAdapter(factory, adapts=None, provides=None):
sm = getSiteManager()
sm.registerSubscriptionAdapter(factory, adapts, provides, event=False)
def provideHandler(factory, adapts=None):
sm = getSiteManager()
sm.registerHandler(factory, adapts, event=False)
def provideInterface(id, interface, iface_type=None, info=''):
"""register Interface with global site manager as utility
>>> gsm = zope.component.getGlobalSiteManager()
>>> from zope.interface import Interface
>>> from zope.interface.interfaces import IInterface
>>> from zope.component.tests import ITestType
>>> class I(Interface):
... pass
>>> IInterface.providedBy(I)
True
>>> ITestType.providedBy(I)
False
>>> interfaces = gsm.getUtilitiesFor(ITestType)
>>> list(interfaces)
[]
# provide first interface type
>>> provideInterface('', I, ITestType)
>>> ITestType.providedBy(I)
True
>>> interfaces = list(gsm.getUtilitiesFor(ITestType))
>>> [name for (name, iface) in interfaces]
[u'zope.component.interface.I']
>>> [iface.__name__ for (name, iface) in interfaces]
['I']
# provide second interface type
>>> class IOtherType(IInterface):
... pass
>>> provideInterface('', I, IOtherType)
>>> ITestType.providedBy(I)
True
>>> IOtherType.providedBy(I)
True
>>> interfaces = list(gsm.getUtilitiesFor(ITestType))
>>> [name for (name, iface) in interfaces]
[u'zope.component.interface.I']
>>> interfaces = list(gsm.getUtilitiesFor(IOtherType))
>>> [name for (name, iface) in interfaces]
[u'zope.component.interface.I']
>>> class I1(Interface):
... pass
>>> provideInterface('', I1)
>>> IInterface.providedBy(I1)
True
>>> ITestType.providedBy(I1)
False
>>> interfaces = list(gsm.getUtilitiesFor(ITestType))
>>> [name for (name, iface) in interfaces]
[u'zope.component.interface.I']
>>> [iface.__name__ for (name, iface) in interfaces]
['I']
"""
if not id:
id = "%s.%s" % (interface.__module__, interface.__name__)
if not IInterface.providedBy(interface):
if not isinstance(interface, (type, types.ClassType)):
raise TypeError(id, "is not an interface or class")
return
if iface_type is not None:
if not iface_type.extends(IInterface):
raise TypeError(iface_type, "is not an interface type")
alsoProvides(interface, iface_type)
else:
iface_type = IInterface
sm = getSiteManager()
sm.registerUtility(interface, iface_type, id, info)
grokcore.component-2.5/src/grokcore/component/interfaces.py 0000664 0001750 0001750 00000017711 11750014416 023367 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2008 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Public interfaces.
"""
from zope.interface import Interface, Attribute
class IContext(Interface):
"""Marker interface for auto-association of context.
The ``grok.context()`` directive is used to associate adapters with the
class or interface they adapt. If there is only a single possible context
object to adapt to in a module, you can leave out this directive and
let the adapter associate automatically.
If you want to make an object to be a candidate for this automatic
association, you can subclass from ``grokcore.component.Context``.
This implements this ``IContext`` directive.
In some cases, you don't want to mix in a base class. You can instead
mark up your class with ``zope.interface.implements(IContext)`` to make
it a candidate for auto-association.
"""
class IBaseClasses(Interface):
Adapter = Attribute("Base class for adapters.")
ClassGrokker = Attribute("Base class to define a class grokker.")
Context = Attribute("Base class for automatically associated contexts.")
GlobalGrokker = Attribute("Base class to define a module grokker.")
GlobalUtility = Attribute("Base class for global utilities.")
InstanceGrokker = Attribute("Base class to define an instance grokker.")
MultiAdapter = Attribute("Base class for multi-adapters.")
MultiSubscription = Attribute(
"Base class for subscription mult-adapters.")
Subscription = Attribute("Base class for subscription adapters.")
class IDirectives(Interface):
def baseclass():
"""Mark this class as a base class.
This means it won't be grokked, though if it's a possible context,
it can still serve as a context.
"""
def implements(*interfaces):
"""Declare that a class implements the given interfaces."""
def implementsOnly(*interfaces):
"""Declare that a class implements only the given interfaces.
Interfaces implemented by base classes are explicitly not inherited.
"""
def classProvides(*interfaces):
"""Declare that a class (as opposed to instances of the class)
directly provides the given interfaces.
"""
def adapts(*classes_or_interfaces):
"""Declare that a class adapts objects of the given classes or
interfaces."""
def context(class_or_interface):
"""Declare the context for views, adapters, etc.
This directive can be used on module and class level. When
used on module level, it will set the context for all views,
adapters, etc. in that module. When used on class level, it
will set the context for that particular class."""
def name(name):
"""Declare the name of a view or adapter/multi-adapter.
This directive can only be used on class level."""
def title(title):
"""Set a human-readable title for a component (e.g. a
permission, menu item, etc.).
This directive expects pure ASCII strings or Unicode and can
only be used on a class level."""
def description(description):
"""Set a human-readable description for a component (e.g. a
permission, menu item, etc.).
This directive expects pure ASCII strings or Unicode and can
only be used on a class level."""
def provides(interface):
"""Explicitly specify with which interface a component will be
looked up."""
def global_utility(factory, provides=None, name=u''):
"""Register a global utility.
factory - the factory that creates the global utility
provides - the interface the utility should be looked up with
name - the name of the utility
"""
def global_adapter(factory, adapts=None, provides=None, name=u''):
"""Register a global adapter.
factory - the adapter factory, a callable
adapts - an interface or list of interfaces adapted
provides - the interface provided by the adapter
name - the name of the adapter
"""
def direct():
"""Specify whether the class should be used for the component
or whether it should be used to instantiate the component.
This directive can be used on GlobalUtility-based classes to
indicate whether the class itself should be registered as a
utility, or an instance of it.
"""
def order(value=None):
"""Control the ordering of components.
If the value is specified, the order will be determined by sorting on
it.
If no value is specified, the order will be determined by definition
order within the module.
If the directive is absent, the order will be determined by class name.
(unfortunately our preferred default behavior on absence which would
be like grok.order() without argument is hard to implement in Python)
Inter-module order is by dotted name of the module the
components are in; unless an explicit argument is specified to
``grok.order()``, components are grouped by module.
The function grok.util.sort_components can be used to sort
components according to these rules.
"""
class IDecorators(Interface):
def subscribe(*classes_or_interfaces):
"""Declare that a function subscribes to an event or a
combination of objects and events."""
def adapter(*classes_or_interfaces):
"""Describes that a function adapts an object or a combination
of objects.
"""
def implementer(*interfaces):
"""Describes that a function that's used as an adapter
implements an interface or a number of interfaces.
"""
def provider(*interfaces):
"""Describes that a function directly provides an interface or a
number of interfaces.
"""
class IGrokErrors(Interface):
def GrokError(message, component):
"""Error indicating that a problem occurrend during the
grokking of a module (at "grok time")."""
def GrokImportError(*args):
"""Error indicating a problem at import time."""
class IMartianAPI(Interface):
"""Part of Martian's API exposed by grokcore.component.
"""
ClassGrokker = Attribute("Grokker for classes.")
GlobalGrokker = Attribute("Grokker that's invoked for a module.")
InstanceGrokker = Attribute("Grokker for instances.")
class IGrokcoreComponentAPI(
IBaseClasses,
IDecorators,
IDirectives,
IGrokErrors,
IMartianAPI,
):
"""grokcore.component's public API.
"""
getSiteManager = Attribute('Get the site manager for the nearest site.')
provideAdapter = Attribute('Registers an adapters')
provideHandler = Attribute('Registers an handler')
provideInterface = Attribute('Regsiters an interfaces as a utility')
provideSubscriptionAdapter = Attribute(
'Registers an subscriptions adapter')
provideUtility = Attribute('Registers an utility')
querySubscriptions = Attribute("Function to query subscriptions.")
queryOrderedSubscriptions = Attribute(
"Function to query subscription in order.")
queryMultiSubscriptions = Attribute("Function to query subscriptions.")
queryOrderedMultiSubscriptions = Attribute(
"Function to query subscriptions in order.")
sort_components = Attribute(
'Sort a list of components using the information provided by '
'`grok.order`.')
grokcore.component-2.5/src/grokcore/component/directive.py 0000664 0001750 0001750 00000014231 11750014416 023214 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok directives.
"""
import martian
import martian.util
from martian.error import GrokError, GrokImportError
from martian.util import scan_for_classes
from zope import interface
from zope.interface.interfaces import IInterface
from grokcore.component.interfaces import IContext
class global_utility(martian.MultipleTimesDirective):
"""Registers an instance of ``class`` (or ``class`` itself, depending on
the value of the ``direct`` parameter) as a global utility.
This allows you to register global utilities that don't inherit from the
``GlobalUtility`` base class.
:param class: The class to register as a global utility.
:param provides: Optionally, the interface the utility will provide.
:param name: Optionally, a name for a named utility registration.
:type name: string or unicode
:param direct: Optionally, a flag indicating the class directly provides
the interfaces, and it needs not to be instantiated.
:type direct: boolean
"""
scope = martian.MODULE
def factory(self, factory, provides=None, name=u'', direct=False):
if provides is not None and not IInterface.providedBy(provides):
raise GrokImportError(
"You can only pass an interface to the "
"provides argument of %s." % self.name)
return (factory, provides, name, direct)
class global_adapter(martian.MultipleTimesDirective):
"""Registers the ``factory`` callable as a global adapter.
This allows you to register global adapters that
don't inherit from the ``Adapter`` or ``MultiAdapter`` base classes.
:param factory: The class that implements the adaptation.
:param adapts: Optionally, a single interface or a tuple of multiple
interfaces to adapts from. If omitted, this information is
deduced from the annotation on the factory. If no adapted
interface can be determined the current context will be
assumed.
:param provides: Optionally, the interface the adapter will provide. If
omitted, this information is deduced from the annotations
on the factory.
:param name: Optionally, a name for a named adapter registration.
:type name: string or unicode
"""
scope = martian.MODULE
def factory(self, factory, adapts=None, provides=None, name=None):
if provides is not None and not IInterface.providedBy(provides):
raise GrokImportError(
"You can only pass an interface to the "
"provides argument of %s." % self.name)
if adapts is None:
adapts = getattr(factory, '__component_adapts__', None)
elif not isinstance(adapts, (list, tuple,)):
adapts = (adapts,)
elif isinstance(adapts, list):
adapts = tuple(adapts)
return (factory, adapts, provides, name)
class name(martian.Directive):
"""Declares the name of a named utility, named adapter, etc.
"""
scope = martian.CLASS
store = martian.ONCE
validate = martian.validateText
default = u''
class context(martian.Directive):
"""Declares the type of object that the adapter (or a similar context-
dependent component) adapts.
:param context: Interface (in this case all objects providing this
interface will be eligible contexts for the adaptation) or
a class (then only instances of that particular class are
eligible).
"""
scope = martian.CLASS_OR_MODULE
store = martian.ONCE
validate = martian.validateInterfaceOrClass
@classmethod
def get_default(cls, component, module=None, **data):
components = list(scan_for_classes(module, IContext))
if len(components) == 0:
raise GrokError(
"No module-level context for %r, please use the 'context' "
"directive." % (component), component)
elif len(components) == 1:
component = components[0]
else:
raise GrokError(
"Multiple possible contexts for %r, please use the 'context' "
"directive."
% (component), component)
return component
class title(martian.Directive):
"""Declares the human-readable title of a component (such as a permission,
role, etc.)
"""
scope = martian.CLASS
store = martian.ONCE
validate = martian.validateText
class description(title):
pass
class direct(martian.MarkerDirective):
"""Declares that a ``GlobalUtility`` class should be registered as a
utility itself, rather than an instance of it.
"""
scope = martian.CLASS
class order(martian.Directive):
scope = martian.CLASS
store = martian.ONCE
default = 0, 0
_order = 0
def factory(self, value=0):
order._order += 1
return value, order._order
class path(martian.Directive):
scope = martian.CLASS
store = martian.ONCE
validate = martian.validateText
class provides(martian.Directive):
"""Declares the interface that a adapter or utility provides for the
registration, as opposed to potentially multiple interfaces that the class
implements.
:param interface: The interface the registered component will provide.
"""
scope = martian.CLASS
store = martian.ONCE
validate = martian.validateInterface
@classmethod
def get_default(cls, component, module, **data):
martian.util.check_implements_one(component)
return list(interface.implementedBy(component))[0]
grokcore.component-2.5/src/grokcore/component/meta.py 0000664 0001750 0001750 00000022211 11750014416 022161 0 ustar jw jw 0000000 0000000 #############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grokkers for the various components."""
import operator
import martian
import martian.util
import grokcore.component
import zope.component.interface
from zope import component, interface
from martian.error import GrokError
from zope.interface import implementedBy
def _provides(component, module=None, **data):
martian.util.check_implements_one(component)
return list(interface.implementedBy(component))[0]
def default_global_utility_provides(component, module, direct, **data):
if direct:
martian.util.check_provides_one(component)
return list(interface.providedBy(component))[0]
return _provides(component)
class AdapterGrokker(martian.ClassGrokker):
martian.component(grokcore.component.Adapter)
martian.directive(grokcore.component.context)
martian.directive(grokcore.component.provides)
martian.directive(grokcore.component.name)
def execute(self, factory, config, context, provides, name, **kw):
config.action(
discriminator=('adapter', context, provides, name),
callable=grokcore.component.provideAdapter,
args=(factory, (context,), provides, name),
)
return True
class MultiAdapterGrokker(martian.ClassGrokker):
martian.component(grokcore.component.MultiAdapter)
martian.directive(grokcore.component.provides)
martian.directive(grokcore.component.name)
def execute(self, factory, config, provides, name, **kw):
for_ = component.adaptedBy(factory)
if for_ is None:
raise GrokError("%r must specify which contexts it adapts "
"(use the 'adapts' directive to specify)."
% factory, factory)
config.action(
discriminator=('adapter', for_, provides, name),
callable=grokcore.component.provideAdapter,
args=(factory, None, provides, name),
)
return True
class SubscriptionGrokker(martian.ClassGrokker):
martian.component(grokcore.component.Subscription)
martian.directive(grokcore.component.context)
martian.directive(grokcore.component.provides)
martian.directive(grokcore.component.name)
def execute(self, factory, config, context, provides, name, **kw):
config.action(
discriminator=None,
callable=grokcore.component.provideSubscriptionAdapter,
args=(factory, (context,), provides),
)
return True
class MultiSubscriptionGrokker(martian.ClassGrokker):
martian.component(grokcore.component.MultiSubscription)
martian.directive(grokcore.component.provides)
martian.directive(grokcore.component.name)
def execute(self, factory, config, provides, name, **kw):
adapts = component.adaptedBy(factory)
if adapts is None:
raise GrokError("%r must specify which contexts it adapts "
"(use the 'adapts' directive to specify)."
% factory, factory)
config.action(
discriminator=None,
callable=grokcore.component.provideSubscriptionAdapter,
args=(factory, adapts, provides),
)
return True
class GlobalUtilityGrokker(martian.ClassGrokker):
martian.component(grokcore.component.GlobalUtility)
# This needs to happen before the FilesystemPageTemplateGrokker grokker
# happens, since it relies on the ITemplateFileFactories being grokked.
martian.priority(1100)
martian.directive(grokcore.component.direct)
martian.directive(grokcore.component.provides,
get_default=default_global_utility_provides)
martian.directive(grokcore.component.name)
def execute(self, factory, config, direct, provides, name, **kw):
if not direct:
factory = factory()
config.action(
discriminator=('utility', provides, name),
callable=grokcore.component.provideUtility,
args=(factory, provides, name),
)
return True
class ImplementerDecoratorGrokker(martian.GlobalGrokker):
def grok(self, name, module, module_info, config, **kw):
adapters = module_info.getAnnotation('grok.adapters', [])
subscribers = set(map(operator.itemgetter(0),
module_info.getAnnotation('grok.subscribers', [])))
for function in adapters:
if function in subscribers:
# We don't register functions that are decorated with
# grok.implementer() *and* the grok.subscribe()
# decorator. These are registered as so called
# subcribers and not as regular adapters.
continue
interfaces = getattr(function, '__component_adapts__', None)
if interfaces is None:
context = grokcore.component.context.bind().get(module)
interfaces = (context, )
name = getattr(function, '__component_name__', u"")
config.action(
discriminator=('adapter', interfaces, function.__implemented__, name),
callable=grokcore.component.provideAdapter,
args=(function, interfaces, function.__implemented__, name),
)
return True
class GlobalUtilityDirectiveGrokker(martian.GlobalGrokker):
def grok(self, name, module, module_info, config, **kw):
infos = grokcore.component.global_utility.bind().get(module)
for factory, provides, name, direct in infos:
if direct is None:
direct = grokcore.component.direct.bind().get(factory)
if provides is None:
bound = grokcore.component.provides.bind(default=None)
provides = bound.get(factory)
if not name:
name = grokcore.component.name.bind().get(factory)
if direct:
obj = factory
if provides is None:
martian.util.check_provides_one(obj)
provides = list(interface.providedBy(obj))[0]
else:
obj = factory()
if provides is None:
provides = _provides(factory)
config.action(
discriminator=('utility', provides, name),
callable=grokcore.component.provideUtility,
args=(obj, provides, name),
)
return True
class GlobalAdapterDirectiveGrokker(martian.GlobalGrokker):
def grok(self, name, module, module_info, config, **kw):
infos = grokcore.component.global_adapter.bind().get(module)
for factory, adapts, provides, name in infos:
if provides is None:
bound = grokcore.component.provides.bind(default=None)
provides = bound.get(factory)
if adapts is None:
adapts = (grokcore.component.context.bind().get(module),)
if name is None:
name = grokcore.component.name.bind().get(factory)
config.action(
discriminator=('adapter', adapts, provides, name),
callable=grokcore.component.provideAdapter,
args=(factory, adapts, provides, name),
)
return True
class SubscriberDirectiveGrokker(martian.GlobalGrokker):
def grok(self, name, module, module_info, config, **kw):
subscribers = module_info.getAnnotation('grok.subscribers', [])
for factory, subscribed in subscribers:
provides = None
implemented = list(implementedBy(factory))
if len(implemented) == 1:
provides = implemented[0]
# provideHandler is essentially the same as
# provideSubscriptionAdapter, where provided=None. However,
# handlers and subscription adapters are tracked in
# separately so we cannot exchange one registration call
# for the the other.
if provides is None:
config.action(
discriminator=None,
callable=grokcore.component.provideHandler,
args=(factory, subscribed))
else:
config.action(
discriminator=None,
callable=grokcore.component.provideSubscriptionAdapter,
args=(factory, subscribed, provides))
for iface in subscribed:
config.action(
discriminator=None,
callable=grokcore.component.provideInterface,
args=('', iface))
return True
grokcore.component-2.5/src/grokcore/component/subscription.py 0000664 0001750 0001750 00000003331 11750014416 023761 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok subscriptions functions.
"""
from zope import component
from grokcore.component import util
def queryOrderedMultiSubscriptions(components, interface):
return util.sort_components(component.subscribers(components, interface))
def queryOrderedSubscriptions(component, interface):
return queryOrderedMultiSubscriptions((component, ), interface)
def queryMultiSubscriptions(components, interface):
"""Query for subscriptions on the `components` providing `interface`.
:parameter components: tuple of components to lookup the subscription for.
:parameter interface: interface that the subscriptions should provide.
:return: a list of subscriptions.
"""
return component.subscribers(components, interface)
def querySubscriptions(component, interface):
"""Query for subscriptions on `component` providing `interface`.
:parameter component: a component to lookup the subscriptions for.
:parameter interface: interface that the subscriptions should provide.
:return: a list of subscription.
"""
return queryMultiSubscriptions((component,), interface)
grokcore.component-2.5/src/grokcore/component/decorators.py 0000664 0001750 0001750 00000011237 11750014416 023406 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok
"""
import sys
import types
import zope.component
import zope.interface
from martian.util import frame_is_module
from martian.error import GrokImportError
from zope.interface.declarations import DescriptorAwareMetaClasses
class subscribe:
"""Declares that a function is to be registered as an event handler for the
specified objects.
Normally, an event handler is simply registered as a subscriber for the
event interface. In case of object events, the event handler is registered
as a subscriber for the object type and the event interface.
"""
def __init__(self, *args):
self.subscribed = args
def __call__(self, function):
frame = sys._getframe(1)
if not frame_is_module(frame):
raise GrokImportError("@grok.subscribe can only be used on module "
"level.")
if not self.subscribed:
raise GrokImportError("@grok.subscribe requires at least one "
"argument.")
# Add the function and subscribed interfaces to the
# grok.subscribers module annotation.
subscribers = frame.f_locals.get('__grok_subscribers__', None)
if subscribers is None:
frame.f_locals['__grok_subscribers__'] = subscribers = []
subscribers.append((function, self.subscribed))
# Also store the subscribed interfaces on the
# attribute__component_adapts__ for provideHandler to register
# the subscriber (in case you don't grok your package and
# register it manually)
return zope.component.adapter(*self.subscribed)(function)
class adapter(zope.component.adapter):
"""Registers the function as an adapter for the specific interface.
The ``name`` argument must be a keyword argument and is optional. If given,
a named adapter is registered.
"""
# Override the z.c.adapter decorator to force sanity checking and
# have better error reporting and add the ability to capture the name
def __init__(self, *interfaces, **kw):
if not interfaces:
raise GrokImportError(
"@grok.adapter requires at least one argument.")
if type(interfaces[0]) is types.FunctionType:
raise GrokImportError(
"@grok.adapter requires at least one argument.")
self.name = u""
if kw:
if 'name' in kw:
self.name = kw.pop('name')
if kw:
raise GrokImportError(
"@grok.adapter got unexpected keyword arguments: %s" % ','.join(kw.keys()))
zope.component.adapter.__init__(self, *interfaces)
def __call__(self, ob):
ob = zope.component.adapter.__call__(self, ob)
if self.name:
ob.__component_name__ = self.name
return ob
class implementer(zope.interface.implementer):
"""Declares that the function implements a certain interface (or a number
of interfaces).
This is useful when a function serves as an object factory, e.g. as an
adapter.
"""
def __call__(self, ob):
# XXX we do not have function grokkers (yet) so we put the annotation
# on the module.
frame = sys._getframe(1)
adapters = frame.f_locals.get('__grok_adapters__', None)
if adapters is None:
frame.f_locals['__grok_adapters__'] = adapters = []
adapters.append(ob)
return zope.interface.implementer.__call__(self, ob)
class provider:
"""Declares that the function object provides a certain interface (or a
number of interfaces).
This is akin to calling directlyProvides() on the function object.
"""
def __init__(self, *interfaces):
self.interfaces = interfaces
def __call__(self, ob):
if isinstance(ob, DescriptorAwareMetaClasses):
raise TypeError("Can't use implementer with classes. Use one of "
"the class-declaration functions instead."
)
zope.interface.alsoProvides(ob, *self.interfaces)
return ob
grokcore.component-2.5/src/grokcore/component/templates/ 0000775 0001750 0001750 00000000000 11750014424 022660 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/templates/default_display_form.pt 0000664 0001750 0001750 00000001473 11750014416 027427 0 ustar jw jw 0000000 0000000
grokcore.component-2.5/src/grokcore/component/templates/default_edit_form.pt 0000664 0001750 0001750 00000003777 11750014416 026720 0 ustar jw jw 0000000 0000000
grokcore.component-2.5/src/grokcore/component/zcml.py 0000664 0001750 0001750 00000004203 11750014416 022201 0 ustar jw jw 0000000 0000000 ##############################################################################
#
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""Grok ZCML directives."""
from zope.interface import Interface
from zope.configuration.fields import GlobalObject
from zope.schema import TextLine
import martian
class IGrokDirective(Interface):
"""Grok a package or module."""
package = GlobalObject(
title=u"Package",
description=u"The package or module to be analyzed by grok.",
required=False)
exclude = TextLine(
title=u"Exclude",
description=u"Name to exclude in the grokking process.",
required=False)
# add a cleanup hook so that grok will bootstrap itself again whenever
# the Component Architecture is torn down.
def resetBootstrap():
# we need to make sure that the grokker registry is clean again
the_module_grokker.clear()
from zope.testing.cleanup import addCleanUp
addCleanUp(resetBootstrap)
the_multi_grokker = martian.MetaMultiGrokker()
the_module_grokker = martian.ModuleGrokker(the_multi_grokker)
def skip_tests(name):
return name in ['tests', 'ftests', 'testing']
def grokDirective(_context, package, exclude=None):
if not exclude:
exclude = None
do_grok(package.__name__, _context, extra_exclude=exclude)
def do_grok(dotted_name, config, extra_exclude=None):
if extra_exclude is not None:
def exclude_filter(name):
return skip_tests(name) or extra_exclude == name
else:
exclude_filter = skip_tests
martian.grok_dotted_name(
dotted_name, the_module_grokker, exclude_filter=exclude_filter,
config=config)
grokcore.component-2.5/src/grokcore/component/tests/ 0000775 0001750 0001750 00000000000 11750014424 022024 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/utility/ 0000775 0001750 0001750 00000000000 11750014424 023527 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/utility/__init__.py 0000664 0001750 0001750 00000000024 11750014416 025635 0 ustar jw jw 0000000 0000000 # this is a package
grokcore.component-2.5/src/grokcore/component/tests/utility/providesmany.py 0000664 0001750 0001750 00000001262 11750014416 026623 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility that are supposed to be registered
directly as utilities and which provide more than one interface must
specify which interface to use for the registration:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
provides more than one interface (use grok.provides to specify which one
to use).
"""
import grokcore.component as grok
from zope import interface
class IClub(interface.Interface):
pass
class ISpikyClub(interface.Interface):
pass
class Club(grok.GlobalUtility):
interface.classProvides(IClub, ISpikyClub)
grok.direct()
grokcore.component-2.5/src/grokcore/component/tests/utility/providesmany2.py 0000664 0001750 0001750 00000001275 11750014416 026711 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility that are supposed to be registered
directly as utilities and which provide more than one interface must
specify which interface to use for the registration:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
provides more than one interface (use grok.provides to specify which one
to use).
"""
import grokcore.component as grok
from zope import interface
class IClub(interface.Interface):
pass
class ISpikyClub(interface.Interface):
pass
class Club(object):
interface.classProvides(IClub, ISpikyClub)
grok.global_utility(Club, direct=True)
grokcore.component-2.5/src/grokcore/component/tests/utility/implementsmany2.py 0000664 0001750 0001750 00000001164 11750014416 027230 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility that implement more than one interface must
specify which interface to use for the registration:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: is implementing
more than one interface (use grok.provides to specify which one to use).
"""
import grokcore.component as grok
from zope import interface
class IClub(interface.Interface):
pass
class ISpikyClub(interface.Interface):
pass
class Club(object):
grok.implements(IClub, ISpikyClub)
grok.global_utility(Club)
grokcore.component-2.5/src/grokcore/component/tests/utility/providesnone.py 0000664 0001750 0001750 00000000625 11750014416 026620 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility must implement exactly one interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
must provide at least one interface (use zope.interface.classProvides
to specify).
"""
import grokcore.component as grok
class Club(grok.GlobalUtility):
grok.direct()
grokcore.component-2.5/src/grokcore/component/tests/utility/implementsnone.py 0000664 0001750 0001750 00000000601 11750014416 027134 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility must implement exactly one interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: must
implement at least one interface (use grok.implements to specify).
"""
import grokcore.component as grok
class Club(grok.GlobalUtility):
pass
grokcore.component-2.5/src/grokcore/component/tests/utility/implementsnone2.py 0000664 0001750 0001750 00000000621 11750014416 027220 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility must implement exactly one interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: must
implement at least one interface (use grok.implements to specify).
"""
import grokcore.component as grok
class Club(object):
pass
grok.global_utility(Club)
grokcore.component-2.5/src/grokcore/component/tests/utility/conflict.py 0000664 0001750 0001750 00000005216 11750014416 025707 0 ustar jw jw 0000000 0000000 """
Trying to register two utilities for the same interface (and
potentially under the same name) will generate a configuration
conflict:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
ConfigurationConflictError: Conflicting configuration actions
For: ('utility', , 'class and module')
For: ('utility', , 'direct class')
For: ('utility', , 'explicit class')
For: ('utility', , 'implicit class')
For: ('utility', , 'mixed class')
"""
import grokcore.component as grok
from zope.interface import Interface, classProvides
class IUtilityInterface(Interface):
pass
class IAnotherInterface(Interface):
pass
class Implicit1(grok.GlobalUtility):
grok.implements(IUtilityInterface)
grok.name('implicit class')
class Implicit2(grok.GlobalUtility):
grok.implements(IUtilityInterface)
grok.name('implicit class')
class Explicit1(grok.GlobalUtility):
grok.implements(IUtilityInterface, IAnotherInterface)
grok.provides(IUtilityInterface)
grok.name('explicit class')
class Explicit2(grok.GlobalUtility):
grok.implements(IUtilityInterface, IAnotherInterface)
grok.provides(IUtilityInterface)
grok.name('explicit class')
class Mixed1(grok.GlobalUtility):
grok.implements(IUtilityInterface, IAnotherInterface)
grok.provides(IUtilityInterface)
grok.name('mixed class')
class Mixed2(grok.GlobalUtility):
grok.implements(IUtilityInterface)
grok.name('mixed class')
class Direct1(grok.GlobalUtility):
classProvides(IUtilityInterface)
grok.name('direct class')
grok.direct()
class Direct2(grok.GlobalUtility):
classProvides(IUtilityInterface)
grok.name('direct class')
grok.direct()
class ClassLevel(grok.GlobalUtility):
"""This utility inherits from Grok's base class and is registered
this way."""
grok.implements(IUtilityInterface)
grok.name('class and module')
class ModuleLevel(object):
"""This utility doesn't inherit from Grok's base class and is
registered explicitly using the module-level directive below."""
grok.implements(IUtilityInterface)
grok.global_utility(ModuleLevel, name='class and module')
grokcore.component-2.5/src/grokcore/component/tests/utility/implementsmany.py 0000664 0001750 0001750 00000001143 11750014416 027143 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility that implement more than one interface must
specify which interface to use for the registration:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: is implementing
more than one interface (use grok.provides to specify which one to use).
"""
import grokcore.component as grok
from zope import interface
class IClub(interface.Interface):
pass
class ISpikyClub(interface.Interface):
pass
class Club(grok.GlobalUtility):
grok.implements(IClub, ISpikyClub)
grokcore.component-2.5/src/grokcore/component/tests/utility/providesnone2.py 0000664 0001750 0001750 00000000651 11750014416 026701 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.GlobalUtility must implement exactly one interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
must provide at least one interface (use zope.interface.classProvides
to specify).
"""
import grokcore.component as grok
class Club(object):
pass
grok.global_utility(Club, direct=True)
grokcore.component-2.5/src/grokcore/component/tests/utility/utility.py 0000664 0001750 0001750 00000012245 11750014416 025611 0 ustar jw jw 0000000 0000000 """
Global utilities can be created by subclassing grok.GlobalUtility:
>>> grok.testing.grok(__name__)
>>> from zope import component
>>> normal_club = component.getUtility(IClub)
>>> IClub.providedBy(normal_club)
True
>>> isinstance(normal_club, NormalClub)
True
Named utilities are registered using grok.name:
>>> huge_club = component.getUtility(IClub, name='huge')
>>> IClub.providedBy(huge_club)
True
>>> isinstance(huge_club, HugeClub)
True
A utility can explicitly specify which interface it should be looked up with.
>>> spiky_club = component.getUtility(IClub, name='spiky')
>>> isinstance(spiky_club, SpikyClub)
True
>>> component.getUtility(ISpikyClub, name='spiky')
Traceback (most recent call last):
...
ComponentLookupError: (,
'spiky')
If a utility implements more than one interface, it has to specify the one to
use with 'grok.provides':
>>> nightclub = component.getUtility(INightClub)
>>> INightClub.providedBy(nightclub)
True
>>> isinstance(nightclub, NightClub)
True
You can make the class the utility by providing the grok.direct() directive,
if you also use interface.classProvides instead of grok.provides.
This is useful for utilities that do nothing but create instances:
>>> clubmaker = component.getUtility(IClubMaker, 'maker')
>>> IClubMaker.providedBy(clubmaker)
True
>>> clubmaker is ClubMaker
True
Utilities (including classes that do not subclass from grok.GlobalUtility) can
be (re-)registered using grok.global_utility:
>>> fireplace = component.getUtility(IFireplace)
>>> IFireplace.providedBy(fireplace)
True
>>> isinstance(fireplace, Fireplace)
True
>>> fireplace = component.getUtility(IFireplace, name='hot')
>>> IFireplace.providedBy(fireplace)
True
>>> isinstance(fireplace, Fireplace)
True
>>> home = component.getUtility(IHome)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
>>> night = component.getUtility(INightClub, name='cool')
>>> IClub.providedBy(night)
True
>>> isinstance(night, NightClub)
True
>>> spiky = component.getUtility(ISpikyClub)
>>> ISpikyClub.providedBy(spiky)
True
>>> isinstance(spiky, NightClub)
True
When re-registering a grok.GlobalUtility, the directives grok.name and
grok.provides on the class will be used, but can be overriden in the
grok.global_utility directive:
>>> small = component.getUtility(ISmallClub, name='tiny')
>>> ISmallClub.providedBy(small)
True
>>> isinstance(small, SmallClub)
True
>>> small2 = component.getUtility(ITinyClub, name='tiny')
>>> ISmallClub.providedBy(small2)
True
>>> isinstance(small2, SmallClub)
True
>>> small is not small2
True
>>> small3 = component.getUtility(ISmallClub, name='small')
>>> ISmallClub.providedBy(small3)
True
>>> isinstance(small3, SmallClub)
True
>>> small3 is not small2 and small3 is not small
True
Normally one registers a utility factory, such as the class, as a
global utility. It is also possible to register an arbitrary object directly
as a global utility. You do this by passing a 'direct' argument set to
'True'. This can be useful if one needs to register functions (such
as factory functions) that can be looked up as a utility, or if the
class you want to register as a global utility has an __init__ that
takes arguments, where you want to do the instantiation yourself.
Let's look up an instance we registered this way:
>>> small4 = component.getUtility(ISmallClub, name='smallish')
>>> ISmallClub.providedBy(small4)
True
>>> isinstance(small4, SmallClub)
True
"""
import grokcore.component as grok
from zope import interface
class IClub(interface.Interface):
pass
class ISpikyClub(IClub):
pass
class ISmallClub(IClub):
pass
class ITinyClub(IClub):
pass
class INightClub(interface.Interface):
pass
class IClubMaker(interface.Interface):
pass
class NormalClub(grok.GlobalUtility):
grok.implements(IClub)
class HugeClub(grok.GlobalUtility):
grok.implements(IClub)
grok.name('huge')
class SpikyClub(grok.GlobalUtility):
grok.implements(ISpikyClub)
grok.provides(IClub)
grok.name('spiky')
class NightClub(grok.GlobalUtility):
grok.implements(INightClub, ISpikyClub)
grok.provides(INightClub)
class SmallClub(grok.GlobalUtility):
grok.implements(ISmallClub, ITinyClub)
grok.provides(ISmallClub)
grok.name('tiny')
class ClubMaker(grok.GlobalUtility):
grok.implements(IClub)
interface.classProvides(IClubMaker)
grok.direct()
grok.name('maker')
class IFireplace(interface.Interface):
pass
class IHome(interface.Interface):
pass
class Fireplace(object):
grok.implements(IFireplace)
class Home(object):
grok.implements(IFireplace, IHome)
grok.global_utility(Fireplace)
grok.global_utility(Fireplace, name='hot')
grok.global_utility(Home, provides=IHome)
grok.global_utility(NightClub, name='cool')
grok.global_utility(NightClub, provides=ISpikyClub)
grok.global_utility(SmallClub, provides=ITinyClub)
grok.global_utility(SmallClub, name='small')
grok.global_utility(SmallClub(), name='smallish',
direct=True)
grokcore.component-2.5/src/grokcore/component/tests/order/ 0000775 0001750 0001750 00000000000 11750014424 023137 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/order/arg_orderdirective.py 0000664 0001750 0001750 00000001651 11750014416 027360 0 ustar jw jw 0000000 0000000 """
If the grok.order directive is present with arguments, sorting will be
done by the order specified.
>>> from grokcore.component import sort_components
>>> components = [First(), Second(), Third(), Fourth(), Fifth()]
>>> sort_components(components)
[<...Fifth object at ...>,
<...Fourth object at ...>,
<...Third object at ...>,
<...Second object at ...>,
<...First object at ...>]
You can use the key option:
>>> from operator import itemgetter
>>> components = [(1, First()), (2, Second()), (3, Third())]
>>> sort_components(components, key=itemgetter(1))
[(3, <...Third object at ...>),
(2, <...Second object at ...>),
(1, <...First object at ...>)]
"""
import grokcore.component as grok
class First(object):
grok.order(5)
class Second(object):
grok.order(4)
class Third(object):
grok.order(3)
class Fourth(object):
grok.order(2)
class Fifth(object):
grok.order(1)
grokcore.component-2.5/src/grokcore/component/tests/order/__init__.py 0000664 0001750 0001750 00000000002 11750014416 025241 0 ustar jw jw 0000000 0000000 #
grokcore.component-2.5/src/grokcore/component/tests/order/combined_orderdirective.py 0000664 0001750 0001750 00000001362 11750014416 030366 0 ustar jw jw 0000000 0000000 """
If the grok.order directive is specified with other classes that don't
have the order specified, then the order will be determined by first
sorting on the order specified, and then by the definition order.
>>> components = [First(), Second(), Third(), Fourth(), Fifth()]
>>> from grokcore.component import sort_components
>>> sort_components(components)
[<...Third object at ...>,
<...Fourth object at ...>,
<...Second object at ...>,
<...Fifth object at ...>,
<...First object at ...>]
"""
import grokcore.component as grok
class First(object):
grok.order(2)
class Second(object):
grok.order(1)
class Third(object):
grok.order()
class Fourth(object):
grok.order()
class Fifth(object):
grok.order(1)
grokcore.component-2.5/src/grokcore/component/tests/order/noarg_orderdirective.py 0000664 0001750 0001750 00000001205 11750014416 027710 0 ustar jw jw 0000000 0000000 """
If the grok.order directive is present with no arguments, sorting will
be done by definition order.
>>> components = [First(), Second(), Third(), Fourth(), Fifth()]
>>> from grokcore.component import sort_components
>>> sort_components(components)
[<...First object at ...>,
<...Second object at ...>,
<...Third object at ...>,
<...Fourth object at ...>,
<...Fifth object at ...>]
"""
import grokcore.component as grok
class First(object):
grok.order()
class Second(object):
grok.order()
class Third(object):
grok.order()
class Fourth(object):
grok.order()
class Fifth(object):
grok.order()
grokcore.component-2.5/src/grokcore/component/tests/order/nodirective.py 0000664 0001750 0001750 00000001041 11750014416 026021 0 ustar jw jw 0000000 0000000 """
If the grok.order directive is absent, sorting will be done by class
name.
>>> components = [First(), Second(), Third(), Fourth(), Fifth()]
>>> from grokcore.component import sort_components
>>> sort_components(components)
[<...Fifth object at ...>,
<...First object at ...>,
<...Fourth object at ...>,
<...Second object at ...>,
<...Third object at ...>]
"""
class First(object):
pass
class Second(object):
pass
class Third(object):
pass
class Fourth(object):
pass
class Fifth(object):
pass
grokcore.component-2.5/src/grokcore/component/tests/order/inter2.py 0000664 0001750 0001750 00000000266 11750014416 024721 0 ustar jw jw 0000000 0000000 """
This module used by inter1 tests
"""
import grokcore.component as grok
class Four(object):
grok.order(1)
class Five(object):
pass
class Six(object):
grok.order()
grokcore.component-2.5/src/grokcore/component/tests/order/combinednoorder_orderdirective.py 0000664 0001750 0001750 00000001340 11750014416 031753 0 ustar jw jw 0000000 0000000 """
If the grok.order directive is specified with other classes that don't
have the order specified, then the order will be determined by first
sorting on the order specified, and then by the definition order.
>>> components = [First(), Second(), Third(), Fourth(), Fifth()]
>>> from grokcore.component import sort_components
>>> sort_components(components)
[<...Fifth object at ...>,
<...Third object at ...>,
<...First object at ...>,
<...Fourth object at ...>,
<...Second object at ...>]
"""
import grokcore.component as grok
class First(object):
grok.order()
class Second(object):
grok.order(1)
class Third(object):
pass
class Fourth(object):
grok.order()
class Fifth(object):
pass
grokcore.component-2.5/src/grokcore/component/tests/order/inter1.py 0000664 0001750 0001750 00000001557 11750014416 024724 0 ustar jw jw 0000000 0000000 """
The ordering works like so:
1. Objects with explicit ordering
(if combined with objects with no ordering not specified, then the orderless
objects come first)
2. Objects with same ordering get grouped by module import order
3. Internal order within module
4. If no ordering is specified by any objects, then objects are sorted
alphabetically by class name
>>> from inter2 import Four, Five, Six
>>> components = [One(), Two(), Three(), Four(), Five(), Six()]
>>> from grokcore.component import sort_components
>>> sort_components(components)
[<...Three object at ...>,
<...One object at ...>,
<...Five object at ...>,
<...Six object at ...>,
<...Four object at ...>,
<...Two object at ...>]
"""
import grokcore.component as grok
class One(object):
grok.order()
class Two(object):
grok.order(2)
class Three(object):
pass
grokcore.component-2.5/src/grokcore/component/tests/directive/ 0000775 0001750 0001750 00000000000 11750014424 024002 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/directive/__init__.py 0000664 0001750 0001750 00000000024 11750014416 026110 0 ustar jw jw 0000000 0000000 # this is a package
grokcore.component-2.5/src/grokcore/component/tests/directive/argumenterror_fixture.py 0000664 0001750 0001750 00000000140 11750014416 031012 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
class Foo(object):
grok.name('too', 'many', 'arguments')
grokcore.component-2.5/src/grokcore/component/tests/directive/multipletimes.py 0000664 0001750 0001750 00000002104 11750014416 027247 0 ustar jw jw 0000000 0000000 """
Since grok.global_utility is a MultipleTimesDirective, there is a list of
GlobalUtilityInfo objects annotated on the module.
>>> from martian import scan
>>> import grokcore.component as grok
>>> from grokcore.component.tests.directive import multipletimes
>>> guis = grok.global_utility.bind().get(multipletimes)
>>> len(guis)
2
>>> factory, provides, name, direct = guis[0]
>>> factory
>>> provides
>>> name
'foo'
>>> factory, provides, name, direct = guis[1]
>>> factory
>>> provides is None
True
>>> name
u''
"""
import grokcore.component as grok
from zope import interface
class IClub(interface.Interface):
pass
class ICave(interface.Interface):
pass
class Club(object):
grok.implements(IClub)
class Cave(object):
grok.implements(ICave)
grok.global_utility(Club, provides=IClub, name='foo')
grok.global_utility(Cave)
grokcore.component-2.5/src/grokcore/component/tests/directive/argumenterror.py 0000664 0001750 0001750 00000000265 11750014416 027254 0 ustar jw jw 0000000 0000000 """
>>> import grokcore.component.tests.directive.argumenterror_fixture
Traceback (most recent call last):
...
TypeError: name takes exactly 1 argument (3 given)
"""
grokcore.component-2.5/src/grokcore/component/tests/__init__.py 0000664 0001750 0001750 00000000040 11750014416 024130 0 ustar jw jw 0000000 0000000 # make this directory a package
grokcore.component-2.5/src/grokcore/component/tests/grokker/ 0000775 0001750 0001750 00000000000 11750014424 023470 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/grokker/continue_scanning.py 0000664 0001750 0001750 00000002133 11750014416 027546 0 ustar jw jw 0000000 0000000 """
A Grokker can declare that scanning should continue, so that other Grokkers can
still perform actions on the grokked components.
Here we define AlphaGrokker which has higher priority than BetaGrokker but does
not block BetaGrokker from picking up the same component::
>>> import grokcore.component as grok
>>> grok.testing.grok(__name__)
In the fixture there is AlphaBetaSub that inherits from both Alpha and Beta.
Thus, both Grokkers are executed, with AlphaGrokker coming before BetaGrokker::
>>> grok.testing.grok('grokcore.component.tests.grokker.continue_scanning_fixture')
alpha
beta
"""
import martian
class Alpha(object):
pass
class Beta(object):
pass
class AlphaGrokker(martian.ClassGrokker):
martian.component(Alpha)
martian.priority(1) # we need to go before BetaGrokker
def grok(self, name, factory, module_info, config, **kw):
print "alpha"
return True
class BetaGrokker(martian.ClassGrokker):
martian.component(Beta)
def grok(self, name, factory, module_info, config, **kw):
print "beta"
return True
grokcore.component-2.5/src/grokcore/component/tests/grokker/onlyonce.py 0000664 0001750 0001750 00000001677 11750014416 025704 0 ustar jw jw 0000000 0000000 """
We define a grokker AlphaGrokker for a component called Alpha. We first need to
grok the module defining the grokkers, in order to get them registered.
Usually this would be triggered from a meta.zcml in a package, that would grok
the module containing the grokkers (e.g. meta.py).
We do it manually now::
>>> import grokcore.component as grok
>>> grok.testing.grok('grokcore.component.tests.grokker.onlyonce_fixture._meta')
This _meta.py module then will be grokked again during 'normal' grok time. Grok
will not re-register the grokkers as this could have unwanted side-effects. It
will grok the components of course.
NOTE: the module is called _meta to make sure it is grokked (although its
grokker registration should be ignored) before the other files. The modules are
picked up in alphabetical order.
To simulate this, we grok the whole package::
>>> grok.testing.grok('grokcore.component.tests.grokker.onlyonce_fixture')
alpha
"""
grokcore.component-2.5/src/grokcore/component/tests/grokker/grokcomponent.py 0000664 0001750 0001750 00000003347 11750014416 026737 0 ustar jw jw 0000000 0000000 """
Let's first grok the meta module to define some basic grokkers::
>>> import grokcore.component as grok
>>> grok.testing.grok('grokcore.component.meta')
It is possible to grok an individual component. Let's define an adapter::
>>> from zope.interface import Interface
>>> class IMyInterface(Interface):
... pass
>>> class SomeClass(object):
... pass
>>> class MyAdapter(grok.Adapter):
... grok.provides(IMyInterface)
... grok.context(SomeClass)
To grok this adapter, you can simply write this::
>>> grok.testing.grok_component('MyAdapter', MyAdapter)
True
We can now use the adapter::
>>> instance = SomeClass()
>>> adapter = IMyInterface(instance)
>>> isinstance(adapter, MyAdapter)
True
We can use grok_component with only two arguments because we know the
adapter grokker is not looking for more. Sometimes we need to supply
an extra argument however::
>>> class ISecondInterface(Interface):
... pass
>>> class SecondAdapter(grok.Adapter):
... grok.provides(ISecondInterface)
This adapter does not supply its own context. Trying to do what we did
before will therefore fail::
>>> grok.testing.grok_component('SecondAdapter', SecondAdapter)
Traceback (most recent call last):
...
GrokError: No module-level context for , please use the 'context' directive.
So we need to supply the context ourselves::
>>> grok.testing.grok_component('SecondAdapter', SecondAdapter, context=SomeClass)
True
Now we can use the SecondAdapter as well::
>>> adapter = ISecondInterface(instance)
>>> isinstance(adapter, SecondAdapter)
True
The next optional argument is module_info and the final argument is
templates.
"""
grokcore.component-2.5/src/grokcore/component/tests/grokker/__init__.py 0000664 0001750 0001750 00000000001 11750014416 025571 0 ustar jw jw 0000000 0000000
grokcore.component-2.5/src/grokcore/component/tests/grokker/onlyonce_fixture/ 0000775 0001750 0001750 00000000000 11750014424 027064 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/grokker/onlyonce_fixture/__init__.py 0000664 0001750 0001750 00000000021 11750014416 031167 0 ustar jw jw 0000000 0000000 # fixture package grokcore.component-2.5/src/grokcore/component/tests/grokker/onlyonce_fixture/implementation.py 0000664 0001750 0001750 00000000074 11750014416 032465 0 ustar jw jw 0000000 0000000 from component import Alpha
class AlphaSub(Alpha):
pass grokcore.component-2.5/src/grokcore/component/tests/grokker/onlyonce_fixture/_meta.py 0000664 0001750 0001750 00000000324 11750014416 030523 0 ustar jw jw 0000000 0000000 import martian
from component import Alpha
class AlphaGrokker(martian.ClassGrokker):
martian.component(Alpha)
def grok(self, name, factory, module_info, **kw):
print "alpha"
return True
grokcore.component-2.5/src/grokcore/component/tests/grokker/onlyonce_fixture/component.py 0000664 0001750 0001750 00000000115 11750014416 031436 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
class Alpha(object):
grok.baseclass()
grokcore.component-2.5/src/grokcore/component/tests/grokker/continue_scanning_fixture.py 0000664 0001750 0001750 00000000166 11750014416 031320 0 ustar jw jw 0000000 0000000 from grokcore.component.tests.grokker.continue_scanning import Alpha, Beta
class AlphaBetaSub(Alpha, Beta):
pass
grokcore.component-2.5/src/grokcore/component/tests/grokker/priority_fixture.py 0000664 0001750 0001750 00000000420 11750014416 027466 0 ustar jw jw 0000000 0000000 import grokcore.component.tests.grokker.priority
class AlphaSub(grokcore.component.tests.grokker.priority.Alpha):
pass
class BetaSub(grokcore.component.tests.grokker.priority.Beta):
pass
class GammaSub(grokcore.component.tests.grokker.priority.Gamma):
pass
grokcore.component-2.5/src/grokcore/component/tests/grokker/priority.py 0000664 0001750 0001750 00000002275 11750014416 025732 0 ustar jw jw 0000000 0000000 """
We define grokkers for the three base classes Alpha, Beta, and Gamma with different
priorities:
- AlphaGrokker with priority 0 (default)
- BetaGrokker with priority 1
- GammaGrokker with priority -1
>>> import grokcore.component as grok
>>> grok.testing.grok(__name__)
We grok a module that implements subclasses for Alpha, Beta, and Gamma and our
grokkers get executed in the order of priority (highest first)::
>>> grok.testing.grok('grokcore.component.tests.grokker.priority_fixture')
beta
alpha
gamma
"""
import martian
class Alpha(object):
pass
class Beta(object):
pass
class Gamma(object):
pass
class AlphaGrokker(martian.ClassGrokker):
martian.component(Alpha)
def grok(self, name, factory, module_info, **kw):
print "alpha"
return True
class BetaGrokker(martian.ClassGrokker):
martian.component(Beta)
martian.priority(1)
def grok(self, name, factory, module_info, **kw):
print "beta"
return True
class GammaGrokker(martian.ClassGrokker):
martian.component(Gamma)
martian.priority(-1)
def grok(self, name, factory, module_info, **kw):
print "gamma"
return True
grokcore.component-2.5/src/grokcore/component/tests/api.txt 0000664 0001750 0001750 00000001241 11750014416 023335 0 ustar jw jw 0000000 0000000 The grokcore.component API
==========================
The grokcore.component API is described by the
``grokcore.component.interfaces.IGrokcoreComponentAPI`` interface.
When you do
>>> from grokcore.component import *
only those objects described in that API interface are imported into
your local namespace. In other words, if we take the list of things
that have been imported and subtract the things that have been defined
in the API interface, we'll end with pretty much nothing:
>>> from grokcore.component.interfaces import IGrokcoreComponentAPI
>>> sorted(set(locals()) - set(IGrokcoreComponentAPI))
['IGrokcoreComponentAPI', '__builtins__', '__file__']
grokcore.component-2.5/src/grokcore/component/tests/grok_component.txt 0000664 0001750 0001750 00000002443 11750014416 025615 0 ustar jw jw 0000000 0000000 Test grok_component() in an ordinary doctest.
We already have tests for grok_component(), but these were placed
inside a module. We will now test grok_component() in a pure doctest
context. This used to demonstrate an error in martian when dealing
with the __builtin__ module (fixed in martian 0.9.2).
grokcore.component.testing.grok_component() can be used to grok individual
components within a doctest, such as adapters. It sets up just enough
context for some grokking to work, though more complicated grokkers
which need module context (such as view grokkers) might not work.
This defines the object we want to provide an adapter for::
>>> class Bar(object):
... pass
This is the interface that we want to adapt to::
>>> from zope.interface import Interface
>>> class IFoo(Interface):
... pass
This is the adapter itself::
>>> import grokcore.component as grok
>>> class MyAdapter(grok.Adapter):
... grok.provides(IFoo)
... grok.context(Bar)
Now we will register the adapter using grok_component()::
>>> from grokcore.component.testing import grok, grok_component
>>> grok('grokcore.component.meta')
>>> grok_component('MyAdapter', MyAdapter)
True
The adapter should now be available::
>>> adapted = IFoo(Bar())
>>> isinstance(adapted, MyAdapter)
True
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/ 0000775 0001750 0001750 00000000000 11750014424 024733 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/subscriptions/multisubscriptions_no_adapts.py 0000664 0001750 0001750 00000000760 11750014416 033323 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
must specify which contexts it adapts (use the 'adapts' directive to specify).
"""
import grokcore.component as grok
from zope import interface
class IRenovate(interface.Interface):
def takedown():
pass
class CaveGardenRenovator(grok.MultiSubscription):
grok.provides(IRenovate)
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/multisubscriptions_no_interface.py0000664 0001750 0001750 00000000703 11750014416 034004 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
must implement at least one interface (use grok.implements to specify).
"""
import grokcore.component as grok
class Cave(grok.Context):
pass
class Garden(grok.Context):
pass
class CaveGardenRedecorator(grok.MultiSubscription):
pass
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/multisubscriptions.py 0000664 0001750 0001750 00000004662 11750014416 031300 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> cave = Cave('Tilburg cave')
>>> martijn = Mammoth('Martijn')
You can query a subscriptions using multiple components. You will get
all subscriptions registered for office and cave (since office is a
base class of cave):
>>> subscriptions = grok.queryMultiSubscriptions((cave, martijn), IActivity)
>>> subscriptions
[,
,
]
>>> _ = map(lambda s: s.do(), subscriptions)
Martijn is sleeping at Tilburg cave.
Martijn is feeding himself at Tilburg cave.
Martijn is writing code at Tilburg cave!
Now, Martijn goes to the office. You will only get subscriptions
registered for office:
>>> office = Office('Grok corp(r)(tm) headquarters')
>>> office_subscriptions = grok.queryMultiSubscriptions(
... (office, martijn), IActivity)
>>> office_subscriptions
[]
>>> _ = map(lambda s: s.do(), office_subscriptions)
Martijn is sleeping at Grok corp(r)(tm) headquarters.
"""
import grokcore.component as grok
from zope import interface
class Office(grok.Context):
def __init__(self, name):
self.name = name
# All caves are a kind of office.
class Cave(Office):
pass
class Mammoth(grok.Context):
def __init__(self, name):
self.name = name
class IActivity(interface.Interface):
def do():
"""Do something.
"""
class Sleep(grok.MultiSubscription):
grok.implements(IActivity)
grok.adapts(Office, Mammoth)
def __init__(self, where, who):
self.where = where
self.who = who
def do(self):
print '%s is sleeping at %s.' % (self.who.name, self.where.name)
class DayTimeActivity(grok.MultiSubscription):
grok.implements(IActivity)
grok.adapts(Cave, Mammoth)
grok.baseclass()
def __init__(self, where, who):
self.where = where
self.who = who
def do(self):
print 'nothing'
class Food(DayTimeActivity):
def do(self):
print '%s is feeding himself at %s.' % (self.who.name, self.where.name)
class WritingCode(DayTimeActivity):
def do(self):
print '%s is writing code at %s!' % (self.who.name, self.where.name)
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/subscriptions_no_interface.py 0000664 0001750 0001750 00000000603 11750014416 032730 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
must implement at least one interface (use grok.implements to specify).
"""
import grokcore.component as grok
class Cave(grok.Context):
pass
class CaveProcessor(grok.Subscription):
pass
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/__init__.py 0000664 0001750 0001750 00000000024 11750014416 027041 0 ustar jw jw 0000000 0000000 # this is a package
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/ordered_subscriptions.py 0000664 0001750 0001750 00000003504 11750014416 031723 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> cave = Cave()
You can query the subscriptions and sort them with the information
provided by grok.order:
>>> ordered_subscriptions = grok.queryOrderedSubscriptions(cave, ICleaner)
>>> ordered_subscriptions
[,
,
]
>>> _ = map(lambda s: s.work(), ordered_subscriptions)
Monday cleaning!
Wednesday cleaning!
Saturday cleaning!
If you use the regular query method, they won't be sorted:
>>> subscriptions = grok.querySubscriptions(cave, ICleaner)
>>> subscriptions
[,
,
]
>>> _ = map(lambda s: s.work(), subscriptions)
Monday cleaning!
Saturday cleaning!
Wednesday cleaning!
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class ICleaner(interface.Interface):
def work():
"""Clean that cave.
"""
class MondayCleaner(grok.Subscription):
grok.implements(ICleaner)
grok.order(1)
def work(self):
print 'Monday cleaning!'
class WednesdayCleaner(grok.Subscription):
grok.implements(ICleaner)
grok.order(3)
def work(self):
print 'Wednesday cleaning!'
class SaturdayCleaner(grok.Subscription):
grok.implements(ICleaner)
grok.order(6)
def work(self):
print 'Saturday cleaning!'
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/subscriptions_no_context.py 0000664 0001750 0001750 00000000705 11750014416 032457 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: No module-level context for
,
please use the 'context' directive.
"""
import grokcore.component as grok
from zope import interface
class ITask(interface.Interface):
def finish():
pass
class CaveProcessor(grok.Subscription):
grok.provides(ITask)
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/decorator.py 0000664 0001750 0001750 00000001435 11750014416 027273 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> cave = Cave('sweet home')
>>> subscriptions = grok.querySubscriptions(cave, IActivity)
>>> subscriptions
[]
Subscription adapters are not registered as regular adapters:
>>> from zope import component
>>> component.queryAdapter(cave, IActivity)
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
def __init__(self, name):
self.name = name
class IActivity(interface.Interface):
pass
class DebuggingGrokcore(object):
def __init__(self, where):
self.where = where
@grok.subscribe(Cave)
@grok.implementer(IActivity)
def debugging(content):
return DebuggingGrokcore(content)
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/subscriptions.py 0000664 0001750 0001750 00000002555 11750014416 030224 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> cave = Cave('sweet home')
>>> subscriptions = grok.querySubscriptions(cave, ICleaner)
>>> subscriptions
[,
,
]
>>> _ = map(lambda s: s.work(), subscriptions)
Monday cleaning sweet home!
Saturday cleaning sweet home!
Wednesday cleaning sweet home!
Subscription adapters are not registered as regular adapters:
>>> component.queryAdapter(cave, ICleaner)
"""
import grokcore.component as grok
from zope import interface, component
class Cave(grok.Context):
def __init__(self, name):
self.name = name
class ICleaner(interface.Interface):
def work():
"""Clean that cave.
"""
class MondayCleaner(grok.Subscription):
grok.implements(ICleaner)
def work(self):
print 'Monday cleaning %s!' % self.context.name
class WednesdayCleaner(grok.Subscription):
grok.provides(ICleaner)
def work(self):
print 'Wednesday cleaning %s!' % self.context.name
class SaturdayCleaner(grok.Subscription):
grok.implements(ICleaner)
def work(self):
print 'Saturday cleaning %s!' % self.context.name
grokcore.component-2.5/src/grokcore/component/tests/subscriptions/ordered_multisubscriptions.py 0000664 0001750 0001750 00000005060 11750014416 032775 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> cave = Cave('Tilburg cave')
>>> martijn = Mammoth('Martijn')
You can query a subscriptions using multiple components and sort them
using `grok.order` information:
>>> ordered_subscriptions = grok.queryOrderedMultiSubscriptions(
... (cave, martijn), IActivity)
>>> ordered_subscriptions
[,
,
]
>>> _ = map(lambda a: a.do(), ordered_subscriptions)
Martijn is cooking in Tilburg cave!
Martijn is growing pumpkins in Tilburg cave!
Martijn is cleaning the Tilburg cave.
Or choose not to:
>>> subscriptions = grok.queryMultiSubscriptions(
... (cave, martijn), IActivity)
(still need to sort them on class name in order to have a working doctest)
>>> subscriptions = sorted(subscriptions, key=lambda s: s.__class__.__name__)
>>> subscriptions
[,
,
]
>>> _ = map(lambda a: a.do(), subscriptions)
Martijn is cleaning the Tilburg cave.
Martijn is cooking in Tilburg cave!
Martijn is growing pumpkins in Tilburg cave!
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
def __init__(self, name):
self.name = name
class Mammoth(grok.Context):
def __init__(self, name):
self.name = name
class IActivity(interface.Interface):
def do():
"""Do something.
"""
class DayTimeActivity(grok.MultiSubscription):
grok.provides(IActivity)
grok.adapts(Cave, Mammoth)
grok.baseclass()
def __init__(self, where, who):
self.where = where
self.who = who
def do(self):
print 'Doing nothing.'
class Cleaning(DayTimeActivity):
grok.order(99)
def do(self):
print '%s is cleaning the %s.' % (self.who.name, self.where.name)
class Cooking(DayTimeActivity):
grok.order(10)
def do(self):
print '%s is cooking in %s!' % (self.who.name, self.where.name)
class Gardening(DayTimeActivity):
grok.order(15)
def do(self):
print '%s is growing pumpkins in %s!' % (self.who.name, self.where.name)
grokcore.component-2.5/src/grokcore/component/tests/view/ 0000775 0001750 0001750 00000000000 11750014424 022776 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/view/__init__.py 0000664 0001750 0001750 00000000024 11750014416 025104 0 ustar jw jw 0000000 0000000 # this is a package
grokcore.component-2.5/src/grokcore/component/tests/view/nomodulename.py 0000664 0001750 0001750 00000000346 11750014416 026037 0 ustar jw jw 0000000 0000000 """
You can't call grok.name on a module:
>>> import grokcore.component.tests.view.nomodulename_fixture
Traceback (most recent call last):
...
GrokImportError: The 'name' directive can only be used on class level.
"""
grokcore.component-2.5/src/grokcore/component/tests/view/nomodulename_fixture.py 0000664 0001750 0001750 00000000122 11750014416 027575 0 ustar jw jw 0000000 0000000 """
This should fail:
"""
import grokcore.component as grok
grok.name('viewname')
grokcore.component-2.5/src/grokcore/component/tests/adapter/ 0000775 0001750 0001750 00000000000 11750014424 023444 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/adapter/order.py 0000664 0001750 0001750 00000000666 11750014416 025142 0 ustar jw jw 0000000 0000000 """
If the model is defined after the adapter, it should still be grokked
properly:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
class Cave(grok.Context):
pass
grokcore.component-2.5/src/grokcore/component/tests/adapter/providerdecorator.py 0000664 0001750 0001750 00000001261 11750014416 027554 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> IMarker.providedBy(not_marked)
False
>>> IMarker.providedBy(marked)
True
>>> IMarker.providedBy(double_marked)
True
>>> IMarker2.providedBy(not_marked)
False
>>> IMarker2.providedBy(marked)
False
>>> IMarker2.providedBy(double_marked)
True
>>> marked()
123
>>> double_marked()
234
"""
import grokcore.component as grok
from zope import interface
class IMarker(interface.Interface):
pass
class IMarker2(interface.Interface):
pass
@grok.provider(IMarker)
def marked():
return 123
@grok.provider(IMarker, IMarker2)
def double_marked():
return 234
def not_marked():
return 456 grokcore.component-2.5/src/grokcore/component/tests/adapter/multiple.py 0000664 0001750 0001750 00000000761 11750014416 025656 0 ustar jw jw 0000000 0000000 """
Multiple models lead to ambiguity:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: Multiple possible contexts for
, please use the
'context' directive.
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class Club(grok.Context):
pass
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grokcore.component-2.5/src/grokcore/component/tests/adapter/nomodel.py 0000664 0001750 0001750 00000000673 11750014416 025462 0 ustar jw jw 0000000 0000000 """
If no model can be found in the module, we get an error:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: No module-level context for
, please use the
'context' directive.
"""
import grokcore.component as grok
from zope import interface
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grokcore.component-2.5/src/grokcore/component/tests/adapter/implementsnonemulti.py 0000664 0001750 0001750 00000000671 11750014416 030133 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.Adapter and grok.MultiAdapter must implement exactly one
interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: must
implement at least one interface (use grok.implements to specify).
"""
import grokcore.component as grok
class Cave(grok.Context):
pass
class Home(grok.MultiAdapter):
pass
grokcore.component-2.5/src/grokcore/component/tests/adapter/adapterdecorator.py 0000664 0001750 0001750 00000003530 11750014416 027343 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>>
>>> cave = Cave()
>>> home = IHome(cave)
>>> home.id
u'default'
>>> IHome.providedBy(home)
True
>>>
>>> isinstance(home, Home)
True
>>> morehome = IMoreHome(cave)
>>> morehome.id
u'default'
>>> IHome.providedBy(morehome)
True
>>> isinstance(morehome, Home)
True
>>> yetanotherhome = IYetAnotherHome(cave)
>>> IHome.providedBy(yetanotherhome)
True
>>> isinstance(yetanotherhome, Home)
True
>>> yetanotherhome.id
u'default'
>>> from grokcore.component.tests.adapter import noarguments_fixture
Traceback (most recent call last):
...
GrokImportError: @grok.adapter requires at least one argument.
>>> from grokcore.component.tests.adapter import functionasargument_fixture
Traceback (most recent call last):
...
GrokImportError: @grok.adapter requires at least one argument.
>>> from zope.component import getAdapter
>>> home = getAdapter(cave, IHome, name='home')
>>> home.id
u'secondary'
"""
import grokcore.component as grok
from zope import interface
class IDummy(interface.Interface):
pass
class ICave(interface.Interface):
pass
class IHome(interface.Interface):
pass
class IMoreHome(interface.Interface):
pass
class IYetAnotherHome(interface.Interface):
pass
class Cave(grok.Context):
grok.implements(ICave)
pass
class Home(object):
grok.implements(IHome)
def __init__(self, id=u"default"):
self.id = id
@grok.adapter(Cave)
@grok.implementer(IHome)
def home_for_cave(cave):
return Home()
@grok.adapter(ICave)
@grok.implementer(IMoreHome)
def more_home_for_cave(cave):
return Home()
@grok.implementer(IYetAnotherHome)
def yet_another_home_for_cave(cave):
return Home()
@grok.adapter(Cave, name=u"home")
@grok.implementer(IHome)
def home_for_cave_named(cave):
return Home(u"secondary") grokcore.component-2.5/src/grokcore/component/tests/adapter/__init__.py 0000664 0001750 0001750 00000000024 11750014416 025552 0 ustar jw jw 0000000 0000000 # this is a package
grokcore.component-2.5/src/grokcore/component/tests/adapter/multiadaptsnone.py 0000664 0001750 0001750 00000000754 11750014416 027234 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.MultiAdapter must declare what they adapt, using grok.adapts:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError:
must specify which contexts it adapts (use the 'adapts' directive to specify).
"""
import grokcore.component as grok
from zope import interface
class IHome(interface.Interface):
pass
class Home(grok.MultiAdapter):
grok.implements(IHome)
grokcore.component-2.5/src/grokcore/component/tests/adapter/functioncontext.py 0000664 0001750 0001750 00000001455 11750014416 027256 0 ustar jw jw 0000000 0000000 """
You can't call grok.context from a function:
>>> func()
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be used on class or
module level.
You can't call grok.context from a method either:
>>> SomeClass().meth()
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be used on class or
module level.
"""
import grokcore.component as grok
from grokcore.component.tests.adapter.adapter import Cave
def func():
"""We don't allow calling `grok.context` from anything else than a
module or a class"""
grok.context(Cave)
class SomeClass(object):
def meth(self):
"""We don't allow calling `grok.context` from anything else
than a module or a class"""
grok.context(Cave)
grokcore.component-2.5/src/grokcore/component/tests/adapter/classorinterface.py 0000664 0001750 0001750 00000002214 11750014416 027345 0 ustar jw jw 0000000 0000000 """
You can only use `grok.context` with interfaces or classes and not
with anything else:
>>> function_context()
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be called with a class or an interface.
>>> string_context()
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be called with a class or an interface.
>>> module_context()
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be called with a class or an interface.
>>> instance_context()
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be called with a class or an interface.
"""
import grokcore.component as grok
def function_context():
def a():
pass
class FunctionContext(object):
grok.context(a)
def string_context():
class StringContext(object):
grok.context('string')
def module_context():
class ModuleContext(object):
grok.context(grok)
def instance_context():
obj = object()
class InstanceContext(object):
grok.context(obj)
grokcore.component-2.5/src/grokcore/component/tests/adapter/multiadapter.py 0000664 0001750 0001750 00000003656 11750014416 026524 0 ustar jw jw 0000000 0000000 """
Multi-Adapters are supported by subclassing grok.MultiAdapter, giving
multiple arguments to grok.adapts, and supplying a matching
__init__():
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> fireplace = Fireplace()
>>> from zope import component
>>> home = component.getMultiAdapter((cave, fireplace))
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
>>> home.cave is cave
True
>>> home.fireplace is fireplace
True
This also works for named adapters using grok.name:
>>> home = component.getMultiAdapter((cave, fireplace), name='home2')
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home2)
True
>>> home.cave is cave
True
>>> home.fireplace is fireplace
True
Multiadapters that implement more than one interface can use grok.provides to
specify the one to use:
>>> home = component.getMultiAdapter((cave, fireplace), name='home3')
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home3)
True
>>> home.cave is cave
True
>>> home.fireplace is fireplace
True
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class Fireplace(grok.Context):
pass
class IHome(interface.Interface):
pass
class Home(grok.MultiAdapter):
grok.adapts(Cave, Fireplace)
grok.implements(IHome)
def __init__(self, cave, fireplace):
self.cave = cave
self.fireplace = fireplace
class Home2(grok.MultiAdapter):
grok.adapts(Cave, Fireplace)
grok.implements(IHome)
grok.name('home2')
def __init__(self, cave, fireplace):
self.cave = cave
self.fireplace = fireplace
class IFireplace(interface.Interface):
pass
class Home3(grok.MultiAdapter):
grok.adapts(Cave, Fireplace)
grok.implements(IHome, IFireplace)
grok.provides(IHome)
grok.name('home3')
def __init__(self, cave, fireplace):
self.cave = cave
self.fireplace = fireplace
grokcore.component-2.5/src/grokcore/component/tests/adapter/modulecontextmultiple_fixture.py 0000664 0001750 0001750 00000000254 11750014416 032234 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class Club(grok.Context):
pass
grok.context(Cave)
grok.context(Club)
grokcore.component-2.5/src/grokcore/component/tests/adapter/implementsnone.py 0000664 0001750 0001750 00000000657 11750014416 027064 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.Adapter and grok.MultiAdapter must implement exactly one
interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: must
implement at least one interface (use grok.implements to specify).
"""
import grokcore.component as grok
class Cave(grok.Context):
pass
class Home(grok.Adapter):
pass
grokcore.component-2.5/src/grokcore/component/tests/adapter/classcontext.py 0000664 0001750 0001750 00000000732 11750014416 026533 0 ustar jw jw 0000000 0000000 """
Explicit class-level context in case of multiple models:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class Club(grok.Context):
pass
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grok.context(Cave)
grokcore.component-2.5/src/grokcore/component/tests/adapter/adapter.py 0000664 0001750 0001750 00000001173 11750014416 025441 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
>>> fireplace = IFireplace(cave)
>>> IFireplace.providedBy(fireplace)
True
>>> isinstance(fireplace, Fireplace)
True
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
class IFireplace(interface.Interface):
pass
class Fireplace(grok.Adapter):
grok.implements(IFireplace, IHome)
grok.provides(IFireplace)
grokcore.component-2.5/src/grokcore/component/tests/adapter/importedmodel.py 0000664 0001750 0001750 00000000775 11750014416 026674 0 ustar jw jw 0000000 0000000 """
Imported model and adapter won't be grokked:
>>> import grokcore.component as grok
>>> grok.testing.grok(__name__)
>>> from grokcore.component.tests.adapter.adapter import IHome
>>> cave = Cave()
>>> home = IHome(cave)
Traceback (most recent call last):
...
TypeError: ('Could not adapt', , )
"""
from grokcore.component.tests.adapter.adapter import Cave, Home
grokcore.component-2.5/src/grokcore/component/tests/adapter/interfacemodule.py 0000664 0001750 0001750 00000001275 11750014416 027172 0 ustar jw jw 0000000 0000000 """
You can also specify interfaces instead of classes with
`grok.context` (module-level):
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
>>> hole = Hole()
>>> home = IHome(hole)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class ICave(interface.Interface):
pass
class Cave(grok.Context):
grok.implements(ICave)
class Hole(grok.Context):
grok.implements(ICave)
grok.context(ICave)
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grokcore.component-2.5/src/grokcore/component/tests/adapter/namedadapter.py 0000664 0001750 0001750 00000001351 11750014416 026444 0 ustar jw jw 0000000 0000000 """
You can register a named adapter by using grok.name:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
Traceback (most recent call last):
...
TypeError: ('Could not adapt', , )
>>> from zope.component import getAdapter
>>> home = getAdapter(cave, IHome, name='home')
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grok.name('home')
grokcore.component-2.5/src/grokcore/component/tests/adapter/classcontextmultiple_fixture.py 0000664 0001750 0001750 00000000261 11750014416 032052 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
class Cave(grok.Context):
pass
class Club(grok.Context):
pass
class Anything(object):
grok.context(Cave)
grok.context(Club)
grokcore.component-2.5/src/grokcore/component/tests/adapter/oldstyleclass.py 0000664 0001750 0001750 00000000624 11750014416 026706 0 ustar jw jw 0000000 0000000 """
Old-style classes are also supported:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class Cave:
pass
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grok.context(Cave)
grokcore.component-2.5/src/grokcore/component/tests/adapter/globaladapter.py 0000664 0001750 0001750 00000006521 11750014416 026624 0 ustar jw jw 0000000 0000000 """
>>> grok.testing.grok(__name__)
>>> from zope.component import getAdapter, getMultiAdapter
>>> cave = Cave()
>>> fireplace = Fireplace()
>>> home = IHome(cave)
>>> home.id
u'one'
>>> home = getAdapter(cave, IHome, name=u"two")
>>> home.id
u'two'
>>> home = getAdapter(cave, IHome, name=u"three")
>>> home.id
u'three'
>>> home = getAdapter(cave, IHome, name=u"four")
>>> home.id
u'four'
>>> home = getAdapter(fireplace, IHome, name=u"five")
>>> home.id
u'five'
>>> home = getMultiAdapter((cave, fireplace), IHome)
>>> home.id
u'six'
>>> home = getAdapter(fireplace, IHome, name=u'seven')
>>> home.id
u'seven-a'
>>> home = getMultiAdapter((cave, fireplace), IHome, name=u'seven')
>>> home.id
u'seven-b'
>>> garage = getAdapter(cave, IGarage, name='named_garage_factory_name')
>>> garage.id
u"I'm a garage"
>>> garage = getAdapter(cave, IGarage)
>>> garage.id
u"I'm a garage"
"""
import grokcore.component as grok
from zope import interface
from zope.interface import implementer
class Cave(grok.Context):
pass
class Fireplace(object):
pass
class IHome(interface.Interface):
pass
class Home(object):
grok.implements(IHome)
def __init__(self, id):
self.id = id
class CaveHomeFactory(object):
grok.implements(IHome)
def __init__(self, id):
self.id = id
def __call__(self, context):
return Home(self.id)
class CaveFireplaceHomeFactory(object):
def __init__(self, id):
self.id = id
def __call__(self, cave, fireplace):
return Home(self.id)
factory1 = CaveHomeFactory(u"one")
factory2 = CaveHomeFactory(u"two")
factory3 = CaveHomeFactory(u"three")
factory4 = CaveHomeFactory(u"four")
factory5 = CaveHomeFactory(u"five")
factory6 = CaveFireplaceHomeFactory(u"six")
factory7a = CaveHomeFactory(u"seven-a")
factory7b = CaveFireplaceHomeFactory(u"seven-b")
# make some direct assertions
implementer(IHome)(factory3)
implementer(IHome)(factory4)
implementer(IHome)(factory5)
implementer(IHome)(factory6)
implementer(IHome)(factory7a)
implementer(IHome)(factory7b)
grok.adapter(Fireplace)(factory5)
grok.adapter(Fireplace)(factory7a)
grok.adapter(Cave, Fireplace)(factory7b)
# should accept single value for adapts
grok.global_adapter(factory1, Cave, IHome)
# should accept tuple for adapts
grok.global_adapter(factory2, (Cave,), IHome, name=u"two")
# should look at the provided interface
grok.global_adapter(factory3, Cave, name=u"three")
# should pick the canonical context
grok.global_adapter(factory4, name=u"four")
# should use __component_adapts__
grok.global_adapter(factory5, name=u"five")
# should work as multi-adapter
grok.global_adapter(factory6, (Cave, Fireplace,))
# should use __component_adapts__ adapting one object
grok.global_adapter(factory7a, name=u"seven")
# should use __component_adapts__ adaping two objects
grok.global_adapter(factory7b, name=u"seven")
class IGarage(interface.Interface):
pass
class NamedGarageFactory(object):
grok.implements(IGarage)
grok.name('named_garage_factory_name')
def __init__(self, context):
self.id = u"I'm a garage"
implementer(IGarage)(NamedGarageFactory)
# should register a named adapter
grok.global_adapter(NamedGarageFactory, Cave, IGarage)
# should override component's name
grok.global_adapter(NamedGarageFactory, Cave, IGarage, name=u'')
grokcore.component-2.5/src/grokcore/component/tests/adapter/importedmodel2.py 0000664 0001750 0001750 00000001207 11750014416 026745 0 ustar jw jw 0000000 0000000 """
Grok error because import model doesn't count as context:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: No module-level context for
,
please use the 'context' directive.
"""
import grokcore.component as grok
from grokcore.component.tests.adapter.adapter import Cave
from zope import interface
class IPainting(interface.Interface):
pass
class Painting(grok.Adapter):
"""
Grokking of this should fail because there's no model (only an
imported one which doesn't count).
"""
grok.implements(IPainting)
grokcore.component-2.5/src/grokcore/component/tests/adapter/conflict.py 0000664 0001750 0001750 00000002147 11750014416 025624 0 ustar jw jw 0000000 0000000 """
Registering two adapters for the same target interface should provoke
a conflict, even if the interface is guessed (instead of being
explicitly declared with grok.provides):
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
ConfigurationConflictError: Conflicting configuration actions
For: ('adapter', , , u'')
"""
import grokcore.component as grok
from zope.interface import Interface
class ICave(Interface):
pass
class IDecoration(Interface):
pass
class ICaveCleaning(Interface):
pass
class Cave(object):
grok.implements(ICave)
class ImplicitProvides(grok.Adapter):
"""Here the provided interface is guessed because the class only
implements one interface."""
grok.context(ICave)
grok.implements(IDecoration)
class ExplicitProvides(grok.Adapter):
"""Here the provided interface is specific explicitly."""
grok.context(ICave)
grok.implements(IDecoration, ICaveCleaning)
grok.provides(IDecoration)
grokcore.component-2.5/src/grokcore/component/tests/adapter/interface.py 0000664 0001750 0001750 00000001277 11750014416 025766 0 ustar jw jw 0000000 0000000 """
You can also specify interfaces instead of classes with
`grok.context` (class-level):
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
>>> hole = Hole()
>>> home = IHome(hole)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class ICave(interface.Interface):
pass
class Cave(grok.Context):
grok.implements(ICave)
class Hole(grok.Context):
grok.implements(ICave)
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grok.context(ICave)
grokcore.component-2.5/src/grokcore/component/tests/adapter/functionasargument_fixture.py 0000664 0001750 0001750 00000000322 11750014416 031476 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
from zope import interface
class IDummy(interface.Interface):
pass
@grok.adapter
@grok.implementer(IDummy)
def decorator_called_with_function_as_argument(cave):
pass
grokcore.component-2.5/src/grokcore/component/tests/adapter/classcontextimported.py 0000664 0001750 0001750 00000000753 11750014416 030302 0 ustar jw jw 0000000 0000000 """
Explicit class-level context for an imported model:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> painting = IPainting(cave)
>>> IPainting.providedBy(painting)
True
>>> isinstance(painting, Painting)
True
"""
import grokcore.component as grok
from grokcore.component.tests.adapter.adapter import Cave
from zope import interface
class IPainting(interface.Interface):
pass
class Painting(grok.Adapter):
grok.implements(IPainting)
grok.context(Cave)
grokcore.component-2.5/src/grokcore/component/tests/adapter/modulecontext.py 0000664 0001750 0001750 00000000730 11750014416 026711 0 ustar jw jw 0000000 0000000 """
Explicit module-level context in case of multiple models:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class Club(grok.Context):
pass
grok.context(Cave)
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grokcore.component-2.5/src/grokcore/component/tests/adapter/implementsmany.py 0000664 0001750 0001750 00000001127 11750014416 027062 0 ustar jw jw 0000000 0000000 """
Subclasses of grok.Adapter and grok.MultiAdapter must implement exactly one
interface:
>>> grok.testing.grok(__name__)
Traceback (most recent call last):
...
GrokError: is implementing
more than one interface (use grok.provides to specify which one to use).
"""
import grokcore.component as grok
from zope import interface
class Cave(grok.Context):
pass
class IHome(interface.Interface):
pass
class IFireplace(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome, IFireplace)
grokcore.component-2.5/src/grokcore/component/tests/adapter/modulecontextimported.py 0000664 0001750 0001750 00000000751 11750014416 030460 0 ustar jw jw 0000000 0000000 """
Explicit module-level context for an imported model:
>>> grok.testing.grok(__name__)
>>> cave = Cave()
>>> painting = IPainting(cave)
>>> IPainting.providedBy(painting)
True
>>> isinstance(painting, Painting)
True
"""
import grokcore.component as grok
from grokcore.component.tests.adapter.adapter import Cave
from zope import interface
grok.context(Cave)
class IPainting(interface.Interface):
pass
class Painting(grok.Adapter):
grok.implements(IPainting)
grokcore.component-2.5/src/grokcore/component/tests/adapter/modulecontextmultiple.py 0000664 0001750 0001750 00000000431 11750014416 030463 0 ustar jw jw 0000000 0000000 """
You can't call grok.context multiple times on module level:
>>> import grokcore.component.tests.adapter.modulecontextmultiple_fixture
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be called once per
class or module.
"""
grokcore.component-2.5/src/grokcore/component/tests/adapter/classcontextmultiple.py 0000664 0001750 0001750 00000000430 11750014416 030302 0 ustar jw jw 0000000 0000000 """
You can't call grok.context multiple times on class level:
>>> import grokcore.component.tests.adapter.classcontextmultiple_fixture
Traceback (most recent call last):
...
GrokImportError: The 'context' directive can only be called once per
class or module.
"""
grokcore.component-2.5/src/grokcore/component/tests/adapter/noarguments_fixture.py 0000664 0001750 0001750 00000000314 11750014416 030125 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
from zope import interface
class IDummy(interface.Interface):
pass
@grok.adapter()
@grok.implementer(IDummy)
def decorator_called_with_no_arguments(cave):
pass
grokcore.component-2.5/src/grokcore/component/tests/adapter/alphabetical.py 0000664 0001750 0001750 00000000766 11750014416 026441 0 ustar jw jw 0000000 0000000 """
Grok does not depend on the alphabetical order:
>>> grok.testing.grok(__name__)
>>> cave = ZCave()
>>> home = IHome(cave)
>>> IHome.providedBy(home)
True
>>> isinstance(home, Home)
True
"""
import grokcore.component as grok
from zope import interface
class ZCave(grok.Context):
"""we call this `ZCave` because we want to test that we do not
depend on alphabetical order"""
class IHome(interface.Interface):
pass
class Home(grok.Adapter):
grok.implements(IHome)
grokcore.component-2.5/src/grokcore/component/tests/test_grok.py 0000664 0001750 0001750 00000004433 11750014416 024404 0 ustar jw jw 0000000 0000000 import re
import unittest
import traceback
import doctest
from pkg_resources import resource_listdir
from zope.testing import cleanup, renormalizing
import zope.component.eventtesting
def setUpZope(test):
zope.component.eventtesting.setUp(test)
def cleanUpZope(test):
cleanup.cleanUp()
checker = renormalizing.RENormalizing([
# str(Exception) has changed from Python 2.4 to 2.5 (due to
# Exception now being a new-style class). This changes the way
# exceptions appear in traceback printouts.
(re.compile(r"ConfigurationExecutionError: :"),
r'ConfigurationExecutionError: \1:'),
])
def suiteFromPackage(name):
files = resource_listdir(__name__, name)
suite = unittest.TestSuite()
for filename in files:
if not filename.endswith('.py'):
continue
if filename.endswith('_fixture.py'):
continue
if filename == '__init__.py':
continue
dottedname = 'grokcore.component.tests.%s.%s' % (name, filename[:-3])
try:
test = doctest.DocTestSuite(dottedname,
setUp=setUpZope,
tearDown=cleanUpZope,
checker=checker,
optionflags=doctest.ELLIPSIS+
doctest.NORMALIZE_WHITESPACE)
except ImportError: # or should this accept anything?
traceback.print_exc()
raise
suite.addTest(test)
return suite
def test_suite():
suite = unittest.TestSuite()
for name in ['adapter', 'directive', 'grokker', 'utility', 'view',
'event', 'inherit', 'order', 'subscriptions']:
suite.addTest(suiteFromPackage(name))
api = doctest.DocFileSuite('api.txt')
suite.addTest(api)
# this test cannot follow the normal testing pattern, as the
# bug it tests for is only exposed in the context of a doctest
grok_component = doctest.DocFileSuite('grok_component.txt',
setUp=setUpZope,
tearDown=cleanUpZope)
suite.addTest(grok_component)
return suite
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
grokcore.component-2.5/src/grokcore/component/tests/inherit/ 0000775 0001750 0001750 00000000000 11750014424 023466 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/inherit/__init__.py 0000664 0001750 0001750 00000000002 11750014416 025570 0 ustar jw jw 0000000 0000000 #
grokcore.component-2.5/src/grokcore/component/tests/inherit/inherit_fixture.py 0000664 0001750 0001750 00000000414 11750014416 027250 0 ustar jw jw 0000000 0000000 import grokcore.component
from zope.interface import Interface
class Foo(grokcore.component.Context):
pass
grokcore.component.context(Foo)
class IAnder(Interface):
pass
class FooAdapter(grokcore.component.Adapter):
grokcore.component.provides(IAnder)
grokcore.component-2.5/src/grokcore/component/tests/inherit/inherit.py 0000664 0001750 0001750 00000001313 11750014416 025501 0 ustar jw jw 0000000 0000000 """
We expect the module-level grok.context to be inherited by subclasses of
an adapter that is associated with this directive. FooAdapter is such
an adapter, defined in inherit_fixture. In this module we've inherited
from it.
Explicit module-level context for an imported model:
>>> grok.testing.grok(__name__)
>>> from zope import component
>>> o = component.getAdapter(inherit_fixture.Foo(), inherit_fixture.IAnder,
... name='bar')
>>> isinstance(o, BarAdapter)
True
"""
import grokcore.component as grok
from grokcore.component.tests.inherit import inherit_fixture
# FooAdapter has a module-level grok.context to associate it
class BarAdapter(inherit_fixture.FooAdapter):
grok.name('bar')
grokcore.component-2.5/src/grokcore/component/tests/event/ 0000775 0001750 0001750 00000000000 11750014424 023145 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore/component/tests/event/__init__.py 0000664 0001750 0001750 00000000024 11750014416 025253 0 ustar jw jw 0000000 0000000 # this is a package
grokcore.component-2.5/src/grokcore/component/tests/event/errorconditions_fixture.py 0000664 0001750 0001750 00000000120 11750014416 030502 0 ustar jw jw 0000000 0000000 import grokcore.component as grok
@grok.subscribe()
def subscriber():
pass
grokcore.component-2.5/src/grokcore/component/tests/event/errorconditions.py 0000664 0001750 0001750 00000001621 11750014416 026743 0 ustar jw jw 0000000 0000000 """
@grok.subscribe can only be used on module level:
>>> function_context()
Traceback (most recent call last):
...
GrokImportError: @grok.subscribe can only be used on module level.
>>> class_context()
Traceback (most recent call last):
...
GrokImportError: @grok.subscribe can only be used on module level.
@grok.subscribe can not be called without arguments:
>>> import grokcore.component.tests.event.errorconditions_fixture
Traceback (most recent call last):
...
GrokImportError: @grok.subscribe requires at least one argument.
"""
import grokcore.component as grok
from zope.component.interfaces import IObjectEvent
def function_context():
@grok.subscribe(grok.Context, IObjectEvent)
def subscriber():
pass
def class_context():
class Wrapper:
@grok.subscribe(grok.Context, IObjectEvent)
def subscriber(self):
pass
grokcore.component-2.5/src/grokcore/component/tests/event/provideHandler.py 0000664 0001750 0001750 00000001421 11750014416 026464 0 ustar jw jw 0000000 0000000 """
When you use the @grokcore.component.subscribe decorator, you can also
use zope.component.provideHandler to register the subscriber. This
can be useful for unittests where you may not want to grok everything
in a module but just enable certain components.
>>> from zope.component import provideHandler
>>> provideHandler(mammothAdded)
>>> manfred = Mammoth('Manfred')
>>> import zope.event
>>> zope.event.notify(ObjectEvent(manfred))
>>> mammoths
['Manfred']
"""
import grokcore.component as grok
from zope.component.interfaces import IObjectEvent, ObjectEvent
class Mammoth(object):
def __init__(self, name):
self.name = name
mammoths = []
@grok.subscribe(Mammoth, IObjectEvent)
def mammothAdded(mammoth, event):
mammoths.append(mammoth.name)
grokcore.component-2.5/src/grokcore/component/tests/event/subscriber.py 0000664 0001750 0001750 00000001514 11750014416 025664 0 ustar jw jw 0000000 0000000 """
You can subscribe to events using the @grok.subscribe decorator:
>>> grok.testing.grok(__name__)
>>> manfred = Mammoth('Manfred')
>>> zope.event.notify(ObjectEvent(manfred))
>>> mammoths
['Manfred']
>>> mammoths2
['Manfred']
The decorated event handling function can also be called directly:
>>> mammothAdded(Mammoth('Max'),None)
>>> mammoths
['Manfred', 'Max']
"""
import zope.event
import grokcore.component as grok
from zope.component.interfaces import IObjectEvent, ObjectEvent
class Mammoth(object):
def __init__(self, name):
self.name = name
mammoths = []
mammoths2 = []
@grok.subscribe(Mammoth, IObjectEvent)
def mammothAdded(mammoth, event):
mammoths.append(mammoth.name)
@grok.subscribe(Mammoth, IObjectEvent)
def mammothAddedInstance(mammoth, event):
mammoths2.append(mammoth.name)
grokcore.component-2.5/src/grokcore/__init__.py 0000664 0001750 0001750 00000000310 11750014416 020764 0 ustar jw jw 0000000 0000000 # this is a namespace package
try:
import pkg_resources
pkg_resources.declare_namespace(__name__)
except ImportError:
import pkgutil
__path__ = pkgutil.extend_path(__path__, __name__)
grokcore.component-2.5/src/grokcore.component.egg-info/ 0000775 0001750 0001750 00000000000 11750014424 022353 5 ustar jw jw 0000000 0000000 grokcore.component-2.5/src/grokcore.component.egg-info/PKG-INFO 0000664 0001750 0001750 00000046017 11750014421 023455 0 ustar jw jw 0000000 0000000 Metadata-Version: 1.0
Name: grokcore.component
Version: 2.5
Summary: Grok-like configuration for basic components (adapters, utilities, subscribers)
Home-page: http://grok.zope.org
Author: Grok Team
Author-email: grok-dev@zope.org
License: ZPL
Download-URL: http://pypi.python.org/pypi/grokcore.component
Description: This package provides base classes of basic component types for the
Zope Component Architecture, as well as means for configuring and
registering them directly in Python (without ZCML).
.. contents::
How to set up ``grokcore.component``
====================================
In the following we assume you're writing or extending an application
that does bootstrap configuration using ZCML. There's always a single
ZCML file that is executed when the application is started, which then
includes everything else. Let's assume this file is called
``site.zcml`` (that's what it's called in Zope), so that file is what
we'll be editing.
In order to register the components that you wrote using the base
classes and directives available from ``grokcore.component``, we'll
use the ```` ZCML directive. But before we can use it,
we need to make sure it's available to the ZCML machinery. We do this
by including the meta configuration from ``grokcore.component``::
Put this line somewhere to the top of ``site.zcml``, next to other
meta configuration includes. Now, further down the line, we can tell
the machinery in ``grokcore.component`` to register all components in
your package (let's say it's called ``helloworld``)::
To sum up, your ``site.zcml`` file should look like something like this::
Examples
========
Adapter
-------
Here's a simple adapter that may be useful in Zope. It extracts the
languages that a user prefers from the request::
import grokcore.component
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.i18n.interfaces import IUserPreferredLanguages
class CookieLanguage(grokcore.component.Adapter):
"""Extract the preferred language from a cookie"""
grokcore.component.context(IBrowserRequest)
grokcore.component.implements(IUserPreferredLanguages)
# No need to implement __init__, it's already provided by the base class.
def getPreferredLanguages(self):
# This an adapter for the request, so self.context is the request.
request = self.context
# Extract the preferred language from a cookie:
lang = request.cookies.get('language', 'en')
# According to IUserPreferredLanguages, we must return a list.
return [lang]
Multi-adapter
-------------
Here's a multi-adapter that functions as a content provider as known
from the ``zope.contentprovider`` library. Content providers are
components that return snippets of HTML. They're multi-adapters for
the content object (model), the request and the view that they're
supposed to be a part of::
import grokcore.component
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IBrowserPage
from zope.contentprovider.interfaces import IContentProvider
class HelloWorldProvider(grokcore.component.MultiAdapter):
"""Display Hello World!"""
grokcore.component.adapts(Interface, IBrowserRequest, IBrowserPage)
grokcore.component.implements(IContentProvider)
def __init__(self, context, request, view):
pass
def update(self):
pass
def render(self):
return u'Hello World!
'
Global utility
--------------
Here's a simple named utility, again from the Zope world. It's a
translation domain. In other words, it contains translations of user
messages and is invoked when the i18n machinery needs to translate
something::
import grokcore.component
from zope.i18n.interfaces import ITranslationDomain
class HelloWorldTranslationDomain(grokcore.component.GlobalUtility):
grokcore.component.implements(ITranslationDomain)
grokcore.component.name('helloworld')
domain = u'helloworld'
def translate(self, msgid, mapping=None, context=None,
target_language=None, default=None):
if target_language is None:
preferred = IUserPreferredLanguages(context)
target_language = preferred.getPreferredLanguages()[0]
translations = {'de': u'Hallo Welt',
'nl': u'Hallo Wereld'}
return translations.get(target_language, u'Hello World')
Of course, it's silly to implement your own translation domain utility
if there are already implementations available in ``zope.i18n`` (one
that reads translations from a GNU gettext message catalog and a
simple implementation for tests). Let's try to reuse that
implementation and register an instance::
import grokcore.component
from zope.i18n.interfaces import ITranslationDomain
from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
messages = {('de', u'Hello World'): u'Hallo Welt',
('nl', u'Hello World'): u'Hallo Wereld'}
helloworld_domain = SimpleTranslationDomain(u'helloworld', messages)
grokcore.component.global_utility(helloworld_domain,
provides=ITranslationDomain,
name='helloworld',
direct=True)
Global adapter
--------------
Sometimes, you may have an object that should be registered as an adapter
factory. It may have come from some other framework that configured that
adapter for you, say, or you may have a class that you instantiate many
times to get different variations on a particular adapter factory. In these
cases, subclassing grokcore.component.Adapter or MultiAdapter is not
possible. Instead, you can use the global_adapter() directive. Here is an
example drawing on the ``z3c.form`` library, which provides an adapter factory
factory for named widget attributes::
import zope.interface
import zope.schema
import grokcore.component
import z3c.form.widget import ComputedWidgetAttribute
class ISchema(Interface):
"""This schema will be used to power a z3c.form form"""
field = zope.schema.TextLine(title=u"Sample field")
...
label_override = z3c.form.widget.StaticWidgetAttribute(
u"Override label", field=ISchema['field'])
grokcore.component.global_adapter(label_override, name=u"label")
In the example above, the provided and adapted interfaces are deduced from the
object returned by the ``StaticWidgetAttribute`` factory. The full syntax
for global_adapter is::
global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
The factory must be a callable (the adapter factory). Adapted interfaces are
given as a tuple. You may use a single interface instead of a one-element
tuple for single adapters. The provided interface is given as shown. The name
defaults to u"" (an unnamed adapter).
Handling events
---------------
Here we see an event handler much like it occurs within Zope itself. It
subscribes to the modified event for all annotatable objects (in other words,
objects that can have metadata associated with them). When invoked, it updates
the Dublin Core 'Modified' property accordingly::
import datetime
import grokcore.component
from zope.annotation.interfaces import IAnnotatable
from zope.lifecycleevent.interfaces import IObjectModifiedEvent
from zope.dublincore.interfaces import IZopeDublinCore
@grokcore.component.subscribe(IAnnotatable, IObjectModifiedEvent)
def updateDublinCoreAfterModification(obj, event):
"""Updated the Dublin Core 'Modified' property when a modified
event is sent for an object."""
IZopeDublinCore(obj).modified = datetime.datetime.utcnow()
Subscriptions
-------------
Subscriptions look similar to Adapter, however, unlike regular adapters,
subscription adapters are used when we want all of the adapters that adapt an
object to a particular adapter.
Analogous to MultiAdapter, there is a MultiSubscription component that "adapts"
multiple objects.
Changes
=======
2.5 (2012-05-01)
----------------
- Introduce provideUtility, providerAdapter, provideSubscriptionAdapter,
provideHandler and provideInterface in grokcore.component. These by default
delegate the registration of components to the global site manager like
was done before, but provide the possibility for custom registries for the
grokked components.
- Fix the `global_adapter` to properly use information annotated by
``grok.adapter``, and using the IContext object if it was not
specified. (Fix Launchpad issue #960097).
- Add a ``key`` option to ``sort_components`` that behave like ``key``
options available on standard Python sort methods.
2.4 (2011-04-27)
----------------
- Fix the `global_adapter` directive implementation to accept an explicit
"empty" name for nameless adapter registrations (as it used to be that
providing an empty name in the registration would actually result in
registering a named adapter in case the factory has a `grok.name`).
2.3 (2011-02-14)
----------------
- Implement the generic (Multi)Subscriptions components.
2.2 (2010-11-03)
----------------
- The default values computation for the context directive and the provides
directive is now defined in the directives themselves. This means that where
the values for these directives is being retrieved, the "default_context"
function does not need to be passed along anymore for general cases.
Analogous to this, when getting values for the provides directive the
"default_provides" function does not need to be passed along in the general
case.
2.1 (2010-11-01)
----------------
* Made package comply to zope.org repository policy.
* Moved directives 'order' from grokcore.viewlet and 'path' from
grokcore.view to this very package.
* Tiny dependency adjustment: moved zope.event to test dependencies.
* Port from 1.x branch exclude parameter to the Grok ZCML directive.
* Port from 1.x branch the ignore of testing.py modules.
2.0 (2009-09-16)
----------------
* Use a newer version of Martian that has better support for
inheritance. This is demonstrated in ``tests/inherit``.
* The ``ContextGrokker`` and the ``scan.py`` module have gone away
thanks the newer Martian.
* Directive implementations (in their factory method) should *not*
bind directives. Directive binding cannot take place at import time,
but only at grok time. Binding directives during import time (when
directives are executed) can lead to change problems. (we noticed
this during our refactoring to use the new Martian).
* Use 1.0b1 versions.cfg in Grok's release info instead of a local
copy; a local copy for all grokcore packages is just too hard to
maintain.
1.7 (2009-06-01)
----------------
* Add missing provider, global_adapter, implementsOnly, classProvides() to
the module interface so that they are included in __all__
1.6 (2009-04-10)
----------------
* Add convenience imports for implementsOnly() and classProvides() class
declarations form zope.interface.
* Add support for registering global adapters at module level::
grok.global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
Only 'factory' is required. If only a single interface is adapted, the
second argument may be a single interface instead of a tuple. If the
component has declared adapted/provided interfaces, the second and third
arguments may be omitted.
* Add support for an @provider decorator to let a function directly provide
an interface::
@grok.provider(IFoo, IBar)
def some_function():
...
This is equivalent to doing alsoProvides(some_function, IFoo, IBar).
* Add support for named adapters with the @adapter decorator::
@grok.adapter(IAdaptedOne, IAdaptedTwo, name=u"foo")
def some_function(one, two):
...
1.5.1 (2008-07-28)
------------------
* The ``IGrokcoreComponentAPI`` interface was missing declarations for
the ``title`` and ``description`` directives.
1.5 (2008-07-22)
----------------
* Fix https://bugs.launchpad.net/grok/+bug/242353: grokcore.component
contains old-style test setup. There is no `register_all_tests`
method in grokcore.component.testing anymore. Use z3c.testsetup
instead.
* Allow functions that have been marked with @grok.subscribe also be
registered with ``zope.component.provideHandler()`` manually. This
is useful for unit tests where you may not want to grok a whole
module.
* Document grokcore.component's public API in an interface,
``IGrokcoreComponentAPI``. When you now do::
from grokcore.component import *
only the items documented in that interface will be imported into
your local namespace.
1.4 (2008-06-11)
----------------
* Ported class grokkers to make use of further improvements in Martian.
This requires Martian 0.10.
1.3 (2008-05-14)
----------------
* Ported class grokkers to make use of the new declarative way of
retrieving directive information from a class. This requires
Martian 0.9.6.
1.2.1 (2008-05-04)
------------------
* Upgrade to Martian 0.9.5, which has a slight change in the signature of
``scan_for_classes``.
* Remove an unnecessary import ``methods_from_class`` from
``grokcore.component.scan``.
1.2 (2008-05-04)
----------------
* Ported directives to Martian's new directive implementation. As a
result, nearly all helper functions that were available from
``grokcore.component.util`` have been removed. The functionality is
mostly available from the directives themselves now.
* The ``baseclass`` directive has been moved to Martian.
* The ``order`` directive and its helper functions have been moved
back to Grok, as it was of no general use, but very specific to
viewlets.
1.1 (2008-05-03)
----------------
* ``determine_module_component`` now looks for classes that implement
a certain interface (such as ``IContext``), instead of taking a list
of classes. If looking for ``IContext``, it still will find
``Context`` subclasses, as these were also made to implement
``IContext``.
* Move the ``public_methods_from_class`` helper function back to Grok,
it isn't used at all in ``grokcore.component``.
1.0.1 (2008-05-02)
------------------
* The grokkers for adapters and global utilities did not use the
correct value for the *provided* interface in the configuration
action discriminator. Because of this, uninformative and
potentially wrong conflict errors would occur, as well as no
conflict where a conflict should have occurred.
* The grokker for the ``global_utility()`` directive did immediate
registrations instead of generating configuration actions.
Therefore it did not provoke ``ConflictErrors`` for conflicting
registrations.
* Improved documentation
1.0 (2008-05-01)
----------------
* Created ``grokcore.component`` in March 2008 by factoring basic
component base classes and their directives and grokkers out of
Grok.
Platform: UNKNOWN
Classifier: Intended Audience :: Developers
Classifier: License :: OSI Approved :: Zope Public License
Classifier: Programming Language :: Python
grokcore.component-2.5/src/grokcore.component.egg-info/dependency_links.txt 0000664 0001750 0001750 00000000001 11750014421 026416 0 ustar jw jw 0000000 0000000
grokcore.component-2.5/src/grokcore.component.egg-info/SOURCES.txt 0000664 0001750 0001750 00000013741 11750014422 024243 0 ustar jw jw 0000000 0000000 CHANGES.txt
COPYRIGHT.txt
CREDITS.txt
INSTALL.txt
LICENSE.txt
README.txt
TODO.txt
bootstrap.py
buildout.cfg
setup.py
src/grokcore/__init__.py
src/grokcore.component.egg-info/PKG-INFO
src/grokcore.component.egg-info/SOURCES.txt
src/grokcore.component.egg-info/dependency_links.txt
src/grokcore.component.egg-info/namespace_packages.txt
src/grokcore.component.egg-info/not-zip-safe
src/grokcore.component.egg-info/requires.txt
src/grokcore.component.egg-info/top_level.txt
src/grokcore/component/__init__.py
src/grokcore/component/components.py
src/grokcore/component/decorators.py
src/grokcore/component/directive.py
src/grokcore/component/interfaces.py
src/grokcore/component/meta.py
src/grokcore/component/meta.zcml
src/grokcore/component/subscription.py
src/grokcore/component/testing.py
src/grokcore/component/util.py
src/grokcore/component/zcml.py
src/grokcore/component/templates/default_display_form.pt
src/grokcore/component/templates/default_edit_form.pt
src/grokcore/component/tests/__init__.py
src/grokcore/component/tests/api.txt
src/grokcore/component/tests/grok_component.txt
src/grokcore/component/tests/test_grok.py
src/grokcore/component/tests/adapter/__init__.py
src/grokcore/component/tests/adapter/adapter.py
src/grokcore/component/tests/adapter/adapterdecorator.py
src/grokcore/component/tests/adapter/alphabetical.py
src/grokcore/component/tests/adapter/classcontext.py
src/grokcore/component/tests/adapter/classcontextimported.py
src/grokcore/component/tests/adapter/classcontextmultiple.py
src/grokcore/component/tests/adapter/classcontextmultiple_fixture.py
src/grokcore/component/tests/adapter/classorinterface.py
src/grokcore/component/tests/adapter/conflict.py
src/grokcore/component/tests/adapter/functionasargument_fixture.py
src/grokcore/component/tests/adapter/functioncontext.py
src/grokcore/component/tests/adapter/globaladapter.py
src/grokcore/component/tests/adapter/implementsmany.py
src/grokcore/component/tests/adapter/implementsnone.py
src/grokcore/component/tests/adapter/implementsnonemulti.py
src/grokcore/component/tests/adapter/importedmodel.py
src/grokcore/component/tests/adapter/importedmodel2.py
src/grokcore/component/tests/adapter/interface.py
src/grokcore/component/tests/adapter/interfacemodule.py
src/grokcore/component/tests/adapter/modulecontext.py
src/grokcore/component/tests/adapter/modulecontextimported.py
src/grokcore/component/tests/adapter/modulecontextmultiple.py
src/grokcore/component/tests/adapter/modulecontextmultiple_fixture.py
src/grokcore/component/tests/adapter/multiadapter.py
src/grokcore/component/tests/adapter/multiadaptsnone.py
src/grokcore/component/tests/adapter/multiple.py
src/grokcore/component/tests/adapter/namedadapter.py
src/grokcore/component/tests/adapter/noarguments_fixture.py
src/grokcore/component/tests/adapter/nomodel.py
src/grokcore/component/tests/adapter/oldstyleclass.py
src/grokcore/component/tests/adapter/order.py
src/grokcore/component/tests/adapter/providerdecorator.py
src/grokcore/component/tests/directive/__init__.py
src/grokcore/component/tests/directive/argumenterror.py
src/grokcore/component/tests/directive/argumenterror_fixture.py
src/grokcore/component/tests/directive/multipletimes.py
src/grokcore/component/tests/event/__init__.py
src/grokcore/component/tests/event/errorconditions.py
src/grokcore/component/tests/event/errorconditions_fixture.py
src/grokcore/component/tests/event/provideHandler.py
src/grokcore/component/tests/event/subscriber.py
src/grokcore/component/tests/grokker/__init__.py
src/grokcore/component/tests/grokker/continue_scanning.py
src/grokcore/component/tests/grokker/continue_scanning_fixture.py
src/grokcore/component/tests/grokker/grokcomponent.py
src/grokcore/component/tests/grokker/onlyonce.py
src/grokcore/component/tests/grokker/priority.py
src/grokcore/component/tests/grokker/priority_fixture.py
src/grokcore/component/tests/grokker/onlyonce_fixture/__init__.py
src/grokcore/component/tests/grokker/onlyonce_fixture/_meta.py
src/grokcore/component/tests/grokker/onlyonce_fixture/component.py
src/grokcore/component/tests/grokker/onlyonce_fixture/implementation.py
src/grokcore/component/tests/inherit/__init__.py
src/grokcore/component/tests/inherit/inherit.py
src/grokcore/component/tests/inherit/inherit_fixture.py
src/grokcore/component/tests/order/__init__.py
src/grokcore/component/tests/order/arg_orderdirective.py
src/grokcore/component/tests/order/combined_orderdirective.py
src/grokcore/component/tests/order/combinednoorder_orderdirective.py
src/grokcore/component/tests/order/inter1.py
src/grokcore/component/tests/order/inter2.py
src/grokcore/component/tests/order/noarg_orderdirective.py
src/grokcore/component/tests/order/nodirective.py
src/grokcore/component/tests/subscriptions/__init__.py
src/grokcore/component/tests/subscriptions/decorator.py
src/grokcore/component/tests/subscriptions/multisubscriptions.py
src/grokcore/component/tests/subscriptions/multisubscriptions_no_adapts.py
src/grokcore/component/tests/subscriptions/multisubscriptions_no_interface.py
src/grokcore/component/tests/subscriptions/ordered_multisubscriptions.py
src/grokcore/component/tests/subscriptions/ordered_subscriptions.py
src/grokcore/component/tests/subscriptions/subscriptions.py
src/grokcore/component/tests/subscriptions/subscriptions_no_context.py
src/grokcore/component/tests/subscriptions/subscriptions_no_interface.py
src/grokcore/component/tests/utility/__init__.py
src/grokcore/component/tests/utility/conflict.py
src/grokcore/component/tests/utility/implementsmany.py
src/grokcore/component/tests/utility/implementsmany2.py
src/grokcore/component/tests/utility/implementsnone.py
src/grokcore/component/tests/utility/implementsnone2.py
src/grokcore/component/tests/utility/providesmany.py
src/grokcore/component/tests/utility/providesmany2.py
src/grokcore/component/tests/utility/providesnone.py
src/grokcore/component/tests/utility/providesnone2.py
src/grokcore/component/tests/utility/utility.py
src/grokcore/component/tests/view/__init__.py
src/grokcore/component/tests/view/nomodulename.py
src/grokcore/component/tests/view/nomodulename_fixture.py grokcore.component-2.5/src/grokcore.component.egg-info/top_level.txt 0000664 0001750 0001750 00000000011 11750014421 025072 0 ustar jw jw 0000000 0000000 grokcore
grokcore.component-2.5/src/grokcore.component.egg-info/requires.txt 0000664 0001750 0001750 00000000153 11750014421 024747 0 ustar jw jw 0000000 0000000 setuptools
martian >= 0.14
zope.component
zope.configuration
zope.interface
zope.testing
[test]
zope.event grokcore.component-2.5/src/grokcore.component.egg-info/not-zip-safe 0000664 0001750 0001750 00000000001 11750014416 024602 0 ustar jw jw 0000000 0000000
grokcore.component-2.5/src/grokcore.component.egg-info/namespace_packages.txt 0000664 0001750 0001750 00000000011 11750014421 026673 0 ustar jw jw 0000000 0000000 grokcore
grokcore.component-2.5/CHANGES.txt 0000664 0001750 0001750 00000015433 11750014416 016076 0 ustar jw jw 0000000 0000000 Changes
=======
2.5 (2012-05-01)
----------------
- Introduce provideUtility, providerAdapter, provideSubscriptionAdapter,
provideHandler and provideInterface in grokcore.component. These by default
delegate the registration of components to the global site manager like
was done before, but provide the possibility for custom registries for the
grokked components.
- Fix the `global_adapter` to properly use information annotated by
``grok.adapter``, and using the IContext object if it was not
specified. (Fix Launchpad issue #960097).
- Add a ``key`` option to ``sort_components`` that behave like ``key``
options available on standard Python sort methods.
2.4 (2011-04-27)
----------------
- Fix the `global_adapter` directive implementation to accept an explicit
"empty" name for nameless adapter registrations (as it used to be that
providing an empty name in the registration would actually result in
registering a named adapter in case the factory has a `grok.name`).
2.3 (2011-02-14)
----------------
- Implement the generic (Multi)Subscriptions components.
2.2 (2010-11-03)
----------------
- The default values computation for the context directive and the provides
directive is now defined in the directives themselves. This means that where
the values for these directives is being retrieved, the "default_context"
function does not need to be passed along anymore for general cases.
Analogous to this, when getting values for the provides directive the
"default_provides" function does not need to be passed along in the general
case.
2.1 (2010-11-01)
----------------
* Made package comply to zope.org repository policy.
* Moved directives 'order' from grokcore.viewlet and 'path' from
grokcore.view to this very package.
* Tiny dependency adjustment: moved zope.event to test dependencies.
* Port from 1.x branch exclude parameter to the Grok ZCML directive.
* Port from 1.x branch the ignore of testing.py modules.
2.0 (2009-09-16)
----------------
* Use a newer version of Martian that has better support for
inheritance. This is demonstrated in ``tests/inherit``.
* The ``ContextGrokker`` and the ``scan.py`` module have gone away
thanks the newer Martian.
* Directive implementations (in their factory method) should *not*
bind directives. Directive binding cannot take place at import time,
but only at grok time. Binding directives during import time (when
directives are executed) can lead to change problems. (we noticed
this during our refactoring to use the new Martian).
* Use 1.0b1 versions.cfg in Grok's release info instead of a local
copy; a local copy for all grokcore packages is just too hard to
maintain.
1.7 (2009-06-01)
----------------
* Add missing provider, global_adapter, implementsOnly, classProvides() to
the module interface so that they are included in __all__
1.6 (2009-04-10)
----------------
* Add convenience imports for implementsOnly() and classProvides() class
declarations form zope.interface.
* Add support for registering global adapters at module level::
grok.global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
Only 'factory' is required. If only a single interface is adapted, the
second argument may be a single interface instead of a tuple. If the
component has declared adapted/provided interfaces, the second and third
arguments may be omitted.
* Add support for an @provider decorator to let a function directly provide
an interface::
@grok.provider(IFoo, IBar)
def some_function():
...
This is equivalent to doing alsoProvides(some_function, IFoo, IBar).
* Add support for named adapters with the @adapter decorator::
@grok.adapter(IAdaptedOne, IAdaptedTwo, name=u"foo")
def some_function(one, two):
...
1.5.1 (2008-07-28)
------------------
* The ``IGrokcoreComponentAPI`` interface was missing declarations for
the ``title`` and ``description`` directives.
1.5 (2008-07-22)
----------------
* Fix https://bugs.launchpad.net/grok/+bug/242353: grokcore.component
contains old-style test setup. There is no `register_all_tests`
method in grokcore.component.testing anymore. Use z3c.testsetup
instead.
* Allow functions that have been marked with @grok.subscribe also be
registered with ``zope.component.provideHandler()`` manually. This
is useful for unit tests where you may not want to grok a whole
module.
* Document grokcore.component's public API in an interface,
``IGrokcoreComponentAPI``. When you now do::
from grokcore.component import *
only the items documented in that interface will be imported into
your local namespace.
1.4 (2008-06-11)
----------------
* Ported class grokkers to make use of further improvements in Martian.
This requires Martian 0.10.
1.3 (2008-05-14)
----------------
* Ported class grokkers to make use of the new declarative way of
retrieving directive information from a class. This requires
Martian 0.9.6.
1.2.1 (2008-05-04)
------------------
* Upgrade to Martian 0.9.5, which has a slight change in the signature of
``scan_for_classes``.
* Remove an unnecessary import ``methods_from_class`` from
``grokcore.component.scan``.
1.2 (2008-05-04)
----------------
* Ported directives to Martian's new directive implementation. As a
result, nearly all helper functions that were available from
``grokcore.component.util`` have been removed. The functionality is
mostly available from the directives themselves now.
* The ``baseclass`` directive has been moved to Martian.
* The ``order`` directive and its helper functions have been moved
back to Grok, as it was of no general use, but very specific to
viewlets.
1.1 (2008-05-03)
----------------
* ``determine_module_component`` now looks for classes that implement
a certain interface (such as ``IContext``), instead of taking a list
of classes. If looking for ``IContext``, it still will find
``Context`` subclasses, as these were also made to implement
``IContext``.
* Move the ``public_methods_from_class`` helper function back to Grok,
it isn't used at all in ``grokcore.component``.
1.0.1 (2008-05-02)
------------------
* The grokkers for adapters and global utilities did not use the
correct value for the *provided* interface in the configuration
action discriminator. Because of this, uninformative and
potentially wrong conflict errors would occur, as well as no
conflict where a conflict should have occurred.
* The grokker for the ``global_utility()`` directive did immediate
registrations instead of generating configuration actions.
Therefore it did not provoke ``ConflictErrors`` for conflicting
registrations.
* Improved documentation
1.0 (2008-05-01)
----------------
* Created ``grokcore.component`` in March 2008 by factoring basic
component base classes and their directives and grokkers out of
Grok.
grokcore.component-2.5/COPYRIGHT.txt 0000664 0001750 0001750 00000000040 11750014416 016362 0 ustar jw jw 0000000 0000000 Zope Foundation and Contributors grokcore.component-2.5/TODO.txt 0000664 0001750 0001750 00000000242 11750014416 015563 0 ustar jw jw 0000000 0000000 ====
TODO
====
- The testing infrastructure needs to be broken out into "grokcore.testing".
- The interfaces need to be broken out into "grokcore.interfaces".
grokcore.component-2.5/README.txt 0000664 0001750 0001750 00000020560 11750014416 015760 0 ustar jw jw 0000000 0000000 This package provides base classes of basic component types for the
Zope Component Architecture, as well as means for configuring and
registering them directly in Python (without ZCML).
.. contents::
How to set up ``grokcore.component``
====================================
In the following we assume you're writing or extending an application
that does bootstrap configuration using ZCML. There's always a single
ZCML file that is executed when the application is started, which then
includes everything else. Let's assume this file is called
``site.zcml`` (that's what it's called in Zope), so that file is what
we'll be editing.
In order to register the components that you wrote using the base
classes and directives available from ``grokcore.component``, we'll
use the ```` ZCML directive. But before we can use it,
we need to make sure it's available to the ZCML machinery. We do this
by including the meta configuration from ``grokcore.component``::
Put this line somewhere to the top of ``site.zcml``, next to other
meta configuration includes. Now, further down the line, we can tell
the machinery in ``grokcore.component`` to register all components in
your package (let's say it's called ``helloworld``)::
To sum up, your ``site.zcml`` file should look like something like this::
Examples
========
Adapter
-------
Here's a simple adapter that may be useful in Zope. It extracts the
languages that a user prefers from the request::
import grokcore.component
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.i18n.interfaces import IUserPreferredLanguages
class CookieLanguage(grokcore.component.Adapter):
"""Extract the preferred language from a cookie"""
grokcore.component.context(IBrowserRequest)
grokcore.component.implements(IUserPreferredLanguages)
# No need to implement __init__, it's already provided by the base class.
def getPreferredLanguages(self):
# This an adapter for the request, so self.context is the request.
request = self.context
# Extract the preferred language from a cookie:
lang = request.cookies.get('language', 'en')
# According to IUserPreferredLanguages, we must return a list.
return [lang]
Multi-adapter
-------------
Here's a multi-adapter that functions as a content provider as known
from the ``zope.contentprovider`` library. Content providers are
components that return snippets of HTML. They're multi-adapters for
the content object (model), the request and the view that they're
supposed to be a part of::
import grokcore.component
from zope.publisher.interfaces.browser import IBrowserRequest
from zope.publisher.interfaces.browser import IBrowserPage
from zope.contentprovider.interfaces import IContentProvider
class HelloWorldProvider(grokcore.component.MultiAdapter):
"""Display Hello World!"""
grokcore.component.adapts(Interface, IBrowserRequest, IBrowserPage)
grokcore.component.implements(IContentProvider)
def __init__(self, context, request, view):
pass
def update(self):
pass
def render(self):
return u'Hello World!
'
Global utility
--------------
Here's a simple named utility, again from the Zope world. It's a
translation domain. In other words, it contains translations of user
messages and is invoked when the i18n machinery needs to translate
something::
import grokcore.component
from zope.i18n.interfaces import ITranslationDomain
class HelloWorldTranslationDomain(grokcore.component.GlobalUtility):
grokcore.component.implements(ITranslationDomain)
grokcore.component.name('helloworld')
domain = u'helloworld'
def translate(self, msgid, mapping=None, context=None,
target_language=None, default=None):
if target_language is None:
preferred = IUserPreferredLanguages(context)
target_language = preferred.getPreferredLanguages()[0]
translations = {'de': u'Hallo Welt',
'nl': u'Hallo Wereld'}
return translations.get(target_language, u'Hello World')
Of course, it's silly to implement your own translation domain utility
if there are already implementations available in ``zope.i18n`` (one
that reads translations from a GNU gettext message catalog and a
simple implementation for tests). Let's try to reuse that
implementation and register an instance::
import grokcore.component
from zope.i18n.interfaces import ITranslationDomain
from zope.i18n.simpletranslationdomain import SimpleTranslationDomain
messages = {('de', u'Hello World'): u'Hallo Welt',
('nl', u'Hello World'): u'Hallo Wereld'}
helloworld_domain = SimpleTranslationDomain(u'helloworld', messages)
grokcore.component.global_utility(helloworld_domain,
provides=ITranslationDomain,
name='helloworld',
direct=True)
Global adapter
--------------
Sometimes, you may have an object that should be registered as an adapter
factory. It may have come from some other framework that configured that
adapter for you, say, or you may have a class that you instantiate many
times to get different variations on a particular adapter factory. In these
cases, subclassing grokcore.component.Adapter or MultiAdapter is not
possible. Instead, you can use the global_adapter() directive. Here is an
example drawing on the ``z3c.form`` library, which provides an adapter factory
factory for named widget attributes::
import zope.interface
import zope.schema
import grokcore.component
import z3c.form.widget import ComputedWidgetAttribute
class ISchema(Interface):
"""This schema will be used to power a z3c.form form"""
field = zope.schema.TextLine(title=u"Sample field")
...
label_override = z3c.form.widget.StaticWidgetAttribute(
u"Override label", field=ISchema['field'])
grokcore.component.global_adapter(label_override, name=u"label")
In the example above, the provided and adapted interfaces are deduced from the
object returned by the ``StaticWidgetAttribute`` factory. The full syntax
for global_adapter is::
global_adapter(factory, (IAdapted1, IAdapted2,), IProvided, name=u"name")
The factory must be a callable (the adapter factory). Adapted interfaces are
given as a tuple. You may use a single interface instead of a one-element
tuple for single adapters. The provided interface is given as shown. The name
defaults to u"" (an unnamed adapter).
Handling events
---------------
Here we see an event handler much like it occurs within Zope itself. It
subscribes to the modified event for all annotatable objects (in other words,
objects that can have metadata associated with them). When invoked, it updates
the Dublin Core 'Modified' property accordingly::
import datetime
import grokcore.component
from zope.annotation.interfaces import IAnnotatable
from zope.lifecycleevent.interfaces import IObjectModifiedEvent
from zope.dublincore.interfaces import IZopeDublinCore
@grokcore.component.subscribe(IAnnotatable, IObjectModifiedEvent)
def updateDublinCoreAfterModification(obj, event):
"""Updated the Dublin Core 'Modified' property when a modified
event is sent for an object."""
IZopeDublinCore(obj).modified = datetime.datetime.utcnow()
Subscriptions
-------------
Subscriptions look similar to Adapter, however, unlike regular adapters,
subscription adapters are used when we want all of the adapters that adapt an
object to a particular adapter.
Analogous to MultiAdapter, there is a MultiSubscription component that "adapts"
multiple objects.
grokcore.component-2.5/setup.cfg 0000664 0001750 0001750 00000000073 11750014424 016077 0 ustar jw jw 0000000 0000000 [egg_info]
tag_build =
tag_date = 0
tag_svn_revision = 0
grokcore.component-2.5/INSTALL.txt 0000664 0001750 0001750 00000001074 11750014416 016130 0 ustar jw jw 0000000 0000000 Preparing for grok development
------------------------------
Install setuptools on your system, or use a setuptools-based
environment like a "virtualenv" or a "buildout", and then install
"grokcore.component". Doing it from the command line looks like::
$ sudo easy_install -U grokcore.component
Then you can try importing it from your Python code.
Running the tests
-----------------
To run the "grokcore.component" tests, you need to download the source
code from version control and run the following command which the
buildout will create::
$ bin/test
grokcore.component-2.5/LICENSE.txt 0000664 0001750 0001750 00000004026 11750014416 016104 0 ustar jw jw 0000000 0000000 Zope Public License (ZPL) Version 2.1
A copyright notice accompanies this license document that identifies the
copyright holders.
This license has been certified as open source. It has also been designated as
GPL compatible by the Free Software Foundation (FSF).
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions in source code must retain the accompanying copyright
notice, this list of conditions, and the following disclaimer.
2. Redistributions in binary form must reproduce the accompanying copyright
notice, this list of conditions, and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. Names of the copyright holders must not be used to endorse or promote
products derived from this software without prior written permission from the
copyright holders.
4. The right to distribute this software or to use it for any purpose does not
give you the right to use Servicemarks (sm) or Trademarks (tm) of the
copyright
holders. Use of them is covered by separate agreement with the copyright
holders.
5. If any files are modified, you must cause the modified files to carry
prominent notices stating that you changed the files and the date of any
change.
Disclaimer
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS ``AS IS'' AND ANY EXPRESSED
OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE,
EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
grokcore.component-2.5/CREDITS.txt 0000664 0001750 0001750 00000000221 11750014416 016110 0 ustar jw jw 0000000 0000000 CREDITS
=======
This package was extracted from the Grok web framework.
For credits, see the CREDITS file in the main ``grok`` project itself.