• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

zopefoundation / grokcore.component / 16098871523

18 Jun 2025 06:24AM UTC coverage: 96.224%. Remained the same
16098871523

push

github

icemac
Back to development: 5.1

113 of 136 branches covered (83.09%)

Branch coverage included in aggregate %.

1416 of 1453 relevant lines covered (97.45%)

0.97 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

85.86
/src/grokcore/component/directive.py
1
##############################################################################
2
#
3
# Copyright (c) 2006-2007 Zope Foundation and Contributors.
4
# All Rights Reserved.
5
#
6
# This software is subject to the provisions of the Zope Public License,
7
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
8
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
9
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
10
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
11
# FOR A PARTICULAR PURPOSE.
12
#
13
##############################################################################
14
"""Grok directives.
15
"""
16
import martian
1✔
17
import martian.util
1✔
18
from martian.error import GrokError
1✔
19
from martian.error import GrokImportError
1✔
20
from martian.util import scan_for_classes
1✔
21
from zope import interface
1✔
22
from zope.interface.interfaces import IInterface
1✔
23

24
from grokcore.component.interfaces import IContext
1✔
25

26

27
class global_utility(martian.MultipleTimesDirective):
1✔
28
    """Registers an instance of ``class`` (or ``class`` itself, depending on
29
    the value of the ``direct`` parameter) as a global utility.
30

31
    This allows you to register global utilities that don't inherit from the
32
    ``GlobalUtility`` base class.
33

34
    :param class: The class to register as a global utility.
35
    :param provides: Optionally, the interface the utility will provide.
36
    :param name: Optionally, a name for a named utility registration.
37
    :type name: string or unicode
38
    :param direct: Optionally, a flag indicating the class directly provides
39
                   the interfaces, and it needs not to be instantiated.
40
    :type direct: boolean
41
    """
42
    scope = martian.MODULE
1✔
43

44
    def factory(self, factory, provides=None, name='', direct=False):
1✔
45
        if provides is not None and not IInterface.providedBy(provides):
1!
46
            raise GrokImportError(
×
47
                "You can only pass an interface to the "
48
                "provides argument of %s." % self.name)
49
        return (factory, provides, name, direct)
1✔
50

51

52
class global_adapter(martian.MultipleTimesDirective):
1✔
53
    """Registers the ``factory`` callable as a global adapter.
54

55
    This allows you to register global adapters that
56
    don't inherit from the ``Adapter`` or ``MultiAdapter`` base classes.
57

58
    :param factory: The class that implements the adaptation.
59
    :param adapts: Optionally, a single interface or a tuple of multiple
60
                   interfaces to adapts from. If omitted, this information is
61
                   deduced from the annotation on the factory. If no adapted
62
                   interface can be determined the current context will be
63
                   assumed.
64
    :param provides: Optionally, the interface the adapter will provide. If
65
                     omitted, this information is deduced from the annotations
66
                     on the factory.
67
    :param name: Optionally, a name for a named adapter registration.
68
    :type name: string or unicode
69

70
    """
71
    scope = martian.MODULE
1✔
72

73
    def factory(self, factory, adapts=None, provides=None, name=None):
1✔
74
        if provides is not None and not IInterface.providedBy(provides):
1!
75
            raise GrokImportError(
×
76
                "You can only pass an interface to the "
77
                "provides argument of %s." % self.name)
78
        if adapts is None:
1✔
79
            adapts = getattr(factory, '__component_adapts__', None)
1✔
80
        elif not isinstance(adapts, (list, tuple,)):
1✔
81
            adapts = (adapts,)
1✔
82
        elif isinstance(adapts, list):
1!
83
            adapts = tuple(adapts)
×
84

85
        return (factory, adapts, provides, name)
1✔
86

87

88
class name(martian.Directive):
1✔
89
    """Declares the name of a named utility, named adapter, etc.
90

91
    """
92
    scope = martian.CLASS
1✔
93
    store = martian.ONCE
1✔
94
    validate = martian.validateText
1✔
95
    default = ''
1✔
96

97

98
class context(martian.Directive):
1✔
99
    """Declares the type of object that the adapter (or a similar context-
100
    dependent component) adapts.
101

102
    :param context: Interface (in this case all objects providing this
103
                    interface will be eligible contexts for the adaptation) or
104
                    a class (then only instances of that particular class are
105
                    eligible).
106
    """
107

108
    scope = martian.CLASS_OR_MODULE
1✔
109
    store = martian.ONCE
1✔
110
    validate = martian.validateInterfaceOrClass
1✔
111

112
    @classmethod
1✔
113
    def get_default(cls, component, module=None, **data):
1✔
114
        components = list(scan_for_classes(module, IContext))
1✔
115
        if len(components) == 0:
1✔
116
            raise GrokError(
1✔
117
                "No module-level context for %r, please use the 'context' "
118
                "directive." % (component), component)
119
        elif len(components) == 1:
1✔
120
            component = components[0]
1✔
121
        else:
122
            raise GrokError(
1✔
123
                "Multiple possible contexts for %r, please use the 'context' "
124
                "directive."
125
                % (component), component)
126
        return component
1✔
127

128

129
class title(martian.Directive):
1✔
130
    """Declares the human-readable title of a component (such as a permission,
131
    role, etc.)
132

133
    """
134
    scope = martian.CLASS
1✔
135
    store = martian.ONCE
1✔
136
    validate = martian.validateText
1✔
137

138

139
class description(title):
1✔
140
    pass
1✔
141

142

143
class direct(martian.MarkerDirective):
1✔
144
    """Declares that a ``GlobalUtility`` class should be registered as a
145
    utility itself, rather than an instance of it.
146

147
    """
148
    scope = martian.CLASS
1✔
149

150

151
class order(martian.Directive):
1✔
152
    scope = martian.CLASS
1✔
153
    store = martian.ONCE
1✔
154
    default = 0, 0
1✔
155

156
    _order = 0
1✔
157

158
    def factory(self, value=0):
1✔
159
        order._order += 1
1✔
160
        return value, order._order
1✔
161

162

163
class path(martian.Directive):
1✔
164
    scope = martian.CLASS
1✔
165
    store = martian.ONCE
1✔
166
    validate = martian.validateText
1✔
167

168

169
class provides(martian.Directive):
1✔
170
    """Declares the interface that a adapter or utility provides for the
171
    registration, as opposed to potentially multiple interfaces that the class
172
    implements.
173

174
    :param interface: The interface the registered component will provide.
175

176
    """
177
    scope = martian.CLASS
1✔
178
    store = martian.ONCE
1✔
179
    validate = martian.validateInterface
1✔
180

181
    @classmethod
1✔
182
    def get_default(cls, component, module, **data):
1✔
183
        martian.util.check_implements_one(component)
1✔
184
        return list(interface.implementedBy(component))[0]
1✔
185

186

187
class implements(martian.Directive):
1✔
188
    """ Declare interfaces implemented by instances of a class.
189
        The arguments are one or more interfaces or interface
190
        specifications (IDeclaration objects).
191

192
        Since the original implementer from zope.interface is not supported
193
        anymore; grokcore.component continues to support it on its own.
194

195
        :param interface or interfaces to be implement by a class.
196
    """
197
    scope = martian.CLASS
1✔
198
    store = martian.ONCE
1✔
199
    default = None
1✔
200

201
    def factory(self, *interfaces):
1✔
202
        for iface in interfaces:
×
203
            if not IInterface.providedBy(iface):
×
204
                raise Exception('%s is not a interface' % repr(iface))
×
205
        return interfaces
×
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc