AccessControl 6.2__tar.gz → 7.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (90) hide show
  1. {AccessControl-6.2 → AccessControl-7.0}/.coveragerc +1 -0
  2. {AccessControl-6.2 → AccessControl-7.0}/.manylinux-install.sh +9 -9
  3. {AccessControl-6.2 → AccessControl-7.0}/CHANGES.rst +25 -0
  4. {AccessControl-6.2 → AccessControl-7.0}/MANIFEST.in +0 -1
  5. {AccessControl-6.2 → AccessControl-7.0}/PKG-INFO +49 -4
  6. {AccessControl-6.2 → AccessControl-7.0}/setup.cfg +0 -3
  7. {AccessControl-6.2 → AccessControl-7.0}/setup.py +4 -3
  8. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/SecurityInfo.py +8 -7
  9. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/ZopeGuards.py +48 -11
  10. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/cAccessControl.c +5 -5
  11. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/logger_wrapper.py +1 -1
  12. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/actual_python.py +33 -0
  13. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testZopeGuards.py +25 -9
  14. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/PKG-INFO +49 -4
  15. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/SOURCES.txt +0 -1
  16. {AccessControl-6.2 → AccessControl-7.0}/tox.ini +24 -10
  17. AccessControl-6.2/appveyor.yml +0 -52
  18. {AccessControl-6.2 → AccessControl-7.0}/.manylinux.sh +0 -0
  19. {AccessControl-6.2 → AccessControl-7.0}/CONTRIBUTING.md +0 -0
  20. {AccessControl-6.2 → AccessControl-7.0}/COPYRIGHT.txt +0 -0
  21. {AccessControl-6.2 → AccessControl-7.0}/HISTORY.rst +0 -0
  22. {AccessControl-6.2 → AccessControl-7.0}/LICENSE.txt +0 -0
  23. {AccessControl-6.2 → AccessControl-7.0}/README.rst +0 -0
  24. {AccessControl-6.2 → AccessControl-7.0}/buildout.cfg +0 -0
  25. {AccessControl-6.2 → AccessControl-7.0}/docs/AccessControl.rst +0 -0
  26. {AccessControl-6.2 → AccessControl-7.0}/docs/requestmethod.rst +0 -0
  27. {AccessControl-6.2 → AccessControl-7.0}/include/Acquisition/Acquisition.h +0 -0
  28. {AccessControl-6.2 → AccessControl-7.0}/include/ExtensionClass/ExtensionClass.h +0 -0
  29. {AccessControl-6.2 → AccessControl-7.0}/include/ExtensionClass/_compat.h +0 -0
  30. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/AuthEncoding.py +0 -0
  31. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/ImplC.py +0 -0
  32. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/ImplPython.py +0 -0
  33. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/Implementation.py +0 -0
  34. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/Owned.py +0 -0
  35. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/Permission.py +0 -0
  36. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/PermissionMapping.py +0 -0
  37. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/PermissionRole.py +0 -0
  38. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/Permissions.py +0 -0
  39. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/Role.py +0 -0
  40. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/SecurityManagement.py +0 -0
  41. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/SecurityManager.py +0 -0
  42. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/SimpleObjectPolicies.py +0 -0
  43. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/SpecialUsers.py +0 -0
  44. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/User.py +0 -0
  45. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/ZopeSecurityPolicy.py +0 -0
  46. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/__init__.py +0 -0
  47. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/_compat.h +0 -0
  48. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/class_init.py +0 -0
  49. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/configure.zcml +0 -0
  50. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/interfaces.py +0 -0
  51. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/meta.zcml +0 -0
  52. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/metaconfigure.py +0 -0
  53. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/owner.py +0 -0
  54. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/permissions.zcml +0 -0
  55. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/requestmethod.py +0 -0
  56. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/rolemanager.py +0 -0
  57. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/safe_formatter.py +0 -0
  58. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/security.py +0 -0
  59. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tainted.py +0 -0
  60. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/__init__.py +0 -0
  61. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/mixed_module/__init__.py +0 -0
  62. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/mixed_module/submodule/__init__.py +0 -0
  63. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/private_module/__init__.py +0 -0
  64. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/private_module/submodule/__init__.py +0 -0
  65. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/public_module/__init__.py +0 -0
  66. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/public_module/submodule/__init__.py +0 -0
  67. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testClassSecurityInfo.py +0 -0
  68. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testImplementation.py +0 -0
  69. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testModuleSecurity.py +0 -0
  70. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testPermissionMapping.py +0 -0
  71. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testPermissionRole.py +0 -0
  72. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testSecurityManager.py +0 -0
  73. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testZCML.py +0 -0
  74. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/testZopeSecurityPolicy.py +0 -0
  75. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_owner.py +0 -0
  76. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_requestmethod.py +0 -0
  77. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_rolemanager.py +0 -0
  78. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_safe_formatter.py +0 -0
  79. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_safeiter.py +0 -0
  80. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_tainted.py +0 -0
  81. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_userfolder.py +0 -0
  82. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/tests/test_users.py +0 -0
  83. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/unauthorized.py +0 -0
  84. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/userfolder.py +0 -0
  85. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl/users.py +0 -0
  86. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/dependency_links.txt +0 -0
  87. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/entry_points.txt +0 -0
  88. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/not-zip-safe +0 -0
  89. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/requires.txt +0 -0
  90. {AccessControl-6.2 → AccessControl-7.0}/src/AccessControl.egg-info/top_level.txt +0 -0
@@ -15,6 +15,7 @@ source =
15
15
  [report]
16
16
  show_missing = true
17
17
  precision = 2
18
+ ignore_errors = True
18
19
  exclude_lines =
19
20
  except ImportError:
20
21
  if __name__ == '__main__':
@@ -28,12 +28,12 @@ yum -y install libffi-devel
28
28
 
29
29
  tox_env_map() {
30
30
  case $1 in
31
- *"cp312"*) echo 'py312';;
32
- *"cp37"*) echo 'py37';;
31
+ *"cp313"*) echo 'py313';;
33
32
  *"cp38"*) echo 'py38';;
34
33
  *"cp39"*) echo 'py39';;
35
34
  *"cp310"*) echo 'py310';;
36
35
  *"cp311"*) echo 'py311';;
36
+ *"cp312"*) echo 'py312';;
37
37
  *) echo 'py';;
38
38
  esac
39
39
  }
@@ -41,13 +41,13 @@ tox_env_map() {
41
41
  # Compile wheels
42
42
  for PYBIN in /opt/python/*/bin; do
43
43
  if \
44
- [[ "${PYBIN}" == *"cp312"* ]] || \
45
- [[ "${PYBIN}" == *"cp311"* ]] || \
46
- [[ "${PYBIN}" == *"cp37"* ]] || \
47
- [[ "${PYBIN}" == *"cp38"* ]] || \
48
- [[ "${PYBIN}" == *"cp39"* ]] || \
49
- [[ "${PYBIN}" == *"cp310"* ]] ; then
50
- if [[ "${PYBIN}" == *"cp312"* ]] ; then
44
+ [[ "${PYBIN}" == *"cp313/"* ]] || \
45
+ [[ "${PYBIN}" == *"cp311/"* ]] || \
46
+ [[ "${PYBIN}" == *"cp312/"* ]] || \
47
+ [[ "${PYBIN}" == *"cp38/"* ]] || \
48
+ [[ "${PYBIN}" == *"cp39/"* ]] || \
49
+ [[ "${PYBIN}" == *"cp310/"* ]] ; then
50
+ if [[ "${PYBIN}" == *"cp313/"* ]] ; then
51
51
  "${PYBIN}/pip" install --pre -e /io/
52
52
  "${PYBIN}/pip" wheel /io/ --pre -w wheelhouse/
53
53
  else
@@ -3,6 +3,31 @@ Changelog
3
3
 
4
4
  For changes before version 3.0, see ``HISTORY.rst``.
5
5
 
6
+ 7.0 (2024-05-30)
7
+ ----------------
8
+
9
+ - Add preliminary support for Python 3.13 as of 3.13b1.
10
+
11
+ - Remove support for Python 3.7.
12
+
13
+ - Build Windows wheels on GHA.
14
+
15
+ - Make dict views (`.keys()`, `.items()` and `.values()`) behave like their
16
+ unrestricted versions.
17
+ (`#147 <https://github.com/zopefoundation/AccessControl/pull/147>`_)
18
+
19
+ - Make `.items()` validate each keys and values, like `.keys()` and
20
+ `.values()` do.
21
+
22
+ - Fix build errors on recent macOS versions.
23
+
24
+
25
+ 6.3 (2023-11-20)
26
+ ----------------
27
+
28
+ - Add support for Python 3.12.
29
+
30
+
6
31
  6.2 (2023-09-04)
7
32
  ----------------
8
33
 
@@ -5,7 +5,6 @@ include *.rst
5
5
  include *.txt
6
6
  include buildout.cfg
7
7
  include tox.ini
8
- include appveyor.yml
9
8
  include .coveragerc
10
9
 
11
10
  recursive-include src *.py
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: AccessControl
3
- Version: 6.2
3
+ Version: 7.0
4
4
  Summary: Security framework for Zope.
5
5
  Home-page: https://github.com/zopefoundation/AccessControl
6
6
  Author: Zope Foundation and Contributors
@@ -17,15 +17,35 @@ Classifier: License :: OSI Approved :: Zope Public License
17
17
  Classifier: Operating System :: OS Independent
18
18
  Classifier: Programming Language :: Python
19
19
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.7
21
20
  Classifier: Programming Language :: Python :: 3.8
22
21
  Classifier: Programming Language :: Python :: 3.9
23
22
  Classifier: Programming Language :: Python :: 3.10
24
23
  Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
25
26
  Classifier: Programming Language :: Python :: Implementation :: CPython
26
- Requires-Python: >=3.7
27
- Provides-Extra: test
27
+ Requires-Python: >=3.8
28
28
  License-File: LICENSE.txt
29
+ Requires-Dist: Acquisition
30
+ Requires-Dist: AuthEncoding
31
+ Requires-Dist: BTrees
32
+ Requires-Dist: DateTime
33
+ Requires-Dist: ExtensionClass>=4.2.1
34
+ Requires-Dist: Persistence>=3.0a3
35
+ Requires-Dist: RestrictedPython>=5.1
36
+ Requires-Dist: transaction
37
+ Requires-Dist: zExceptions
38
+ Requires-Dist: zope.component
39
+ Requires-Dist: zope.configuration
40
+ Requires-Dist: zope.deferredimport
41
+ Requires-Dist: zope.interface
42
+ Requires-Dist: zope.publisher
43
+ Requires-Dist: zope.schema
44
+ Requires-Dist: zope.security
45
+ Requires-Dist: zope.testing
46
+ Requires-Dist: funcsigs; python_version < "3.3"
47
+ Provides-Extra: test
48
+ Requires-Dist: zope.testrunner; extra == "test"
29
49
 
30
50
  .. image:: https://github.com/zopefoundation/AccessControl/actions/workflows/tests.yml/badge.svg
31
51
  :target: https://github.com/zopefoundation/AccessControl/actions/workflows/tests.yml
@@ -53,6 +73,31 @@ Changelog
53
73
 
54
74
  For changes before version 3.0, see ``HISTORY.rst``.
55
75
 
76
+ 7.0 (2024-05-30)
77
+ ----------------
78
+
79
+ - Add preliminary support for Python 3.13 as of 3.13b1.
80
+
81
+ - Remove support for Python 3.7.
82
+
83
+ - Build Windows wheels on GHA.
84
+
85
+ - Make dict views (`.keys()`, `.items()` and `.values()`) behave like their
86
+ unrestricted versions.
87
+ (`#147 <https://github.com/zopefoundation/AccessControl/pull/147>`_)
88
+
89
+ - Make `.items()` validate each keys and values, like `.keys()` and
90
+ `.values()` do.
91
+
92
+ - Fix build errors on recent macOS versions.
93
+
94
+
95
+ 6.3 (2023-11-20)
96
+ ----------------
97
+
98
+ - Add support for Python 3.12.
99
+
100
+
56
101
  6.2 (2023-09-04)
57
102
  ----------------
58
103
 
@@ -1,6 +1,3 @@
1
- [bdist_wheel]
2
- universal = 0
3
-
4
1
  [zest.releaser]
5
2
  create-wheel = no
6
3
 
@@ -32,7 +32,7 @@ ext_modules = [
32
32
  join('include', 'Acquisition', 'Acquisition.h')]),
33
33
  ]
34
34
 
35
- version = '6.2'
35
+ version = '7.0'
36
36
 
37
37
 
38
38
  setup(name='AccessControl',
@@ -60,11 +60,12 @@ setup(name='AccessControl',
60
60
  'Operating System :: OS Independent',
61
61
  'Programming Language :: Python',
62
62
  'Programming Language :: Python :: 3',
63
- 'Programming Language :: Python :: 3.7',
64
63
  'Programming Language :: Python :: 3.8',
65
64
  'Programming Language :: Python :: 3.9',
66
65
  'Programming Language :: Python :: 3.10',
67
66
  'Programming Language :: Python :: 3.11',
67
+ 'Programming Language :: Python :: 3.12',
68
+ 'Programming Language :: Python :: 3.13',
68
69
  'Programming Language :: Python :: Implementation :: CPython',
69
70
  ],
70
71
  ext_modules=ext_modules,
@@ -88,7 +89,7 @@ setup(name='AccessControl',
88
89
  'zope.testing',
89
90
  'funcsigs;python_version<"3.3"',
90
91
  ],
91
- python_requires='>=3.7',
92
+ python_requires='>=3.8',
92
93
  include_package_data=True,
93
94
  zip_safe=False,
94
95
  extras_require={
@@ -78,7 +78,8 @@ class SecurityInfo(Implicit):
78
78
  def _setaccess(self, names, access):
79
79
  for name in names:
80
80
  if self.names.get(name, access) != access:
81
- LOG.warn('Conflicting security declarations for "%s"' % name)
81
+ LOG.warning(
82
+ f'Conflicting security declarations for {name!r}')
82
83
  self._warnings = 1
83
84
  self.names[name] = access
84
85
 
@@ -159,8 +160,8 @@ class SecurityInfo(Implicit):
159
160
  for role in roles:
160
161
  rdict[role] = 1
161
162
  if self.roles.get(permission_name, rdict) != rdict:
162
- LOG.warn('Conflicting default role'
163
- 'declarations for permission "%s"' % permission_name)
163
+ LOG.warning('Conflicting default role'
164
+ ' declarations for permission "%s"' % permission_name)
164
165
  self._warnings = 1
165
166
  self.roles[permission_name] = rdict
166
167
 
@@ -248,8 +249,8 @@ class ClassSecurityInfo(SecurityInfo):
248
249
  access)
249
250
 
250
251
  if getattr(self, '_warnings', None):
251
- LOG.warn('Class "%s" had conflicting '
252
- 'security declarations' % classobj.__name__)
252
+ LOG.warning('Class "%s" had conflicting'
253
+ ' security declarations' % classobj.__name__)
253
254
 
254
255
 
255
256
  class ClassSecurityInformation(ClassSecurityInfo):
@@ -343,8 +344,8 @@ class _ModuleSecurityInfo(SecurityInfo):
343
344
  dict['__allow_access_to_unprotected_subobjects__'] = self
344
345
 
345
346
  if getattr(self, '_warnings', None):
346
- LOG.warn('Module "%s" had conflicting '
347
- 'security declarations' % dict['__name__'])
347
+ LOG.warning('Module "%s" had conflicting'
348
+ ' security declarations' % dict['__name__'])
348
349
 
349
350
  declareProtected__roles__ = ACCESS_PRIVATE
350
351
 
@@ -12,6 +12,7 @@
12
12
  ##############################################################################
13
13
 
14
14
 
15
+ import collections.abc
15
16
  import math
16
17
  import random
17
18
  import string
@@ -127,13 +128,18 @@ def get_dict_pop(d, name):
127
128
  return guarded_pop
128
129
 
129
130
 
130
- def get_iter(c, name):
131
- iter = getattr(c, name)
131
+ def get_mapping_view(c, name):
132
132
 
133
- def guarded_iter():
134
- return SafeIter(iter(), c)
133
+ view_class = {
134
+ 'keys': SafeKeysView,
135
+ 'items': SafeItemsView,
136
+ 'values': SafeValuesView,
137
+ }
135
138
 
136
- return guarded_iter
139
+ def guarded_mapping_view():
140
+ return view_class[name](c)
141
+
142
+ return guarded_mapping_view
137
143
 
138
144
 
139
145
  def get_list_pop(lst, name):
@@ -153,18 +159,15 @@ _dict_white_list = {
153
159
  'copy': 1,
154
160
  'fromkeys': 1,
155
161
  'get': get_dict_get,
156
- 'items': 1,
162
+ 'items': get_mapping_view,
163
+ 'keys': get_mapping_view,
157
164
  'pop': get_dict_pop,
158
165
  'popitem': 1,
159
166
  'setdefault': 1,
160
167
  'update': 1,
168
+ 'values': get_mapping_view,
161
169
  }
162
170
 
163
- _dict_white_list.update({
164
- 'keys': get_iter,
165
- 'values': get_iter,
166
- })
167
-
168
171
 
169
172
  def _check_dict_access(name, value):
170
173
  # Check whether value is a dict method
@@ -272,6 +275,40 @@ class NullIter(SafeIter):
272
275
  next = __next__
273
276
 
274
277
 
278
+ # The following three view classes are used only for mappings of type `dict`
279
+ # (not subclasses). Therefore, the mapping does not have security assertions
280
+ # and cannot acquire ones. As a consequence, the `guard` calls used in their
281
+ # methods verify that the checked key or value is accessible based solely on
282
+ # its own virtues, i.e. either because it is public or has its own security
283
+ # assertions allowing access.
284
+ class _SafeMappingView:
285
+ __allow_access_to_unprotected_subobjects__ = 1
286
+
287
+ def __iter__(self):
288
+ for e in super().__iter__():
289
+ guard(self._mapping, e)
290
+ yield e
291
+
292
+
293
+ class SafeKeysView(_SafeMappingView, collections.abc.KeysView):
294
+ pass
295
+
296
+
297
+ class SafeValuesView(_SafeMappingView, collections.abc.ValuesView):
298
+ pass
299
+
300
+
301
+ class SafeItemsView(_SafeMappingView, collections.abc.ItemsView):
302
+ def __iter__(self):
303
+ for k, v in super().__iter__():
304
+ guard(self._mapping, k)
305
+ # When checking the value, we check the guard with index=None,
306
+ # not with index=k, the key name does not matter. guard just
307
+ # needs to verify that the value itself can be accessed.
308
+ guard(self._mapping, v)
309
+ yield k, v
310
+
311
+
275
312
  def _error(index):
276
313
  raise Unauthorized('unauthorized access to element')
277
314
 
@@ -425,7 +425,7 @@ static PyExtensionClass ZopeSecurityPolicyType = {
425
425
  0, /* tp_itemsize */
426
426
  /* Standard methods */
427
427
  (destructor) ZopeSecurityPolicy_dealloc,/* tp_dealloc */
428
- NULL, /* tp_print */
428
+ 0, /* tp_vectorcall_offset */
429
429
  NULL, /* tp_getattr */
430
430
  NULL, /* tp_setattr */
431
431
  NULL, /* tp_compare */
@@ -484,7 +484,7 @@ static PyExtensionClass SecurityManagerType = {
484
484
  0, /* tp_itemsize */
485
485
  /* Standard methods */
486
486
  (destructor) SecurityManager_dealloc,/* tp_dealloc */
487
- NULL, /* tp_print */
487
+ 0, /* tp_vectorcall_offset*/
488
488
  NULL, /* tp_getattr */
489
489
  NULL, /* tp_setattr */
490
490
  NULL, /* tp_compare */
@@ -543,7 +543,7 @@ static PyExtensionClass PermissionRoleType = {
543
543
  0, /* tp_itemsize */
544
544
  /* Standard methods */
545
545
  (destructor) PermissionRole_dealloc, /* tp_dealloc */
546
- NULL, /* tp_print */
546
+ 0, /* tp_vectorcall_offset */
547
547
  NULL, /* tp_getattr */
548
548
  NULL, /* tp_setattr */
549
549
  NULL, /* tp_compare */
@@ -613,7 +613,7 @@ static PyExtensionClass imPermissionRoleType = {
613
613
  0, /* tp_itemsize */
614
614
  /* Standard methods */
615
615
  (destructor) imPermissionRole_dealloc, /* tp_dealloc */
616
- NULL, /* tp_print */
616
+ 0, /* tp_vectorcall_offset */
617
617
  NULL, /* tp_getattr */
618
618
  NULL, /* tp_setattr */
619
619
  NULL, /* tp_compare */
@@ -1071,7 +1071,7 @@ static PyObject *ZopeSecurityPolicy_validate(PyObject *self, PyObject *args) {
1071
1071
  **| try:
1072
1072
  **| if roles is None or 'Anonymous' in roles: return 1
1073
1073
  **| except TypeError:
1074
- **| LOG.warn('"%s' passed as roles"
1074
+ **| LOG.warning('"%s' passed as roles"
1075
1075
  **| " during validation of '%s' is not a sequence." %
1076
1076
  **| ('roles', name))
1077
1077
  **| raise
@@ -5,4 +5,4 @@ from logging import getLogger
5
5
 
6
6
 
7
7
  LOG = getLogger('AccessControl')
8
- warn = LOG.warn
8
+ warn = LOG.warning
@@ -123,6 +123,39 @@ def f7():
123
123
  access = getattr(d, meth)
124
124
  result = sorted(access())
125
125
  assert result == expected[kind], (meth, kind, result, expected[kind])
126
+ assert len(access()) == len(expected[kind]), (meth, kind, "len")
127
+ iter_ = access() # iterate twice on the same view
128
+ assert list(iter_) == list(iter_)
129
+
130
+ assert sorted([k for k in getattr(d, meth)()]) == expected[kind]
131
+ assert sorted(k for k in getattr(d, meth)()) == expected[kind]
132
+ assert {k: v for k, v in d.items()} == d
133
+
134
+ assert 1 in d
135
+ assert 1 in d.keys()
136
+ assert 2 in d.values()
137
+ assert (1, 2) in d.items()
138
+
139
+ assert d
140
+ assert d.keys()
141
+ assert d.values()
142
+ assert d.items()
143
+
144
+ empty_d = {}
145
+ assert not empty_d
146
+ assert not empty_d.keys()
147
+ assert not empty_d.values()
148
+ assert not empty_d.items()
149
+
150
+ smaller_d = {1: 2}
151
+ for m, _ in methods:
152
+ assert getattr(d, m)() != getattr(smaller_d, m)()
153
+ assert not getattr(d, m)() == getattr(smaller_d, m)()
154
+ if m != 'values':
155
+ assert getattr(d, m)() > getattr(smaller_d, m)()
156
+ assert getattr(d, m)() >= getattr(smaller_d, m)()
157
+ assert getattr(smaller_d, m)() < getattr(d, m)()
158
+ assert getattr(smaller_d, m)() <= getattr(d, m)()
126
159
 
127
160
 
128
161
  f7()
@@ -258,23 +258,40 @@ class TestDictGuards(GuardTestCase):
258
258
  self.assertTrue(sm.calls)
259
259
 
260
260
  def test_keys_empty(self):
261
- from AccessControl.ZopeGuards import get_iter
262
- keys = get_iter({}, 'keys')
261
+ from AccessControl.ZopeGuards import get_mapping_view
262
+ keys = get_mapping_view({}, 'keys')
263
263
  self.assertEqual(list(keys()), [])
264
264
 
265
+ def test_kvi_len(self):
266
+ from AccessControl.ZopeGuards import get_mapping_view
267
+ for attr in ("keys", "values", "items"):
268
+ with self.subTest(attr):
269
+ view = get_mapping_view({'a': 1}, attr)
270
+ self.assertEqual(len(view()), 1)
271
+
265
272
  def test_keys_validates(self):
266
273
  sm = SecurityManager()
267
274
  old = self.setSecurityManager(sm)
268
275
  keys = guarded_getattr({GuardTestCase: 1}, 'keys')
269
276
  try:
270
- next(keys())
277
+ next(iter(keys()))
271
278
  finally:
272
279
  self.setSecurityManager(old)
273
280
  self.assertTrue(sm.calls)
274
281
 
282
+ def test_items_validates(self):
283
+ sm = SecurityManager()
284
+ old = self.setSecurityManager(sm)
285
+ items = guarded_getattr({GuardTestCase: GuardTestCase}, 'items')
286
+ try:
287
+ next(iter(items()))
288
+ finally:
289
+ self.setSecurityManager(old)
290
+ self.assertEqual(len(sm.calls), 2)
291
+
275
292
  def test_values_empty(self):
276
- from AccessControl.ZopeGuards import get_iter
277
- values = get_iter({}, 'values')
293
+ from AccessControl.ZopeGuards import get_mapping_view
294
+ values = get_mapping_view({}, 'values')
278
295
  self.assertEqual(list(values()), [])
279
296
 
280
297
  def test_values_validates(self):
@@ -282,18 +299,17 @@ class TestDictGuards(GuardTestCase):
282
299
  old = self.setSecurityManager(sm)
283
300
  values = guarded_getattr({GuardTestCase: 1}, 'values')
284
301
  try:
285
- next(values())
302
+ next(iter(values()))
286
303
  finally:
287
304
  self.setSecurityManager(old)
288
305
  self.assertTrue(sm.calls)
289
306
 
290
307
  def test_kvi_iteration(self):
291
- from AccessControl.ZopeGuards import SafeIter
292
308
  d = dict(a=1, b=2)
293
309
  for attr in ("keys", "values", "items"):
294
310
  v = getattr(d, attr)()
295
- si = SafeIter(v)
296
- self.assertEqual(next(si), next(iter(v)))
311
+ si = guarded_getattr(d, attr)()
312
+ self.assertEqual(next(iter(si)), next(iter(v)))
297
313
 
298
314
 
299
315
  class TestListGuards(GuardTestCase):
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: AccessControl
3
- Version: 6.2
3
+ Version: 7.0
4
4
  Summary: Security framework for Zope.
5
5
  Home-page: https://github.com/zopefoundation/AccessControl
6
6
  Author: Zope Foundation and Contributors
@@ -17,15 +17,35 @@ Classifier: License :: OSI Approved :: Zope Public License
17
17
  Classifier: Operating System :: OS Independent
18
18
  Classifier: Programming Language :: Python
19
19
  Classifier: Programming Language :: Python :: 3
20
- Classifier: Programming Language :: Python :: 3.7
21
20
  Classifier: Programming Language :: Python :: 3.8
22
21
  Classifier: Programming Language :: Python :: 3.9
23
22
  Classifier: Programming Language :: Python :: 3.10
24
23
  Classifier: Programming Language :: Python :: 3.11
24
+ Classifier: Programming Language :: Python :: 3.12
25
+ Classifier: Programming Language :: Python :: 3.13
25
26
  Classifier: Programming Language :: Python :: Implementation :: CPython
26
- Requires-Python: >=3.7
27
- Provides-Extra: test
27
+ Requires-Python: >=3.8
28
28
  License-File: LICENSE.txt
29
+ Requires-Dist: Acquisition
30
+ Requires-Dist: AuthEncoding
31
+ Requires-Dist: BTrees
32
+ Requires-Dist: DateTime
33
+ Requires-Dist: ExtensionClass>=4.2.1
34
+ Requires-Dist: Persistence>=3.0a3
35
+ Requires-Dist: RestrictedPython>=5.1
36
+ Requires-Dist: transaction
37
+ Requires-Dist: zExceptions
38
+ Requires-Dist: zope.component
39
+ Requires-Dist: zope.configuration
40
+ Requires-Dist: zope.deferredimport
41
+ Requires-Dist: zope.interface
42
+ Requires-Dist: zope.publisher
43
+ Requires-Dist: zope.schema
44
+ Requires-Dist: zope.security
45
+ Requires-Dist: zope.testing
46
+ Requires-Dist: funcsigs; python_version < "3.3"
47
+ Provides-Extra: test
48
+ Requires-Dist: zope.testrunner; extra == "test"
29
49
 
30
50
  .. image:: https://github.com/zopefoundation/AccessControl/actions/workflows/tests.yml/badge.svg
31
51
  :target: https://github.com/zopefoundation/AccessControl/actions/workflows/tests.yml
@@ -53,6 +73,31 @@ Changelog
53
73
 
54
74
  For changes before version 3.0, see ``HISTORY.rst``.
55
75
 
76
+ 7.0 (2024-05-30)
77
+ ----------------
78
+
79
+ - Add preliminary support for Python 3.13 as of 3.13b1.
80
+
81
+ - Remove support for Python 3.7.
82
+
83
+ - Build Windows wheels on GHA.
84
+
85
+ - Make dict views (`.keys()`, `.items()` and `.values()`) behave like their
86
+ unrestricted versions.
87
+ (`#147 <https://github.com/zopefoundation/AccessControl/pull/147>`_)
88
+
89
+ - Make `.items()` validate each keys and values, like `.keys()` and
90
+ `.values()` do.
91
+
92
+ - Fix build errors on recent macOS versions.
93
+
94
+
95
+ 6.3 (2023-11-20)
96
+ ----------------
97
+
98
+ - Add support for Python 3.12.
99
+
100
+
56
101
  6.2 (2023-09-04)
57
102
  ----------------
58
103
 
@@ -8,7 +8,6 @@ HISTORY.rst
8
8
  LICENSE.txt
9
9
  MANIFEST.in
10
10
  README.rst
11
- appveyor.yml
12
11
  buildout.cfg
13
12
  setup.cfg
14
13
  setup.py
@@ -4,21 +4,24 @@
4
4
  minversion = 4.0
5
5
  envlist =
6
6
  lint
7
- py37,py37-pure
8
7
  py38,py38-pure
9
8
  py39,py39-pure
10
9
  py310,py310-pure
11
10
  py311,py311-pure
12
11
  py312,py312-pure
12
+ py313,py313-pure
13
13
  coverage
14
14
 
15
15
  [testenv]
16
16
  usedevelop = true
17
- pip_pre = py312: true
17
+ pip_pre = py313: true
18
18
  deps =
19
+ setuptools < 69
19
20
  setenv =
20
21
  pure: PURE_PYTHON=1
21
22
  !pure-!pypy3: PURE_PYTHON=0
23
+ py312: VIRTUALENV_PIP=23.1.2
24
+ py312: PIP_REQUIRE_VIRTUALENV=0
22
25
  commands =
23
26
  zope-testrunner --test-path=src {posargs:-vc}
24
27
  extras =
@@ -37,21 +40,32 @@ commands =
37
40
  coverage run -m zope.testrunner --test-path=src {posargs:-vc}
38
41
  coverage html -i
39
42
  coverage report -i -m --fail-under=80
43
+ [testenv:release-check]
44
+ description = ensure that the distribution is ready to release
45
+ basepython = python3
46
+ skip_install = true
47
+ deps =
48
+ twine
49
+ build
50
+ check-manifest
51
+ check-python-versions >= 0.20.0
52
+ wheel
53
+ commands_pre =
54
+ commands =
55
+ check-manifest
56
+ check-python-versions --only setup.py,tox.ini,.github/workflows/tests.yml
57
+ python -m build --sdist --no-isolation
58
+ twine check dist/*
40
59
 
41
60
  [testenv:lint]
42
61
  basepython = python3
43
62
  skip_install = true
63
+ deps =
64
+ isort
65
+ flake8
44
66
  commands =
45
67
  isort --check-only --diff {toxinidir}/src {toxinidir}/setup.py
46
68
  flake8 src setup.py
47
- check-manifest
48
- check-python-versions
49
- deps =
50
- check-manifest
51
- check-python-versions >= 0.19.1
52
- wheel
53
- flake8
54
- isort
55
69
 
56
70
  [testenv:isort-apply]
57
71
  basepython = python3
@@ -1,52 +0,0 @@
1
- # Generated from:
2
- # https://github.com/zopefoundation/meta/tree/master/config/c-code
3
- environment:
4
- # Currently the builds use @dataflake's Appveyor account. The PyPI token belongs
5
- # to zope.wheelbuilder, which is managed by @mgedmin and @dataflake.
6
-
7
- global:
8
- TWINE_USERNAME: __token__
9
- TWINE_PASSWORD:
10
- secure: vSlDBj79vziJOA5k3z16r1OSr/7Jq6uCf23VKErSsXWb2dGJMUxR6GQ6tRs53GfiyxBQdpdfOA5QuVS4G4W3rVLwD/YXCidpidwBF3pKk4J2Nnk88HpZID6lQOV713DA/kkEuoO97Ty1BRYeaca9bA0P0KmRYU7Iy30p4xBUnmNKYnfilH0/waASYEDwpkrl49DiUh1+bMQjE5LKIBeaF0LLquzHGYETQf4BgpywUIV/8dQnc0vL/RXCa6PrWOxg/8S6ponIYyJ32Y4OoprZ1Q==
11
-
12
- matrix:
13
- - python: 37-x64
14
- - python: 38-x64
15
- - python: 39-x64
16
- - python: 310-x64
17
- - python: 311-x64
18
- # `multibuild` cannot install non-final versions as they are not on
19
- # ftp.python.org, so we skip Python 3.11 until its final release:
20
- # - python: 312-x64
21
-
22
- install:
23
- - "SET PYTHONVERSION=%PYTHON%"
24
- - "SET PATH=C:\\Python%PYTHON%;c:\\Python%PYTHON%\\scripts;%PATH%"
25
- - ps: |
26
- $env:PYTHON = "C:\\Python${env:PYTHON}"
27
- if (-not (Test-Path $env:PYTHON)) {
28
- curl -o install_python.ps1 https://raw.githubusercontent.com/matthew-brett/multibuild/11a389d78892cf90addac8f69433d5e22bfa422a/install_python.ps1
29
- .\install_python.ps1
30
- }
31
- - ps: if (-not (Test-Path $env:PYTHON)) { throw "No $env:PYTHON" }
32
- - echo "C:\Program Files\Microsoft SDKs\Windows\v7.1\Bin\SetEnv.cmd" /x64 > "C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\bin\amd64\vcvars64.bat"
33
- - python -m pip install -U pip
34
- - pip install -U setuptools wheel
35
- - pip install -U -e .[test]
36
-
37
- matrix:
38
- fast_finish: true
39
-
40
- build_script:
41
- - python -W ignore setup.py -q bdist_wheel
42
-
43
- test_script:
44
- - zope-testrunner --test-path=src
45
- artifacts:
46
- - path: 'dist\*.whl'
47
- name: wheel
48
-
49
- deploy_script:
50
- - ps: if ($env:APPVEYOR_REPO_TAG -eq $TRUE) { pip install twine; twine upload --skip-existing dist\*.whl }
51
-
52
- deploy: on
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes