/usr/share/pyshared/martian/context.txt is in python-martian 0.14-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 | Context associating directives
==============================
Martian can help you implement directives that implicitly associate
with another object or class in the modules. The most common example
of this is the way Grok's ``context`` directive works.
It has the following rules:
* ``grok.context`` can be used on the class to establish the context
class for this class.
* ``grok.context`` can be used on the module to establish the context
class for all classes in the module that require a context. Only
class-level ``grok.context`` use will override this.
* If there is no ``grok.context`` for the class or module, the context
will be a class in the module that implements a special ``IContext``
interface.
* If there are multiple possible impicit contexts, the context is
ambiguous. This is an error.
* If there is no possible implicit context, the context cannot be
established. This is an error too.
Let's implement a context directive with this behavior::
>>> import martian
>>> class context(martian.Directive):
... scope = martian.CLASS_OR_MODULE
... store = martian.ONCE
Let's use an explicit class context::
>>> class A(object):
... pass
>>> class explicitclasscontext(FakeModule):
... class B(object):
... context(A)
>>> from martiantest.fake import explicitclasscontext
>>> context.bind().get(explicitclasscontext.B)
<class 'A'>
Let's now use the directive on the module-level, explicitly::
>>> class explicitmodulecontext(FakeModule):
... context(A)
... class B(object):
... pass
>>> from martiantest.fake import explicitmodulecontext
>>> context.bind().get(explicitmodulecontext.B)
<class 'martiantest.fake.explicitmodulecontext.A'>
XXX why does this get this put into martiantest.fake.explicitmodule? A
problem in FakeModule?
Let's see a combination of the two, to check whether context on the class
level overrides that on the module level::
>>> class D(object):
... pass
>>> class explicitcombo(FakeModule):
... context(A)
... class B(object):
... pass
... class C(object):
... context(D)
>>> from martiantest.fake import explicitcombo
>>> context.bind().get(explicitcombo.B)
<class 'martiantest.fake.explicitcombo.A'>
>>> context.bind().get(explicitcombo.C)
<class 'D'>
So far so good. Now let's look at automatic association. Let's provide
a ``get_default`` function that associates with any class that implements
``IContext``:
>>> from zope.interface import Interface
>>> class IContext(Interface):
... pass
>>> get_default_context = martian.GetDefaultComponentFactory(
... IContext, 'context', 'context')
We define a base class that will be automatically associated with::
>>> from zope.interface import implements
>>> class Context(object):
... implements(IContext)
Let's experiment whether implicit context association works::
>>> class implicitcontext(FakeModule):
... class A(Context):
... pass
... class B(object):
... pass
>>> from martiantest.fake import implicitcontext
>>> context.bind(get_default=get_default_context).get(implicitcontext.B)
<class 'martiantest.fake.implicitcontext.A'>
We now test the failure conditions.
There is no implicit context to associate with::
>>> class noimplicitcontext(FakeModule):
... class B(object):
... pass
>>> from martiantest.fake import noimplicitcontext
>>> context.bind(get_default=get_default_context).get(noimplicitcontext.B)
Traceback (most recent call last):
...
GrokError: No module-level context for <class 'martiantest.fake.noimplicitcontext.B'>, please use the 'context' directive.
There are too many possible contexts::
>>> class ambiguouscontext(FakeModule):
... class A(Context):
... pass
... class B(Context):
... pass
... class C(object):
... pass
>>> from martiantest.fake import ambiguouscontext
>>> context.bind(get_default=get_default_context).get(ambiguouscontext.B)
Traceback (most recent call last):
...
GrokError: Multiple possible contexts for <class 'martiantest.fake.ambiguouscontext.B'>, please use the 'context' directive.
Let's try this with inheritance, where an implicit context is provided
by a base class defined in another module::
>>> class basemodule(FakeModule):
... class A(Context):
... pass
... class B(object):
... pass
>>> from martiantest.fake import basemodule
>>> class submodule(FakeModule):
... class C(basemodule.B):
... pass
>>> from martiantest.fake import submodule
>>> context.bind(get_default=get_default_context).get(submodule.C)
<class 'martiantest.fake.basemodule.A'>
Let's try it again with an ambiguous context in this case, resolved because
there is an unambiguous context for the base class ``B``::
>>> class basemodule2(FakeModule):
... class A(Context):
... pass
... class B(object):
... pass
>>> from martiantest.fake import basemodule2
>>> class submodule2(FakeModule):
... class Ambiguous1(Context):
... pass
... class Ambiguous2(Context):
... pass
... class C(basemodule2.B):
... pass
>>> from martiantest.fake import submodule2
>>> context.bind(get_default=get_default_context).get(submodule2.C)
<class 'martiantest.fake.basemodule2.A'>
If the implicit context cannot be found in the base class either, the error
will show up for the most specific class (``C``)::
>>> class basemodule3(FakeModule):
... class B(object):
... pass
>>> from martiantest.fake import basemodule3
>>> class submodule3(FakeModule):
... class C(basemodule3.B):
... pass
>>> from martiantest.fake import submodule3
>>> context.bind(get_default=get_default_context).get(submodule3.C)
Traceback (most recent call last):
...
GrokError: No module-level context for <class 'martiantest.fake.submodule3.C'>, please use the 'context' directive.
|