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

zopefoundation / Zope / 3956162881

pending completion
3956162881

push

github

Michael Howitz
Update to deprecation warning free releases.

4401 of 7036 branches covered (62.55%)

Branch coverage included in aggregate %.

27161 of 31488 relevant lines covered (86.26%)

0.86 hits per line

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

80.62
/src/App/ProductContext.py
1
##############################################################################
2
#
3
# Copyright (c) 2002 Zope Foundation and Contributors.
4
#
5
# This software is subject to the provisions of the Zope Public License,
6
# Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
7
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
8
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
9
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
10
# FOR A PARTICULAR PURPOSE.
11
#
12
##############################################################################
13
"""Objects providing context for product initialization
1✔
14
"""
15

16
import os
1✔
17
from logging import getLogger
1✔
18

19
import Products
1✔
20
from AccessControl.Permission import registerPermissions
1✔
21
from AccessControl.PermissionRole import PermissionRole
1✔
22
from App.FactoryDispatcher import FactoryDispatcher
1✔
23
from OFS.ObjectManager import ObjectManager
1✔
24
from zope.interface import implementedBy
1✔
25

26

27
if not hasattr(Products, 'meta_types'):
1!
28
    Products.meta_types = ()
1✔
29
if not hasattr(Products, 'meta_classes'):
1!
30
    Products.meta_classes = {}
1✔
31
    Products.meta_class_info = {}
1✔
32

33

34
_marker = []  # Create a new marker object
1✔
35
LOG = getLogger('ProductContext')
1✔
36

37

38
class ProductContext:
1✔
39

40
    def __init__(self, product, app, package):
1✔
41
        self.__prod = product
1✔
42
        self.__app = app
1✔
43
        self.__pack = package
1✔
44

45
    def registerClass(self, instance_class=None, meta_type='',
1✔
46
                      permission=None, constructors=(),
47
                      icon=None, permissions=None, legacy=(),
48
                      visibility="Global", interfaces=_marker,
49
                      container_filter=None):
50
        """Register a constructor
51

52
        Keyword arguments are used to provide meta data:
53

54
        instance_class -- The class of the object that will be created.
55

56
          This is not currently used, but may be used in the future to
57
          increase object mobility.
58

59
        meta_type -- The kind of object being created
60
           This appears in add lists.  If not specified, then the class
61
           meta_type will be used.
62

63
        permission -- The permission name for the constructors.
64
           If not specified, then a permission name based on the
65
           meta type will be used.
66

67
        constructors -- A list of constructor methods
68
          A method can be a callable object with a __name__
69
          attribute giving the name the method should have in the
70
          product, or the method may be a tuple consisting of a
71
          name and a callable object.  The method must be picklable.
72

73
          The first method will be used as the initial method called
74
          when creating an object.
75

76
        icon -- No longer used.
77

78
        permissions -- Additional permissions to be registered
79
           If not provided, then permissions defined in the
80
           class will be registered.
81

82
        legacy -- A list of legacy methods to be added to ObjectManager
83
                  for backward compatibility
84

85
        visibility -- "Global" if the object is globally visible, None else
86

87
        interfaces -- a list of the interfaces the object supports
88

89
        container_filter -- function that is called with an ObjectManager
90
           object as the only parameter, which should return a true object
91
           if the object is happy to be created in that container. The
92
           filter is called before showing ObjectManager's Add list,
93
           and before pasting (after object copy or cut), but not
94
           before calling an object's constructor.
95

96
        """
97
        pack = self.__pack
1✔
98
        initial = constructors[0]
1✔
99
        productObject = self.__prod
1✔
100
        pid = productObject.id
1✔
101

102
        if permissions:
1!
103
            if isinstance(permissions, str):  # You goofed it!
×
104
                raise TypeError(
×
105
                    'Product context permissions should be a '
106
                    'list of permissions not a string', permissions)
107
            for p in permissions:
×
108
                if isinstance(p, tuple):
×
109
                    p, default = p
×
110
                    registerPermissions(((p, (), default),))
×
111
                else:
112
                    registerPermissions(((p, ()),))
×
113

114
        ############################################################
115
        # Constructor permission setup
116
        if permission is None:
1✔
117
            permission = "Add %ss" % (meta_type or instance_class.meta_type)
1✔
118

119
        if isinstance(permission, tuple):
1!
120
            permission, default = permission
×
121
        else:
122
            default = ('Manager',)
1✔
123

124
        pr = PermissionRole(permission, default)
1✔
125
        registerPermissions(((permission, (), default),))
1✔
126
        ############################################################
127

128
        OM = ObjectManager
1✔
129

130
        for method in legacy:
1✔
131
            if isinstance(method, tuple):
1✔
132
                name, method = method
1✔
133
                aliased = 1
1✔
134
            else:
135
                name = method.__name__
1✔
136
                aliased = 0
1✔
137
            if name not in OM.__dict__:
1✔
138
                setattr(OM, name, method)
1✔
139
                setattr(OM, name + '__roles__', pr)
1✔
140
                if aliased:
1✔
141
                    # Set the unaliased method name and its roles
142
                    # to avoid security holes.  XXX: All "legacy"
143
                    # methods need to be eliminated.
144
                    setattr(OM, method.__name__, method)
1✔
145
                    setattr(OM, method.__name__ + '__roles__', pr)
1✔
146

147
        if isinstance(initial, tuple):
1✔
148
            name, initial = initial
1✔
149
        else:
150
            name = initial.__name__
1✔
151

152
        fd = getattr(pack, '__FactoryDispatcher__', None)
1✔
153
        if fd is None:
1✔
154
            class __FactoryDispatcher__(FactoryDispatcher):
1✔
155
                "Factory Dispatcher for a Specific Product"
156

157
            fd = pack.__FactoryDispatcher__ = __FactoryDispatcher__
1✔
158

159
        if not hasattr(pack, '_m'):
1✔
160
            pack._m = AttrDict(fd)
1✔
161

162
        m = pack._m
1✔
163

164
        if interfaces is _marker:
1!
165
            if instance_class is None:
1!
166
                interfaces = ()
×
167
            else:
168
                interfaces = tuple(implementedBy(instance_class))
1✔
169

170
        Products.meta_types = Products.meta_types + ({
1✔
171
            'name': meta_type or instance_class.meta_type,
172
            # 'action': The action in the add drop down in the ZMI. This is
173
            #           currently also required by the _verifyObjectPaste
174
            #           method of CopyContainers like Folders.
175
            'action': (f'manage_addProduct/{pid}/{name}'),
176
            # 'product': product id
177
            'product': pid,
178
            # 'permission': Guards the add action.
179
            'permission': permission,
180
            # 'visibility': A silly name. Doesn't have much to do with
181
            #               visibility. Allowed values: 'Global', None
182
            'visibility': visibility,
183
            # 'interfaces': A tuple of oldstyle and/or newstyle interfaces.
184
            'interfaces': interfaces,
185
            'instance': instance_class,
186
            'container_filter': container_filter
187
        },)
188

189
        m[name] = initial
1✔
190
        m[name + '__roles__'] = pr
1✔
191

192
        for method in constructors[1:]:
1✔
193
            if isinstance(method, tuple):
1!
194
                name, method = method
×
195
            else:
196
                name = os.path.split(method.__name__)[-1]
1✔
197
            if name not in productObject.__dict__:
1!
198
                m[name] = method
1✔
199
                m[name + '__roles__'] = pr
1✔
200

201
    def getApplication(self):
1✔
202
        return self.__app
1✔
203

204

205
class AttrDict:
1✔
206

207
    def __init__(self, ob):
1✔
208
        self.ob = ob
1✔
209

210
    def __contains__(self, name):
1✔
211
        return hasattr(self.ob, name)
1✔
212

213
    def __getitem__(self, name):
1✔
214
        return getattr(self.ob, name)
×
215

216
    def __setitem__(self, name, v):
1✔
217
        setattr(self.ob, name, v)
1✔
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