Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Move out component bits of repoze.plugin into repoze.component.
- Loading branch information
0 parents
commit aaab96b
Showing
21 changed files
with
2,033 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
repoze.component Changelog | ||
========================== | ||
|
||
0.1 (unreleased) | ||
---------------- | ||
|
||
- Initial release. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
Copyright (c) 2009 Agendaless Consulting and Contributors. | ||
(http://www.agendaless.com), All Rights Reserved | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
License | ||
|
||
A copyright notice accompanies this license document that identifies | ||
the copyright holders. | ||
|
||
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. 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. | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
repoze.component README | ||
======================= | ||
|
||
:mod:`repoze.component` is a package that software developers can use | ||
to provide configurability and pluggability to their applications. | ||
:mod:`repoze.plugin` provides a generalized indirection mechanism | ||
which can be used to provide plugin points to integrators or other | ||
developers who may wish to provide alternate implementations of | ||
application logic or configuration values. | ||
|
||
See docs/index.rst for more information. |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
@import url('default.css'); | ||
body { | ||
background-color: #006339; | ||
} | ||
|
||
div.document { | ||
background-color: #dad3bd; | ||
} | ||
|
||
div.sphinxsidebar h3, h4, h5, a { | ||
color: #127c56 !important; | ||
} | ||
|
||
div.related { | ||
color: #dad3bd !important; | ||
background-color: #00744a; | ||
} | ||
|
||
div.related a { | ||
color: #dad3bd !important; | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
# Makefile for Sphinx documentation | ||
# | ||
|
||
# You can set these variables from the command line. | ||
SPHINXOPTS = | ||
SPHINXBUILD = sphinx-build | ||
PAPER = | ||
|
||
# Internal variables. | ||
PAPEROPT_a4 = -D latex_paper_size=a4 | ||
PAPEROPT_letter = -D latex_paper_size=letter | ||
ALLSPHINXOPTS = -d .build/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) . | ||
|
||
.PHONY: help clean html web pickle htmlhelp latex changes linkcheck | ||
|
||
help: | ||
@echo "Please use \`make <target>' where <target> is one of" | ||
@echo " html to make standalone HTML files" | ||
@echo " pickle to make pickle files (usable by e.g. sphinx-web)" | ||
@echo " htmlhelp to make HTML files and a HTML help project" | ||
@echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" | ||
@echo " changes to make an overview over all changed/added/deprecated items" | ||
@echo " linkcheck to check all external links for integrity" | ||
|
||
clean: | ||
-rm -rf .build/* | ||
|
||
html: | ||
mkdir -p .build/html .build/doctrees | ||
$(SPHINXBUILD) -b html $(ALLSPHINXOPTS) .build/html | ||
@echo | ||
@echo "Build finished. The HTML pages are in .build/html." | ||
|
||
pickle: | ||
mkdir -p .build/pickle .build/doctrees | ||
$(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) .build/pickle | ||
@echo | ||
@echo "Build finished; now you can process the pickle files or run" | ||
@echo " sphinx-web .build/pickle" | ||
@echo "to start the sphinx-web server." | ||
|
||
web: pickle | ||
|
||
htmlhelp: | ||
mkdir -p .build/htmlhelp .build/doctrees | ||
$(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) .build/htmlhelp | ||
@echo | ||
@echo "Build finished; now you can run HTML Help Workshop with the" \ | ||
".hhp project file in .build/htmlhelp." | ||
|
||
latex: | ||
mkdir -p .build/latex .build/doctrees | ||
$(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) .build/latex | ||
@echo | ||
@echo "Build finished; the LaTeX files are in .build/latex." | ||
@echo "Run \`make all-pdf' or \`make all-ps' in that directory to" \ | ||
"run these through (pdf)latex." | ||
|
||
changes: | ||
mkdir -p .build/changes .build/doctrees | ||
$(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) .build/changes | ||
@echo | ||
@echo "The overview file is in .build/changes." | ||
|
||
linkcheck: | ||
mkdir -p .build/linkcheck .build/doctrees | ||
$(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) .build/linkcheck | ||
@echo | ||
@echo "Link check complete; look for any errors in the above output " \ | ||
"or in .build/linkcheck/output.txt." |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
Using :mod:`repoze.component` as an Adapter System | ||
================================================== | ||
|
||
We've seen the basic registration and lookup facilities of a | ||
:mod:`repoze.component` registry. You can provide additional | ||
functionality to your applications if you use it as an "adapter | ||
registry". Using a component registry as an adapter registry makes it | ||
possible to use the :mod:`repoze.component` component registry for the | ||
same purposes as something like :term:`zope.component`. | ||
|
||
The extra methods exposed by a :mod:`repoze.component` registry that | ||
allow you to treat it as an adapter regstry are ``resolve`` and | ||
``adapt``. The ``resolve`` method simply accepts a provides value and | ||
sequence of *objects that supply component types* and returns a | ||
matching component. The ``adapt`` method does exactly what resolve | ||
does, but it additionally uses the component as a factory, passing | ||
each ``requires`` value to it as a positional argument and returns the | ||
result. | ||
|
||
.. note:: If you hold your head just right and squint at it hard | ||
enough, you might consider :mod:`repoze.component` software that makes | ||
it possible to do a form of `aspect-oriented programming | ||
<http://en.wikipedia.org/wiki/Aspect-oriented_programming>`_ in | ||
Python. However, you need to know nothing about aspect-oriented | ||
programming to use it (the author doesn't really know anything | ||
about "proper" aspect-oriented programming either, but he's told | ||
that it's not dissimlar to the mechanisms exposed by | ||
:mod:`repoze.component`). | ||
|
||
"Requires" Objects Supply Component Types | ||
----------------------------------------- | ||
|
||
Object used as "requires" arguments to the ``resolve`` and ``adapts`` | ||
methods of a component registry usually supply a component type. This | ||
is done by adding a ``__component_type__`` attribute to objects passed | ||
to these methods. | ||
|
||
The component type must be stored on those objects as the | ||
``__component_type__`` attribute. The ``__component_type__`` may be a | ||
single object (usually a string) or it may be a sequence of objects. | ||
The object is assumed to be a single object if the | ||
``__component_type__`` does not have an ``__iter__`` method. For | ||
example, the following is legal: | ||
|
||
.. code-block:: python | ||
class MyObject(object): | ||
__component_type__ = 'mytype' | ||
The followng is also legal. | ||
|
||
.. code-block:: python | ||
class MyObject(object): | ||
__component_type__ = ('mytype', 'anothertype') | ||
Likewise, it's also legal to do: | ||
|
||
.. code-block:: python | ||
class MyObject(object): | ||
__component_type__ = ['mytype', 'anothertype'] | ||
Classes or instances can carry component types: | ||
|
||
.. code-block:: python | ||
class MyObject(object): | ||
pass | ||
obj = MyObject() | ||
obj.__component_type__ = ('mytype', 'anothertype') | ||
How :mod:`repoze.component` Computes an Effecive Component Type for a Requires Object | ||
------------------------------------------------------------------------------------- | ||
|
||
When a component type is computed for an object, the object is | ||
searched in the following order. All values are collected and used to | ||
construct the final "requires" argument used. | ||
|
||
- The object itself is checked for the ``__component_type__`` | ||
attribute. | ||
|
||
- If the object is a class, its base classes are checked in Python MRO | ||
order for a ``__component_type__`` attribute. | ||
|
||
- If the object is an instance, its class then its base classes are | ||
checked in Python MRO order for a ``__component_type__`` attribute. | ||
|
||
We'll use the following set of objects as examples: | ||
|
||
.. code-block:: python | ||
class A(object): | ||
__component_type__ = ('a', 'hello') | ||
class B(A): | ||
__component_type__ = 'b' | ||
class C(B): | ||
__component_type__ = 'c' | ||
instance = C() | ||
instance.__component_type__ = 'i' | ||
If "instance" is used as an argument to the ``resolve`` method of an | ||
component registry: | ||
|
||
- We first look at the instance to find a component type. This | ||
finds component type ``i``. | ||
|
||
- We look at its direct class ``C`` which finds component type ``c``. | ||
|
||
- We look at the component type of the base classes of the ``C`` | ||
class. The B class provides component type ``b``, the ``A`` class | ||
provides component types (``a`` and ``hello``). | ||
|
||
Thus our "requires" argument for this particular object is ``['i', | ||
'c', 'b', 'a', 'hello']``. Every object supplied as a "requires" | ||
argument to either the ``resolve`` or ``adapt`` method of a component | ||
registry has its requires values computed this way. We then find a | ||
component based on the set of requires arguments passed in ala | ||
:ref:`lookup_ordering`. | ||
|
||
Comparing :mod:`repoze.component` to :term:`zope.component` | ||
----------------------------------------------------------- | ||
|
||
Zope and Twisted developers (and any other developer who has used | ||
:term:`zope.component`) will find :mod:`repoze.component` familiar. | ||
:mod:`repoze.component` steals concepts shamelessly from | ||
:term:`zope.component`. :mod:`repoze.component` differs primarily from | ||
:term:`zope.component` by abandoning the high-level concept of an | ||
:term:`interface`. In :term:`zope.component`, component lookups and | ||
registrations are done in terms of interfaces, which are very specific | ||
kinds of Python objects. In :mod:`repoze.component`, interfaces are not | ||
used. Instead, components (such as "adapters" and "utilities") are | ||
registered using marker "component types", which are usually just | ||
strings although they can be any hashable type. | ||
|
||
.. note:: | ||
|
||
In the examples below, where a :term:`zope.component` API might | ||
expect an interface object (e.g. the interface ``ISomething``), the | ||
:mod:`repoze.component` API expects a compoment type (e.g. the string | ||
``something``). Also, in the examples below, whereas | ||
:term:`zope.component` users typically rely on APIs that consult a | ||
"global registry", :mod:`repoze.component` provides no such facility. | ||
Thus examples that refer to ``registry`` below refer to a plugin | ||
registry created by parsing a configuration file (or constructed | ||
manually). | ||
|
||
The :mod:`repoze.component` equivalent of ``utility = | ||
zope.component.getUtility(ISomething)`` is the following: | ||
|
||
.. code-block:: python | ||
utility = registry.lookup('something') | ||
The :mod:`repoze.component` equivalent of ``implementation = | ||
zope.component.getAdapter(context, ISomething, name='foo')`` is the | ||
following: | ||
|
||
.. code-block:: python | ||
implementation = registry.adapt('something', context, name='foo') | ||
The :mod:`repoze.component` equivalent of ``implementation = | ||
getMultiAdapter((context1, context2), ISomething, name='foo')`` is the | ||
following: | ||
|
||
.. code-block:: python | ||
implementation = registry.adapt('something', context1, context2, name='foo') | ||
Likewise, the :mod:`repoze.component` equivalent of ``implementation = | ||
getMultiAdapter((context1, context2, context3), ISomething, | ||
name='foo')`` is the following: | ||
|
||
.. code-block:: python | ||
implementation = registry.adapt('something', context1, context2, context3, | ||
name='foo') | ||
Oops, something went wrong.