pypi package 'zope-app-component'

Popularity: Low
Description: Local Zope Component Support
Installation: pip install zope-app-component
Last version: 5.0 (Download)
Homepage: https://github.com/zopefoundation/zope.app.component
Size: 30.44 kB
License: ZPL 2.1
Keywords: zope, component, architecture, local

Activity

Last modified: February 21, 2023 7:44 AM (7 months ago)
Versions released in one year: 1
Weekly downloads: 122
10/02/202212/18/202203/05/202305/21/202308/06/202306012018024001234released versions / week
  • Versions released
  • Weekly downloads

What's new in version 5.0

Delta between version 4.1.0 and version 5.0

Source: Github
Commits:
  • 4c1eb69d1ab15a53ef16adc9dfe7ad52f38d74b6, October 22, 2018 12:36 PM:
    Back to development: 4.1.1
  • e186b59d134b527897943becb688a6f57e0e8056, May 14, 2020 12:46 PM:
    Modernize Python versions.
    
    - Add support for Python 3.8.
    
    - Drop support for Python 3.4.
    
    modified:   .travis.yml
    modified:   CHANGES.rst
    modified:   setup.py
    modified:   tox.ini
  • 11a6367507b8995f4ce05bbf669b98499bb07544, April 19, 2021 6:47 AM:
    Configuring for pure-python
  • 0b886692c927345f7847c188c0b2aec6c55690de, April 19, 2021 6:47 AM:
    Lint the code.
    
    Add support for Python 3.9.
  • f418554828db8a6ef71c8d223521d43f0c00842e, February 21, 2023 7:42 AM:
    Config with pure python template 0b886692 (#8)
    
    * Bumped version for breaking release.
    
    * Drop support for Python 2.7, 3.5, 3.6.
    
    * Add support for Python 3.10, 3.11.
  • 064301d2e039cd6559f13237f8181e630090ebaf, February 21, 2023 7:43 AM:
    Garden change log.
  • e9dd20c40fe000893fd5228a5edadec49870c13d, February 21, 2023 7:44 AM:
    Preparing release 5.0
Files changed:
.coveragerc CHANGED
@@ -1,6 +0,0 @@
1
- [run]
2
- source = src
3
-
4
- [report]
5
- exclude_lines =
6
- pragma: no cover
 
 
 
 
 
 
.editorconfig CHANGED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
+ #
4
+ # EditorConfig Configuration file, for more details see:
5
+ # http://EditorConfig.org
6
+ # EditorConfig is a convention description, that could be interpreted
7
+ # by multiple editors to enforce common coding conventions for specific
8
+ # file types
9
+
10
+ # top-most EditorConfig file:
11
+ # Will ignore other EditorConfig files in Home directory or upper tree level.
12
+ root = true
13
+
14
+
15
+ [*] # For All Files
16
+ # Unix-style newlines with a newline ending every file
17
+ end_of_line = lf
18
+ insert_final_newline = true
19
+ trim_trailing_whitespace = true
20
+ # Set default charset
21
+ charset = utf-8
22
+ # Indent style default
23
+ indent_style = space
24
+ # Max Line Length - a hard line wrap, should be disabled
25
+ max_line_length = off
26
+
27
+ [*.{py,cfg,ini}]
28
+ # 4 space indentation
29
+ indent_size = 4
30
+
31
+ [*.{yml,zpt,pt,dtml,zcml}]
32
+ # 2 space indentation
33
+ indent_size = 2
34
+
35
+ [{Makefile,.gitmodules}]
36
+ # Tab indentation (no size specified, but view as 4 spaces)
37
+ indent_style = tab
38
+ indent_size = unset
39
+ tab_width = unset
.github/workflows/tests.yml CHANGED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
+ name: tests
4
+
5
+ on:
6
+ push:
7
+ pull_request:
8
+ schedule:
9
+ - cron: '0 12 * * 0' # run once a week on Sunday
10
+ # Allow to run this workflow manually from the Actions tab
11
+ workflow_dispatch:
12
+
13
+ jobs:
14
+ build:
15
+ strategy:
16
+ # We want to see all failures:
17
+ fail-fast: false
18
+ matrix:
19
+ os:
20
+ - ["ubuntu", "ubuntu-20.04"]
21
+ config:
22
+ # [Python version, tox env]
23
+ - ["3.9", "lint"]
24
+ - ["3.7", "py37"]
25
+ - ["3.8", "py38"]
26
+ - ["3.9", "py39"]
27
+ - ["3.10", "py310"]
28
+ - ["3.11", "py311"]
29
+ - ["pypy-3.9", "pypy3"]
30
+ - ["3.9", "coverage"]
31
+
32
+ runs-on: ${{ matrix.os[1] }}
33
+ if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name != github.event.pull_request.base.repo.full_name
34
+ name: ${{ matrix.config[1] }}
35
+ steps:
36
+ - uses: actions/checkout@v3
37
+ - name: Set up Python
38
+ uses: actions/setup-python@v4
39
+ with:
40
+ python-version: ${{ matrix.config[0] }}
41
+ - name: Pip cache
42
+ uses: actions/cache@v3
43
+ with:
44
+ path: ~/.cache/pip
45
+ key: ${{ runner.os }}-pip-${{ matrix.config[0] }}-${{ hashFiles('setup.*', 'tox.ini') }}
46
+ restore-keys: |
47
+ ${{ runner.os }}-pip-${{ matrix.config[0] }}-
48
+ ${{ runner.os }}-pip-
49
+ - name: Install dependencies
50
+ run: |
51
+ python -m pip install --upgrade pip
52
+ pip install tox
53
+ - name: Test
54
+ run: tox -e ${{ matrix.config[1] }}
55
+ - name: Coverage
56
+ if: matrix.config[1] == 'coverage'
57
+ run: |
58
+ pip install coveralls
59
+ coveralls --service=github
60
+ env:
61
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
.gitignore CHANGED
@@ -1,13 +1,32 @@
1
- bin/
2
- eggs/
3
- develop-eggs/
4
- parts/
 
 
 
 
 
 
 
5
  .installed.cfg
6
- *.py[co]
 
 
7
  __pycache__/
 
8
  build/
 
 
 
9
  dist/
10
- *.egg-info/
11
- .tox/
12
- .coverage
13
- htmlcov
 
 
 
 
 
 
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
+ *.dll
4
+ *.egg-info/
5
+ *.profraw
6
+ *.pyc
7
+ *.pyo
8
+ *.so
9
+ .coverage
10
+ .coverage.*
11
+ .eggs/
12
  .installed.cfg
13
+ .mr.developer.cfg
14
+ .tox/
15
+ .vscode/
16
  __pycache__/
17
+ bin/
18
  build/
19
+ coverage.xml
20
+ develop-eggs/
21
+ develop/
22
  dist/
23
+ docs/_build
24
+ eggs/
25
+ etc/
26
+ lib/
27
+ lib64
28
+ log/
29
+ parts/
30
+ pyvenv.cfg
31
+ testing.log
32
+ var/
.meta.toml CHANGED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
+ [meta]
4
+ template = "pure-python"
5
+ commit-id = "20a50c67"
6
+
7
+ [python]
8
+ with-pypy = true
9
+ with-sphinx-doctests = false
10
+ with-future-python = false
11
+ with-macos = false
12
+ with-windows = false
13
+
14
+ [tox]
15
+ use-flake8 = true
16
+
17
+ [coverage]
18
+ fail-under = 97
19
+
20
+ [flake8]
21
+ additional-config = [
22
+ "# F401 imported but unused",
23
+ "per-file-ignores =",
24
+ " src/zope/app/component/__init__.py: F401",
25
+ " src/zope/app/component/contentdirective.py: F401",
26
+ " src/zope/app/component/hooks.py: F401",
27
+ " src/zope/app/component/interfaces/__init__.py: F401",
28
+ " src/zope/app/component/metaconfigure.py: F401",
29
+ " src/zope/app/component/metadirectives.py: F401",
30
+ " src/zope/app/component/site.py: F401",
31
+ " src/zope/app/component/vocabulary.py: F401",
32
+ ]
33
+
34
+ [manifest]
35
+ additional-rules = [
36
+ "recursive-include src *.pt",
37
+ "recursive-include src *.rst",
38
+ "recursive-include src *.zcml",
39
+ ]
.travis.yml CHANGED
@@ -1,32 +0,0 @@
1
- language: python
2
- sudo: false
3
- python:
4
- - 2.7
5
- - 3.4
6
- - 3.5
7
- - 3.6
8
- - pypy
9
- - pypy3
10
- matrix:
11
- include:
12
- - python: "3.7"
13
- dist: xenial
14
- sudo: true
15
- script:
16
- - coverage run -m zope.testrunner --test-path=src --auto-color --auto-progress
17
-
18
- after_success:
19
- - coveralls
20
- notifications:
21
- email: false
22
-
23
- install:
24
- - pip install -U pip setuptools
25
- - pip install -U coveralls coverage
26
- - pip install -U -e ".[test]"
27
-
28
-
29
- cache: pip
30
-
31
- before_cache:
32
- - rm -f $HOME/.cache/pip/log/debug.log
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
CHANGES.rst CHANGED
@@ -2,6 +2,21 @@
2
  CHANGES
3
  =======
4
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  4.1.0 (2018-10-22)
6
  ------------------
7
 
2
  CHANGES
3
  =======
4
 
5
+ 5.0 (2023-02-21)
6
+ ----------------
7
+
8
+ - Add support for Python 3.8, 3.9, 3.10, 3.11.
9
+
10
+ - Drop support for Python 2.7, 3.4, 3.5, 3.6.
11
+
12
+ - Remove deprecated:
13
+
14
+ - ``zope.app.component.getNextUtility`` (import from ``zope.site``)
15
+ - ``zope.app.component.queryNextUtility`` (import from ``zope.site``)
16
+ - ``zope.app.component.getNextSiteManager`` (no replacement)
17
+ - ``zope.app.component.queryNextSiteManager`` (no replacement)
18
+
19
+
20
  4.1.0 (2018-10-22)
21
  ------------------
22
 
CONTRIBUTING.md CHANGED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <!--
2
+ Generated from:
3
+ https://github.com/zopefoundation/meta/tree/master/config/pure-python
4
+ -->
5
+ # Contributing to zopefoundation projects
6
+
7
+ The projects under the zopefoundation GitHub organization are open source and
8
+ welcome contributions in different forms:
9
+
10
+ * bug reports
11
+ * code improvements and bug fixes
12
+ * documentation improvements
13
+ * pull request reviews
14
+
15
+ For any changes in the repository besides trivial typo fixes you are required
16
+ to sign the contributor agreement. See
17
+ https://www.zope.dev/developer/becoming-a-committer.html for details.
18
+
19
+ Please visit our [Developer
20
+ Guidelines](https://www.zope.dev/developer/guidelines.html) if you'd like to
21
+ contribute code changes and our [guidelines for reporting
22
+ bugs](https://www.zope.dev/developer/reporting-bugs.html) if you want to file a
23
+ bug report.
MANIFEST.in CHANGED
@@ -1,10 +1,12 @@
1
- include *.py
2
- include *.txt
 
3
  include *.rst
 
4
  include buildout.cfg
5
- include setup.cfg
6
- include .coveragerc
7
  include tox.ini
 
 
8
  recursive-include src *.pt
9
  recursive-include src *.rst
10
  recursive-include src *.zcml
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
+ include *.md
4
  include *.rst
5
+ include *.txt
6
  include buildout.cfg
 
 
7
  include tox.ini
8
+
9
+ recursive-include src *.py
10
  recursive-include src *.pt
11
  recursive-include src *.rst
12
  recursive-include src *.zcml
bootstrap.py CHANGED
@@ -1,210 +0,0 @@
1
- ##############################################################################
2
- #
3
- # Copyright (c) 2006 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
- """Bootstrap a buildout-based project
15
-
16
- Simply run this script in a directory containing a buildout.cfg.
17
- The script accepts buildout command-line options, so you can
18
- use the -c option to specify an alternate configuration file.
19
- """
20
-
21
- import os
22
- import shutil
23
- import sys
24
- import tempfile
25
-
26
- from optparse import OptionParser
27
-
28
- __version__ = '2015-07-01'
29
- # See zc.buildout's changelog if this version is up to date.
30
-
31
- tmpeggs = tempfile.mkdtemp(prefix='bootstrap-')
32
-
33
- usage = '''\
34
- [DESIRED PYTHON FOR BUILDOUT] bootstrap.py [options]
35
-
36
- Bootstraps a buildout-based project.
37
-
38
- Simply run this script in a directory containing a buildout.cfg, using the
39
- Python that you want bin/buildout to use.
40
-
41
- Note that by using --find-links to point to local resources, you can keep
42
- this script from going over the network.
43
- '''
44
-
45
- parser = OptionParser(usage=usage)
46
- parser.add_option("--version",
47
- action="store_true", default=False,
48
- help=("Return bootstrap.py version."))
49
- parser.add_option("-t", "--accept-buildout-test-releases",
50
- dest='accept_buildout_test_releases',
51
- action="store_true", default=False,
52
- help=("Normally, if you do not specify a --version, the "
53
- "bootstrap script and buildout gets the newest "
54
- "*final* versions of zc.buildout and its recipes and "
55
- "extensions for you. If you use this flag, "
56
- "bootstrap and buildout will get the newest releases "
57
- "even if they are alphas or betas."))
58
- parser.add_option("-c", "--config-file",
59
- help=("Specify the path to the buildout configuration "
60
- "file to be used."))
61
- parser.add_option("-f", "--find-links",
62
- help=("Specify a URL to search for buildout releases"))
63
- parser.add_option("--allow-site-packages",
64
- action="store_true", default=False,
65
- help=("Let bootstrap.py use existing site packages"))
66
- parser.add_option("--buildout-version",
67
- help="Use a specific zc.buildout version")
68
- parser.add_option("--setuptools-version",
69
- help="Use a specific setuptools version")
70
- parser.add_option("--setuptools-to-dir",
71
- help=("Allow for re-use of existing directory of "
72
- "setuptools versions"))
73
-
74
- options, args = parser.parse_args()
75
- if options.version:
76
- print("bootstrap.py version %s" % __version__)
77
- sys.exit(0)
78
-
79
-
80
- ######################################################################
81
- # load/install setuptools
82
-
83
- try:
84
- from urllib.request import urlopen
85
- except ImportError:
86
- from urllib2 import urlopen
87
-
88
- ez = {}
89
- if os.path.exists('ez_setup.py'):
90
- exec(open('ez_setup.py').read(), ez)
91
- else:
92
- exec(urlopen('https://bootstrap.pypa.io/ez_setup.py').read(), ez)
93
-
94
- if not options.allow_site_packages:
95
- # ez_setup imports site, which adds site packages
96
- # this will remove them from the path to ensure that incompatible versions
97
- # of setuptools are not in the path
98
- import site
99
- # inside a virtualenv, there is no 'getsitepackages'.
100
- # We can't remove these reliably
101
- if hasattr(site, 'getsitepackages'):
102
- for sitepackage_path in site.getsitepackages():
103
- # Strip all site-packages directories from sys.path that
104
- # are not sys.prefix; this is because on Windows
105
- # sys.prefix is a site-package directory.
106
- if sitepackage_path != sys.prefix:
107
- sys.path[:] = [x for x in sys.path
108
- if sitepackage_path not in x]
109
-
110
- setup_args = dict(to_dir=tmpeggs, download_delay=0)
111
-
112
- if options.setuptools_version is not None:
113
- setup_args['version'] = options.setuptools_version
114
- if options.setuptools_to_dir is not None:
115
- setup_args['to_dir'] = options.setuptools_to_dir
116
-
117
- ez['use_setuptools'](**setup_args)
118
- import setuptools
119
- import pkg_resources
120
-
121
- # This does not (always?) update the default working set. We will
122
- # do it.
123
- for path in sys.path:
124
- if path not in pkg_resources.working_set.entries:
125
- pkg_resources.working_set.add_entry(path)
126
-
127
- ######################################################################
128
- # Install buildout
129
-
130
- ws = pkg_resources.working_set
131
-
132
- setuptools_path = ws.find(
133
- pkg_resources.Requirement.parse('setuptools')).location
134
-
135
- # Fix sys.path here as easy_install.pth added before PYTHONPATH
136
- cmd = [sys.executable, '-c',
137
- 'import sys; sys.path[0:0] = [%r]; ' % setuptools_path +
138
- 'from setuptools.command.easy_install import main; main()',
139
- '-mZqNxd', tmpeggs]
140
-
141
- find_links = os.environ.get(
142
- 'bootstrap-testing-find-links',
143
- options.find_links or
144
- ('http://downloads.buildout.org/'
145
- if options.accept_buildout_test_releases else None)
146
- )
147
- if find_links:
148
- cmd.extend(['-f', find_links])
149
-
150
- requirement = 'zc.buildout'
151
- version = options.buildout_version
152
- if version is None and not options.accept_buildout_test_releases:
153
- # Figure out the most recent final version of zc.buildout.
154
- import setuptools.package_index
155
- _final_parts = '*final-', '*final'
156
-
157
- def _final_version(parsed_version):
158
- try:
159
- return not parsed_version.is_prerelease
160
- except AttributeError:
161
- # Older setuptools
162
- for part in parsed_version:
163
- if (part[:1] == '*') and (part not in _final_parts):
164
- return False
165
- return True
166
-
167
- index = setuptools.package_index.PackageIndex(
168
- search_path=[setuptools_path])
169
- if find_links:
170
- index.add_find_links((find_links,))
171
- req = pkg_resources.Requirement.parse(requirement)
172
- if index.obtain(req) is not None:
173
- best = []
174
- bestv = None
175
- for dist in index[req.project_name]:
176
- distv = dist.parsed_version
177
- if _final_version(distv):
178
- if bestv is None or distv > bestv:
179
- best = [dist]
180
- bestv = distv
181
- elif distv == bestv:
182
- best.append(dist)
183
- if best:
184
- best.sort()
185
- version = best[-1].version
186
- if version:
187
- requirement = '=='.join((requirement, version))
188
- cmd.append(requirement)
189
-
190
- import subprocess
191
- if subprocess.call(cmd) != 0:
192
- raise Exception(
193
- "Failed to execute command:\n%s" % repr(cmd)[1:-1])
194
-
195
- ######################################################################
196
- # Import and run buildout
197
-
198
- ws.add_entry(tmpeggs)
199
- ws.require(requirement)
200
- import zc.buildout.buildout
201
-
202
- if not [a for a in args if '=' not in a]:
203
- args.append('bootstrap')
204
-
205
- # if -c was provided, we push it back into args for buildout' main function
206
- if options.config_file is not None:
207
- args[0:0] = ['-c', options.config_file]
208
-
209
- zc.buildout.buildout.main(args)
210
- shutil.rmtree(tmpeggs)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
buildout.cfg CHANGED
@@ -1,18 +0,0 @@
1
- [buildout]
2
- develop = .
3
- parts = test coverage-test coverage-report
4
-
5
- [test]
6
- recipe = zc.recipe.testrunner
7
- eggs = zope.app.component [test]
8
-
9
- [coverage-test]
10
- recipe = zc.recipe.testrunner
11
- eggs = zope.app.component [test]
12
- defaults = ['--coverage', '../../coverage']
13
-
14
- [coverage-report]
15
- recipe = zc.recipe.egg
16
- eggs = z3c.coverage
17
- scripts = coverage=coverage-report
18
- arguments = ('coverage', 'coverage/report')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
setup.cfg CHANGED
@@ -1,2 +1,33 @@
 
 
1
  [bdist_wheel]
2
- universal = 1
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
  [bdist_wheel]
4
+ universal = 0
5
+
6
+ [flake8]
7
+ doctests = 1
8
+ # F401 imported but unused
9
+ per-file-ignores =
10
+ src/zope/app/component/__init__.py: F401
11
+ src/zope/app/component/contentdirective.py: F401
12
+ src/zope/app/component/hooks.py: F401
13
+ src/zope/app/component/interfaces/__init__.py: F401
14
+ src/zope/app/component/metaconfigure.py: F401
15
+ src/zope/app/component/metadirectives.py: F401
16
+ src/zope/app/component/site.py: F401
17
+ src/zope/app/component/vocabulary.py: F401
18
+
19
+ [check-manifest]
20
+ ignore =
21
+ .editorconfig
22
+ .meta.toml
23
+
24
+ [isort]
25
+ force_single_line = True
26
+ combine_as_imports = True
27
+ sections = FUTURE,STDLIB,THIRDPARTY,ZOPE,FIRSTPARTY,LOCALFOLDER
28
+ known_third_party = six, docutils, pkg_resources, pytz
29
+ known_zope =
30
+ known_first_party =
31
+ default_section = ZOPE
32
+ line_length = 79
33
+ lines_after_imports = 2
setup.py CHANGED
@@ -12,19 +12,23 @@
12
  #
13
  ##############################################################################
14
  # This package is developed by the Zope Toolkit project, documented here:
15
- # http://docs.zope.org/zopetoolkit
16
  # When developing and releasing this package, please follow the documented
17
  # Zope Toolkit policies as described by this documentation.
18
  ##############################################################################
19
  """Setup for zope.app.component package
20
  """
21
  import os
22
- from setuptools import setup, find_packages
 
 
 
23
 
24
  def read(*rnames):
25
  with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
26
  return f.read()
27
 
 
28
  test_requires = [
29
  'zope.app.appsetup',
30
  'zope.app.basicskin >= 4.0',
@@ -58,29 +62,28 @@ def read(*rnames):
58
  ]
59
 
60
  setup(name='zope.app.component',
61
- version='4.1.0',
62
  author='Zope Corporation and Contributors',
63
- author_email='zope-dev@zope.org',
64
  description='Local Zope Component Support',
65
  long_description=(
66
  read('README.rst')
67
  + '\n\n.. contents:: \n\n' +
68
  read('CHANGES.rst')
69
- ),
70
  keywords="zope component architecture local",
71
  classifiers=[
72
  'Development Status :: 5 - Production/Stable',
73
  'Environment :: Web Environment',
74
  'Intended Audience :: Developers',
75
  'License :: OSI Approved :: Zope Public License',
76
  'Programming Language :: Python',
77
- 'Programming Language :: Python :: 2',
78
- 'Programming Language :: Python :: 2.7',
79
  'Programming Language :: Python :: 3',
80
- 'Programming Language :: Python :: 3.4',
81
- 'Programming Language :: Python :: 3.5',
82
- 'Programming Language :: Python :: 3.6',
83
  'Programming Language :: Python :: 3.7',
 
 
 
 
84
  'Programming Language :: Python :: Implementation :: CPython',
85
  'Programming Language :: Python :: Implementation :: PyPy',
86
  'Natural Language :: English',
@@ -93,10 +96,10 @@ def read(*rnames):
93
  packages=find_packages('src'),
94
  package_dir={'': 'src'},
95
  namespace_packages=['zope', 'zope.app'],
 
96
  extras_require={
97
  'test': test_requires,
98
  },
99
- tests_require=test_requires,
100
  install_requires=[
101
  'setuptools',
102
  'zope.site',
@@ -116,4 +119,4 @@ def read(*rnames):
116
  ],
117
  include_package_data=True,
118
  zip_safe=False,
119
- )
12
  #
13
  ##############################################################################
14
  # This package is developed by the Zope Toolkit project, documented here:
15
+ # https://zopetoolkit.readthedocs.io/
16
  # When developing and releasing this package, please follow the documented
17
  # Zope Toolkit policies as described by this documentation.
18
  ##############################################################################
19
  """Setup for zope.app.component package
20
  """
21
  import os
22
+
23
+ from setuptools import find_packages
24
+ from setuptools import setup
25
+
26
 
27
  def read(*rnames):
28
  with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
29
  return f.read()
30
 
31
+
32
  test_requires = [
33
  'zope.app.appsetup',
34
  'zope.app.basicskin >= 4.0',
62
  ]
63
 
64
  setup(name='zope.app.component',
65
+ version='5.0',
66
  author='Zope Corporation and Contributors',
67
+ author_email='zope-dev@zope.dev',
68
  description='Local Zope Component Support',
69
  long_description=(
70
  read('README.rst')
71
  + '\n\n.. contents:: \n\n' +
72
  read('CHANGES.rst')
73
+ ),
74
  keywords="zope component architecture local",
75
  classifiers=[
76
  'Development Status :: 5 - Production/Stable',
77
  'Environment :: Web Environment',
78
  'Intended Audience :: Developers',
79
  'License :: OSI Approved :: Zope Public License',
80
  'Programming Language :: Python',
 
 
81
  'Programming Language :: Python :: 3',
 
 
 
82
  'Programming Language :: Python :: 3.7',
83
+ 'Programming Language :: Python :: 3.8',
84
+ 'Programming Language :: Python :: 3.9',
85
+ 'Programming Language :: Python :: 3.10',
86
+ 'Programming Language :: Python :: 3.11',
87
  'Programming Language :: Python :: Implementation :: CPython',
88
  'Programming Language :: Python :: Implementation :: PyPy',
89
  'Natural Language :: English',
96
  packages=find_packages('src'),
97
  package_dir={'': 'src'},
98
  namespace_packages=['zope', 'zope.app'],
99
+ python_requires='>=3.7',
100
  extras_require={
101
  'test': test_requires,
102
  },
 
103
  install_requires=[
104
  'setuptools',
105
  'zope.site',
119
  ],
120
  include_package_data=True,
121
  zip_safe=False,
122
+ )
src/zope/__init__.py CHANGED
@@ -1 +1 @@
1
- __import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
1
+ __import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
src/zope/app/__init__.py CHANGED
@@ -1 +1 @@
1
- __import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
1
+ __import__('pkg_resources').declare_namespace(__name__) # pragma: no cover
src/zope/app/component/__init__.py CHANGED
@@ -13,47 +13,3 @@
13
  ##############################################################################
14
  """Local Component Architecture
15
  """
16
- __docformat__ = "reStructuredText"
17
-
18
- import zope.component
19
- import zope.deprecation
20
-
21
- from zope.site import getNextUtility, queryNextUtility # BBB
22
-
23
- _marker = object()
24
-
25
- # BBB: Deprecated on 9/26/2006
26
- @zope.deprecation.deprecate('''This function has been deprecated and will go
27
- away in Zope 3.6. There is no replacement for this function, since it does not
28
- make sense in light of registry bases anymore. If you are using this function
29
- to lookup the next utility, consider using get/queryNextUtility. Otherwise, it
30
- is suggested to iterate through the list of bases of a registry manually.''')
31
- def getNextSiteManager(context): # pragma: no cover
32
- """Get the next site manager."""
33
- sm = queryNextSiteManager(context, _marker)
34
- if sm is _marker:
35
- raise zope.component.interfaces.ComponentLookupError(
36
- "No more site managers have been found.")
37
- return sm
38
-
39
-
40
- # BBB: Deprecated on 9/26/2006
41
- @zope.deprecation.deprecate('''This function has been deprecated and will go
42
- away in Zope 3.6. There is no replacement for this function, since it does not
43
- make sense in light of registry bases anymore. If you are using this function
44
- to lookup the next utility, consider using get/queryNextUtility. Otherwise, it
45
- is suggested to iterate through the list of bases of a registry manually.''')
46
- def queryNextSiteManager(context, default=None): # pragma: no cover
47
- """Get the next site manager.
48
-
49
- If the site manager of the given context is the global site manager, then
50
- `default` is returned.
51
- """
52
- sm = zope.component.getSiteManager(context)
53
- if sm is zope.component.getGlobalSiteManager():
54
- return default
55
-
56
- bases = sm.__bases__
57
- if not bases:
58
- return zope.component.getGlobalSiteManager()
59
- return bases[0]
13
  ##############################################################################
14
  """Local Component Architecture
15
  """
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
src/zope/app/component/browser/__init__.py CHANGED
@@ -13,19 +13,18 @@
13
  ##############################################################################
14
  """View support for adding and configuring utilities and adapters.
15
  """
16
- __docformat__ = 'restructuredtext'
17
-
18
  import zope.component
19
  import zope.component.interfaces
 
 
20
  from zope.exceptions.interfaces import UserError
21
- from zope.security.proxy import removeSecurityProxy
22
  from zope.publisher.browser import BrowserView
23
- from zope.component.interfaces import IFactory
24
- from zope.component.interface import searchInterface
25
  from zope.traversing.browser.absoluteurl import absoluteURL
 
26
  from zope.app.component.i18n import ZopeMessageFactory as _
27
- from zope.app.container.browser.adding import Adding
28
- from zope.site.site import LocalSiteManager
29
 
30
  class ComponentAdding(Adding):
31
  """Adding subclass used for registerable components."""
@@ -34,7 +33,7 @@ class ComponentAdding(Adding):
34
 
35
  def add(self, content):
36
  # Override so as to save a reference to the added object
37
- self.added_object = super(ComponentAdding, self).add(content)
38
  return self.added_object
39
 
40
  def nextURL(self):
@@ -45,12 +44,12 @@ def nextURL(self):
45
  (self.added_object, self.request), name='absolute_url'))
46
  return url + "/@@registration.html"
47
 
48
- return super(ComponentAdding, self).nextURL() # pragma: no cover
49
 
50
  def action(self, type_name, id=''):
51
  # For special case of that we want to redirect to another adding view
52
  # (usually another menu such as AddUtility)
53
- if type_name.startswith("../"): # pragma: no cover
54
  # Special case
55
  url = type_name
56
  if id:
@@ -60,14 +59,14 @@ def action(self, type_name, id=''):
60
 
61
  # Call the superclass action() method.
62
  # As a side effect, self.added_object is set by add() above.
63
- super(ComponentAdding, self).action(type_name, id)
64
 
65
  _addFilterInterface = None
66
 
67
  def addingInfo(self):
68
  # A site management folder can have many things. We only want
69
  # things that implement a particular interface
70
- info = super(ComponentAdding, self).addingInfo()
71
  if self._addFilterInterface is None:
72
  return info
73
  out = []
@@ -101,7 +100,7 @@ def nextURL(self):
101
  url = absoluteURL(self.added_object, self.request)
102
  return url + "/@@addRegistration.html"
103
 
104
- return super(UtilityAdding, self).nextURL() # pragma: no cover
105
 
106
 
107
  class MakeSite(BrowserView):
@@ -151,7 +150,7 @@ def addSiteManager(self):
151
 
152
  """
153
  if zope.component.interfaces.ISite.providedBy(self.context):
154
- raise UserError(_(u'This is already a site'))
155
 
156
  # We don't want to store security proxies (we can't,
157
  # actually), so we have to remove proxies here before passing
13
  ##############################################################################
14
  """View support for adding and configuring utilities and adapters.
15
  """
 
 
16
  import zope.component
17
  import zope.component.interfaces
18
+ from zope.app.container.browser.adding import Adding
19
+ from zope.component.interfaces import IFactory
20
  from zope.exceptions.interfaces import UserError
 
21
  from zope.publisher.browser import BrowserView
22
+ from zope.security.proxy import removeSecurityProxy
23
+ from zope.site.site import LocalSiteManager
24
  from zope.traversing.browser.absoluteurl import absoluteURL
25
+
26
  from zope.app.component.i18n import ZopeMessageFactory as _
27
+
 
28
 
29
  class ComponentAdding(Adding):
30
  """Adding subclass used for registerable components."""
33
 
34
  def add(self, content):
35
  # Override so as to save a reference to the added object
36
+ self.added_object = super().add(content)
37
  return self.added_object
38
 
39
  def nextURL(self):
44
  (self.added_object, self.request), name='absolute_url'))
45
  return url + "/@@registration.html"
46
 
47
+ return super().nextURL() # pragma: no cover
48
 
49
  def action(self, type_name, id=''):
50
  # For special case of that we want to redirect to another adding view
51
  # (usually another menu such as AddUtility)
52
+ if type_name.startswith("../"): # pragma: no cover
53
  # Special case
54
  url = type_name
55
  if id:
59
 
60
  # Call the superclass action() method.
61
  # As a side effect, self.added_object is set by add() above.
62
+ super().action(type_name, id)
63
 
64
  _addFilterInterface = None
65
 
66
  def addingInfo(self):
67
  # A site management folder can have many things. We only want
68
  # things that implement a particular interface
69
+ info = super().addingInfo()
70
  if self._addFilterInterface is None:
71
  return info
72
  out = []
100
  url = absoluteURL(self.added_object, self.request)
101
  return url + "/@@addRegistration.html"
102
 
103
+ return super().nextURL() # pragma: no cover
104
 
105
 
106
  class MakeSite(BrowserView):
150
 
151
  """
152
  if zope.component.interfaces.ISite.providedBy(self.context):
153
+ raise UserError(_('This is already a site'))
154
 
155
  # We don't want to store security proxies (we can't,
156
  # actually), so we have to remove proxies here before passing
src/zope/app/component/browser/registration.py CHANGED
@@ -14,16 +14,17 @@
14
  """General registry-related views
15
  """
16
  import base64
17
- import warnings
18
 
19
- from zope import interface, component, schema
 
 
20
  from zope.formlib import form
21
  from zope.publisher.browser import BrowserPage
22
  from zope.security.proxy import removeSecurityProxy
23
- import zope.component.interfaces
24
- import zope.publisher.interfaces.browser
25
 
26
- import zope.app.pagetemplate
 
 
27
  from zope.app.component.i18n import ZopeMessageFactory as _
28
 
29
 
@@ -38,6 +39,7 @@ def _registrations(context, comp):
38
  if getattr(registration, attrname) == comp or comp is None:
39
  yield registration
40
 
 
41
  class IRegistrationDisplay(interface.Interface):
42
  """Display registration information
43
  """
@@ -52,10 +54,12 @@ def render():
52
  def unregister():
53
  "Remove the registration by unregistering the component"
54
 
 
55
  class ISiteRegistrationDisplay(IRegistrationDisplay):
56
  """Display registration information, including the component registered
57
  """
58
 
 
59
  @component.adapter(None, zope.publisher.interfaces.browser.IBrowserRequest)
60
  class RegistrationView(BrowserPage):
61
 
@@ -65,7 +69,7 @@ def registrations(self):
65
  registrations = [
66
  component.getMultiAdapter((r, self.request), IRegistrationDisplay)
67
  for r in sorted(_registrations(self.context, self.context))
68
- ]
69
  return registrations
70
 
71
  def update(self):
@@ -79,10 +83,11 @@ def __call__(self):
79
  self.update()
80
  return self.render()
81
 
 
82
  @component.adapter(zope.interface.interfaces.IUtilityRegistration,
83
  zope.publisher.interfaces.browser.IBrowserRequest)
84
  @interface.implementer(IRegistrationDisplay)
85
- class UtilityRegistrationDisplay(object):
86
  """Utility Registration Details"""
87
 
88
  def __init__(self, context, request):
@@ -94,7 +99,7 @@ def provided(self):
94
  return provided.__module__ + '.' + provided.__name__
95
 
96
  def id(self):
97
- joined = "%s %s" % (self.provided(), self.context.name)
98
  joined_bytes = joined.encode("utf8")
99
  j64_bytes = base64.b64encode(joined_bytes)
100
  if not isinstance(j64_bytes, str):
@@ -125,14 +130,15 @@ def render(self):
125
  return {
126
  "info": self._provided(),
127
  "comment": self._comment()
128
- }
129
 
130
  def unregister(self):
131
  self.context.registry.unregisterUtility(
132
  self.context.component,
133
  self.context.provided,
134
  self.context.name,
135
- )
 
136
 
137
  class SiteRegistrationView(RegistrationView):
138
 
@@ -143,9 +149,10 @@ def registrations(self):
143
  component.getMultiAdapter((r, self.request),
144
  ISiteRegistrationDisplay)
145
  for r in sorted(_registrations(self.context, None))
146
- ]
147
  return registrations
148
 
 
149
  @interface.implementer_only(ISiteRegistrationDisplay)
150
  class UtilitySiteRegistrationDisplay(UtilityRegistrationDisplay):
151
  """Utility Registration Details"""
@@ -155,11 +162,11 @@ def render(self):
155
  (self.context.component, self.request), name='absolute_url')
156
  try:
157
  url = url()
158
- except TypeError: # pragma: no cover
159
  url = ""
160
 
161
  cname = getattr(self.context.component, '__name__', '')
162
- if not cname: # pragma: no cover
163
  cname = _("(unknown name)")
164
  if url:
165
  url += "/@@SelectedManagementView.html"
@@ -169,7 +176,8 @@ def render(self):
169
  "url": url,
170
  "info": self._provided(),
171
  "comment": self._comment()
172
- }
 
173
 
174
  @component.adapter(None, zope.publisher.interfaces.browser.IBrowserRequest)
175
  class AddUtilityRegistration(form.Form):
@@ -198,38 +206,28 @@ class AddUtilityRegistration(form.Form):
198
  title=_("Register As"),
199
  description=_("The name under which the utility will be known."),
200
  required=False,
201
- default=u'',
202
- missing_value=u''
203
  ),
204
  schema.Text(
205
  __name__='comment',
206
  title=_("Comment"),
207
  required=False,
208
- default=u'',
209
- missing_value=u''
210
  ),
211
  )
212
 
213
  name = provided = None
214
 
215
- prefix = 'field' # in hopes of making old tests pass. :)
216
 
217
  def __init__(self, context, request):
218
- if self.name is not None: # pragma: no cover
219
  self.form_fields = self.form_fields.omit('name')
220
- if self.provided is not None: # pragma: no cover
221
  self.form_fields = self.form_fields.omit('provided')
222
- super(AddUtilityRegistration, self).__init__(context, request)
223
-
224
- def update(self):
225
- # hack to make work with old tests
226
- if 'UPDATE_SUBMIT' in self.request.form: # pragma: no cover
227
- warnings.warn(
228
- "Old test needs to be updated.",
229
- DeprecationWarning)
230
- self.request.form['field.actions.register'] = 'Register'
231
- self.request.form['field.comment'] = u''
232
- super(AddUtilityRegistration, self).update()
233
 
234
  @property
235
  def label(self):
@@ -253,9 +251,4 @@ def register(self, action, data):
253
  provided, name,
254
  data['comment'] or '')
255
 
256
- if 'UPDATE_SUBMIT' in self.request.form: # pragma: no cover
257
- # Backward compat until 3.5
258
- self.request.response.redirect('@@SelectedManagementView.html')
259
- return
260
-
261
  self.request.response.redirect('@@registration.html')
14
  """General registry-related views
15
  """
16
  import base64
 
17
 
18
+ import zope.app.pagetemplate
19
+ import zope.component.interfaces
20
+ import zope.publisher.interfaces.browser
21
  from zope.formlib import form
22
  from zope.publisher.browser import BrowserPage
23
  from zope.security.proxy import removeSecurityProxy
 
 
24
 
25
+ from zope import component
26
+ from zope import interface
27
+ from zope import schema
28
  from zope.app.component.i18n import ZopeMessageFactory as _
29
 
30
 
39
  if getattr(registration, attrname) == comp or comp is None:
40
  yield registration
41
 
42
+
43
  class IRegistrationDisplay(interface.Interface):
44
  """Display registration information
45
  """
54
  def unregister():
55
  "Remove the registration by unregistering the component"
56
 
57
+
58
  class ISiteRegistrationDisplay(IRegistrationDisplay):
59
  """Display registration information, including the component registered
60
  """
61
 
62
+
63
  @component.adapter(None, zope.publisher.interfaces.browser.IBrowserRequest)
64
  class RegistrationView(BrowserPage):
65
 
69
  registrations = [
70
  component.getMultiAdapter((r, self.request), IRegistrationDisplay)
71
  for r in sorted(_registrations(self.context, self.context))
72
+ ]
73
  return registrations
74
 
75
  def update(self):
83
  self.update()
84
  return self.render()
85
 
86
+
87
  @component.adapter(zope.interface.interfaces.IUtilityRegistration,
88
  zope.publisher.interfaces.browser.IBrowserRequest)
89
  @interface.implementer(IRegistrationDisplay)
90
+ class UtilityRegistrationDisplay:
91
  """Utility Registration Details"""
92
 
93
  def __init__(self, context, request):
99
  return provided.__module__ + '.' + provided.__name__
100
 
101
  def id(self):
102
+ joined = "{} {}".format(self.provided(), self.context.name)
103
  joined_bytes = joined.encode("utf8")
104
  j64_bytes = base64.b64encode(joined_bytes)
105
  if not isinstance(j64_bytes, str):
130
  return {
131
  "info": self._provided(),
132
  "comment": self._comment()
133
+ }
134
 
135
  def unregister(self):
136
  self.context.registry.unregisterUtility(
137
  self.context.component,
138
  self.context.provided,
139
  self.context.name,
140
+ )
141
+
142
 
143
  class SiteRegistrationView(RegistrationView):
144
 
149
  component.getMultiAdapter((r, self.request),
150
  ISiteRegistrationDisplay)
151
  for r in sorted(_registrations(self.context, None))
152
+ ]
153
  return registrations
154
 
155
+
156
  @interface.implementer_only(ISiteRegistrationDisplay)
157
  class UtilitySiteRegistrationDisplay(UtilityRegistrationDisplay):
158
  """Utility Registration Details"""
162
  (self.context.component, self.request), name='absolute_url')
163
  try:
164
  url = url()
165
+ except TypeError: # pragma: no cover
166
  url = ""
167
 
168
  cname = getattr(self.context.component, '__name__', '')
169
+ if not cname: # pragma: no cover
170
  cname = _("(unknown name)")
171
  if url:
172
  url += "/@@SelectedManagementView.html"
176
  "url": url,
177
  "info": self._provided(),
178
  "comment": self._comment()
179
+ }
180
+
181
 
182
  @component.adapter(None, zope.publisher.interfaces.browser.IBrowserRequest)
183
  class AddUtilityRegistration(form.Form):
206
  title=_("Register As"),
207
  description=_("The name under which the utility will be known."),
208
  required=False,
209
+ default='',
210
+ missing_value=''
211
  ),
212
  schema.Text(
213
  __name__='comment',
214
  title=_("Comment"),
215
  required=False,
216
+ default='',
217
+ missing_value=''
218
  ),
219
  )
220
 
221
  name = provided = None
222
 
223
+ prefix = 'field' # in hopes of making old tests pass. :)
224
 
225
  def __init__(self, context, request):
226
+ if self.name is not None: # pragma: no cover
227
  self.form_fields = self.form_fields.omit('name')
228
+ if self.provided is not None: # pragma: no cover
229
  self.form_fields = self.form_fields.omit('provided')
230
+ super().__init__(context, request)
 
 
 
 
 
 
 
 
 
 
231
 
232
  @property
233
  def label(self):
251
  provided, name,
252
  data['comment'] or '')
253
 
 
 
 
 
 
254
  self.request.response.redirect('@@registration.html')
src/zope/app/component/browser/tests/__init__.py CHANGED
@@ -15,6 +15,7 @@
15
  from zope import interface
16
  from zope.app.component.browser import ComponentAdding
17
 
 
18
  class ISampleBase(interface.Interface):
19
  pass
20
 
@@ -24,8 +25,9 @@ class ISample(ISampleBase):
24
 
25
 
26
  @interface.implementer(ISample)
27
- class Sample(object):
28
  pass
29
 
 
30
  class FilteredAdding(ComponentAdding):
31
  _addFilterInterface = ISample
15
  from zope import interface
16
  from zope.app.component.browser import ComponentAdding
17
 
18
+
19
  class ISampleBase(interface.Interface):
20
  pass
21
 
25
 
26
 
27
  @interface.implementer(ISample)
28
+ class Sample:
29
  pass
30
 
31
+
32
  class FilteredAdding(ComponentAdding):
33
  _addFilterInterface = ISample
src/zope/app/component/browser/tests/test_site.py CHANGED
@@ -16,10 +16,15 @@
16
 
17
 
18
  import doctest
 
19
  import unittest
20
 
21
- from zope.testbrowser.wsgi import TestBrowserLayer
22
  from zope.app.wsgi.testlayer import BrowserLayer
 
 
 
 
23
 
24
  import zope.app.component.browser
25
  import zope.app.component.testing
@@ -31,30 +36,25 @@ class _AppComponentBrowserLayer(TestBrowserLayer,
31
  def setUp(self):
32
  # Typically this would be done by zope.app.principalannotation's
33
  # bootstrap.zcml but we don't have a dep on that.
34
- super(_AppComponentBrowserLayer, self).setUp()
35
- from zope.principalannotation.utility import PrincipalAnnotationUtility
36
- from zope.principalannotation.interfaces import IPrincipalAnnotationUtility
37
- from zope import component
38
- component.getGlobalSiteManager().registerUtility(PrincipalAnnotationUtility(),
39
- IPrincipalAnnotationUtility)
40
 
41
 
42
  AppComponentBrowserLayer = _AppComponentBrowserLayer(
43
  zope.app.component.browser,
44
  allowTearDown=True)
45
 
46
- from zope.testing import renormalizing
47
 
48
- import re
49
  checker = renormalizing.RENormalizing([
50
  (re.compile("u('.*?')"), r"\1"),
51
  (re.compile('u(".*?")'), r"\1"),
52
  ])
53
 
 
54
  def test_suite():
55
- flags = optionflags=(doctest.ELLIPSIS
56
- | doctest.NORMALIZE_WHITESPACE
57
- | renormalizing.IGNORE_EXCEPTION_MODULE_IN_PYTHON2)
58
 
59
  site = doctest.DocFileSuite(
60
  "../site.rst",
16
 
17
 
18
  import doctest
19
+ import re
20
  import unittest
21
 
22
+ import zope.component
23
  from zope.app.wsgi.testlayer import BrowserLayer
24
+ from zope.principalannotation.interfaces import IPrincipalAnnotationUtility
25
+ from zope.principalannotation.utility import PrincipalAnnotationUtility
26
+ from zope.testbrowser.wsgi import TestBrowserLayer
27
+ from zope.testing import renormalizing
28
 
29
  import zope.app.component.browser
30
  import zope.app.component.testing
36
  def setUp(self):
37
  # Typically this would be done by zope.app.principalannotation's
38
  # bootstrap.zcml but we don't have a dep on that.
39
+ super().setUp()
40
+ import zope.component
41
+ zope.component.getGlobalSiteManager().registerUtility(
42
+ PrincipalAnnotationUtility(), IPrincipalAnnotationUtility)
 
 
43
 
44
 
45
  AppComponentBrowserLayer = _AppComponentBrowserLayer(
46
  zope.app.component.browser,
47
  allowTearDown=True)
48
 
 
49
 
 
50
  checker = renormalizing.RENormalizing([
51
  (re.compile("u('.*?')"), r"\1"),
52
  (re.compile('u(".*?")'), r"\1"),
53
  ])
54
 
55
+
56
  def test_suite():
57
+ flags = doctest.ELLIPSIS | doctest.NORMALIZE_WHITESPACE
 
 
58
 
59
  site = doctest.DocFileSuite(
60
  "../site.rst",
src/zope/app/component/hooks.py CHANGED
@@ -17,15 +17,13 @@
17
  """
18
  __docformat__ = 'restructuredtext'
19
 
20
- from zope.component.hooks import (
21
- read_property,
22
- SiteInfo,
23
- siteinfo,
24
- setSite,
25
- getSite,
26
- getSiteManager,
27
- adapter_hook,
28
- setHooks,
29
- resetHooks,
30
- setSite,
31
- clearSite) # BBB
17
  """
18
  __docformat__ = 'restructuredtext'
19
 
20
+ from zope.component.hooks import SiteInfo # BBB
21
+ from zope.component.hooks import adapter_hook
22
+ from zope.component.hooks import clearSite
23
+ from zope.component.hooks import getSite
24
+ from zope.component.hooks import getSiteManager
25
+ from zope.component.hooks import read_property
26
+ from zope.component.hooks import resetHooks
27
+ from zope.component.hooks import setHooks
28
+ from zope.component.hooks import setSite
29
+ from zope.component.hooks import siteinfo
 
 
src/zope/app/component/i18n.py CHANGED
@@ -17,4 +17,6 @@
17
 
18
  # import this as _ to create i18n messages in the zope domain
19
  from zope.i18nmessageid import MessageFactory
 
 
20
  ZopeMessageFactory = MessageFactory('zope')
17
 
18
  # import this as _ to create i18n messages in the zope domain
19
  from zope.i18nmessageid import MessageFactory
20
+
21
+
22
  ZopeMessageFactory = MessageFactory('zope')
src/zope/app/component/interfaces/__init__.py CHANGED
@@ -13,11 +13,10 @@
13
  ##############################################################################
14
 
15
  # BBB
16
- from zope.site.interfaces import (INewLocalSite,
17
- NewLocalSite,
18
- ILocalSiteManager,
19
- ISiteManagementFolder)
20
-
21
  # BBB
22
- from zope.component.interfaces import (ISite,
23
- IPossibleSite)
 
 
13
  ##############################################################################
14
 
15
  # BBB
16
+ from zope.component.interfaces import IPossibleSite
17
+ from zope.component.interfaces import ISite
 
 
 
18
  # BBB
19
+ from zope.site.interfaces import ILocalSiteManager
20
+ from zope.site.interfaces import INewLocalSite
21
+ from zope.site.interfaces import ISiteManagementFolder
22
+ from zope.site.interfaces import NewLocalSite
src/zope/app/component/interfaces/registration.py CHANGED
@@ -13,16 +13,20 @@
13
  ##############################################################################
14
  """Interfaces for objects supporting registration
15
  """
16
- from zope import interface, schema
17
  import zope.schema.interfaces
18
 
 
 
 
 
19
  class IComponent(zope.schema.interfaces.IField):
20
  """A component
21
 
22
  This is just the interface for the ComponentPath field below. We'll use
23
  this as the basis for looking up an appropriate widget.
24
  """
25
 
 
26
  @interface.implementer(IComponent)
27
  class Component(schema.Field):
28
  """A component
13
  ##############################################################################
14
  """Interfaces for objects supporting registration
15
  """
 
16
  import zope.schema.interfaces
17
 
18
+ from zope import interface
19
+ from zope import schema
20
+
21
+
22
  class IComponent(zope.schema.interfaces.IField):
23
  """A component
24
 
25
  This is just the interface for the ComponentPath field below. We'll use
26
  this as the basis for looking up an appropriate widget.
27
  """
28
 
29
+
30
  @interface.implementer(IComponent)
31
  class Component(schema.Field):
32
  """A component
src/zope/app/component/interfaces/tests/test_registration.py CHANGED
@@ -14,7 +14,9 @@
14
 
15
  import unittest
16
 
17
- from zope.interface.verify import verifyClass, verifyObject
 
 
18
 
19
  class TestComponent(unittest.TestCase):
20
 
@@ -25,5 +27,6 @@ def test_implements(self):
25
  verifyClass(IComponent, Component)
26
  verifyObject(IComponent, Component())
27
 
 
28
  def test_suite():
29
  return unittest.defaultTestLoader.loadTestsFromName(__name__)
14
 
15
  import unittest
16
 
17
+ from zope.interface.verify import verifyClass
18
+ from zope.interface.verify import verifyObject
19
+
20
 
21
  class TestComponent(unittest.TestCase):
22
 
27
  verifyClass(IComponent, Component)
28
  verifyObject(IComponent, Component())
29
 
30
+
31
  def test_suite():
32
  return unittest.defaultTestLoader.loadTestsFromName(__name__)
src/zope/app/component/metaconfigure.py CHANGED
@@ -12,5 +12,8 @@
12
  #
13
  ##############################################################################
14
  # BBB
15
- from zope.component.security import PublicPermission, _checker
16
- from zope.component.zcml import view, resource, subscriber
 
 
 
12
  #
13
  ##############################################################################
14
  # BBB
15
+ from zope.component.security import PublicPermission
16
+ from zope.component.security import _checker
17
+ from zope.component.zcml import resource
18
+ from zope.component.zcml import subscriber
19
+ from zope.component.zcml import view
src/zope/app/component/metadirectives.py CHANGED
@@ -13,14 +13,13 @@
13
  ##############################################################################
14
 
15
  # BBB
16
- from zope.security.metadirectives import (IClassDirective,
17
- IImplementsSubdirective,
18
- IRequireSubdirective,
19
- IAllowSubdirective,
20
- IFactorySubdirective)
21
-
22
  # BBB
23
- from zope.component.zcml import (IBasicViewInformation,
24
- IBasicResourceInformation,
25
- IViewDirective,
26
- IResourceDirective)
 
13
  ##############################################################################
14
 
15
  # BBB
16
+ from zope.component.zcml import IBasicResourceInformation
17
+ from zope.component.zcml import IBasicViewInformation
18
+ from zope.component.zcml import IResourceDirective
19
+ from zope.component.zcml import IViewDirective
 
 
20
  # BBB
21
+ from zope.security.metadirectives import IAllowSubdirective
22
+ from zope.security.metadirectives import IClassDirective
23
+ from zope.security.metadirectives import IFactorySubdirective
24
+ from zope.security.metadirectives import IImplementsSubdirective
25
+ from zope.security.metadirectives import IRequireSubdirective
src/zope/app/component/site.py CHANGED
@@ -18,14 +18,14 @@
18
  # on the side of caution for backwards compatibility we
19
  # import everything defined
20
  from zope.component.hooks import setSite
21
- from zope.site.site import (SiteManagementFolder,
22
- SMFolderFactory,
23
- SiteManagerContainer,
24
- _findNextSiteManager,
25
- _LocalAdapterRegistry,
26
- LocalSiteManager,
27
- threadSiteSubscriber,
28
- clearThreadSiteSubscriber,
29
- clearSite,
30
- SiteManagerAdapter,
31
- changeSiteConfigurationAfterMove) # BBB
18
  # on the side of caution for backwards compatibility we
19
  # import everything defined
20
  from zope.component.hooks import setSite
21
+ from zope.site.site import LocalSiteManager
22
+ from zope.site.site import SiteManagementFolder
23
+ from zope.site.site import SiteManagerAdapter
24
+ from zope.site.site import SiteManagerContainer
25
+ from zope.site.site import SMFolderFactory
26
+ from zope.site.site import _findNextSiteManager
27
+ from zope.site.site import _LocalAdapterRegistry
28
+ from zope.site.site import changeSiteConfigurationAfterMove # BBB
29
+ from zope.site.site import clearSite
30
+ from zope.site.site import clearThreadSiteSubscriber
31
+ from zope.site.site import threadSiteSubscriber
src/zope/app/component/testing.py CHANGED
@@ -17,22 +17,20 @@
17
  This is part of the public API of this package.
18
  """
19
 
20
- from zope import component
21
-
22
  from zope.component.hooks import setSite
23
  from zope.component.interfaces import ISite
24
  from zope.component.testing import PlacelessSetup
25
-
26
  from zope.container.interfaces import ISimpleReadContainer
27
  from zope.container.traversal import ContainerTraversable
28
-
29
  from zope.site.folder import Folder
30
  from zope.site.folder import rootFolder
31
  from zope.site.site import LocalSiteManager
32
-
33
  from zope.traversing.api import traverse
34
  from zope.traversing.interfaces import ITraversable
35
 
 
 
 
36
  def buildSampleFolderTree():
37
  r"""
38
  Create a tree of folders and return the root::
@@ -47,30 +45,30 @@ def buildSampleFolderTree():
47
  """
48
 
49
  root = rootFolder()
50
- root[u'folder1'] = Folder()
51
- root[u'folder1'][u'folder1_1'] = Folder()
52
- root[u'folder1'][u'folder1_1'][u'folder1_1_1'] = Folder()
53
- root[u'folder1'][u'folder1_1'][u'folder1_1_2'] = Folder()
54
- root[u'folder1'][u'folder1_2'] = Folder()
55
- root[u'folder1'][u'folder1_2'][u'folder1_2_1'] = Folder()
56
- root[u'folder2'] = Folder()
57
- root[u'folder2'][u'folder2_1'] = Folder()
58
- root[u'folder2'][u'folder2_1'][u'folder2_1_1'] = Folder()
59
- root[u"\N{CYRILLIC SMALL LETTER PE}"
60
- u"\N{CYRILLIC SMALL LETTER A}"
61
- u"\N{CYRILLIC SMALL LETTER PE}"
62
- u"\N{CYRILLIC SMALL LETTER KA}"
63
- u"\N{CYRILLIC SMALL LETTER A}3"] = Folder()
64
- root[u"\N{CYRILLIC SMALL LETTER PE}"
65
- u"\N{CYRILLIC SMALL LETTER A}"
66
- u"\N{CYRILLIC SMALL LETTER PE}"
67
- u"\N{CYRILLIC SMALL LETTER KA}"
68
- u"\N{CYRILLIC SMALL LETTER A}3"][
69
- u"\N{CYRILLIC SMALL LETTER PE}"
70
- u"\N{CYRILLIC SMALL LETTER A}"
71
- u"\N{CYRILLIC SMALL LETTER PE}"
72
- u"\N{CYRILLIC SMALL LETTER KA}"
73
- u"\N{CYRILLIC SMALL LETTER A}3_1"] = Folder()
74
 
75
  return root
76
 
@@ -93,13 +91,17 @@ def setUpTraversal():
93
  ITraversable)
94
 
95
 
96
- class Place(object):
97
- "A property-like descriptor that traverses its name starting from 'rootFolder."
 
 
 
 
98
  def __init__(self, path):
99
  self.path = path
100
 
101
  def __get__(self, inst, cls=None):
102
- if inst is None: # pragma: no cover
103
  return self
104
 
105
  try:
@@ -120,34 +122,34 @@ class PlacefulSetup(PlacelessSetup):
120
  """
121
 
122
  # Places :)
123
- rootFolder = Place(u'')
124
-
125
- folder1 = Place(u'folder1')
126
- folder1_1 = Place(u'folder1/folder1_1')
127
- folder1_1_1 = Place(u'folder1/folder1_1/folder1_1_1')
128
- folder1_1_2 = Place(u'folder1/folder1_2/folder1_1_2')
129
- folder1_2 = Place(u'folder1/folder1_2')
130
- folder1_2_1 = Place(u'folder1/folder1_2/folder1_2_1')
131
-
132
- folder2 = Place(u'folder2')
133
- folder2_1 = Place(u'folder2/folder2_1')
134
- folder2_1_1 = Place(u'folder2/folder2_1/folder2_1_1')
135
-
136
- folder3 = Place(u"\N{CYRILLIC SMALL LETTER PE}"
137
- u"\N{CYRILLIC SMALL LETTER A}"
138
- u"\N{CYRILLIC SMALL LETTER PE}"
139
- u"\N{CYRILLIC SMALL LETTER KA}"
140
- u"\N{CYRILLIC SMALL LETTER A}3")
141
- folder3_1 = Place(u"\N{CYRILLIC SMALL LETTER PE}"
142
- u"\N{CYRILLIC SMALL LETTER A}"
143
- u"\N{CYRILLIC SMALL LETTER PE}"
144
- u"\N{CYRILLIC SMALL LETTER KA}"
145
- u"\N{CYRILLIC SMALL LETTER A}3/"
146
- u"\N{CYRILLIC SMALL LETTER PE}"
147
- u"\N{CYRILLIC SMALL LETTER A}"
148
- u"\N{CYRILLIC SMALL LETTER PE}"
149
- u"\N{CYRILLIC SMALL LETTER KA}"
150
- u"\N{CYRILLIC SMALL LETTER A}3_1")
151
 
152
  def setUp(self, folders=False, site=False):
153
  PlacelessSetup.setUp(self)
17
  This is part of the public API of this package.
18
  """
19
 
 
 
20
  from zope.component.hooks import setSite
21
  from zope.component.interfaces import ISite
22
  from zope.component.testing import PlacelessSetup
 
23
  from zope.container.interfaces import ISimpleReadContainer
24
  from zope.container.traversal import ContainerTraversable
 
25
  from zope.site.folder import Folder
26
  from zope.site.folder import rootFolder
27
  from zope.site.site import LocalSiteManager
 
28
  from zope.traversing.api import traverse
29
  from zope.traversing.interfaces import ITraversable
30
 
31
+ from zope import component
32
+
33
+
34
  def buildSampleFolderTree():
35
  r"""
36
  Create a tree of folders and return the root::
45
  """
46
 
47
  root = rootFolder()
48
+ root['folder1'] = Folder()
49
+ root['folder1']['folder1_1'] = Folder()
50
+ root['folder1']['folder1_1']['folder1_1_1'] = Folder()
51
+ root['folder1']['folder1_1']['folder1_1_2'] = Folder()
52
+ root['folder1']['folder1_2'] = Folder()
53
+ root['folder1']['folder1_2']['folder1_2_1'] = Folder()
54
+ root['folder2'] = Folder()
55
+ root['folder2']['folder2_1'] = Folder()
56
+ root['folder2']['folder2_1']['folder2_1_1'] = Folder()
57
+ root["\N{CYRILLIC SMALL LETTER PE}"
58
+ "\N{CYRILLIC SMALL LETTER A}"
59
+ "\N{CYRILLIC SMALL LETTER PE}"
60
+ "\N{CYRILLIC SMALL LETTER KA}"
61
+ "\N{CYRILLIC SMALL LETTER A}3"] = Folder()
62
+ root["\N{CYRILLIC SMALL LETTER PE}"
63
+ "\N{CYRILLIC SMALL LETTER A}"
64
+ "\N{CYRILLIC SMALL LETTER PE}"
65
+ "\N{CYRILLIC SMALL LETTER KA}"
66
+ "\N{CYRILLIC SMALL LETTER A}3"][
67
+ "\N{CYRILLIC SMALL LETTER PE}"
68
+ "\N{CYRILLIC SMALL LETTER A}"
69
+ "\N{CYRILLIC SMALL LETTER PE}"
70
+ "\N{CYRILLIC SMALL LETTER KA}"
71
+ "\N{CYRILLIC SMALL LETTER A}3_1"] = Folder()
72
 
73
  return root
74
 
91
  ITraversable)
92
 
93
 
94
+ class Place:
95
+ """A property-like descriptor that traverses its name starting from
96
+
97
+ rootFolder.
98
+ """
99
+
100
  def __init__(self, path):
101
  self.path = path
102
 
103
  def __get__(self, inst, cls=None):
104
+ if inst is None: # pragma: no cover
105
  return self
106
 
107
  try:
122
  """
123
 
124
  # Places :)
125
+ rootFolder = Place('')
126
+
127
+ folder1 = Place('folder1')
128
+ folder1_1 = Place('folder1/folder1_1')
129
+ folder1_1_1 = Place('folder1/folder1_1/folder1_1_1')
130
+ folder1_1_2 = Place('folder1/folder1_2/folder1_1_2')
131
+ folder1_2 = Place('folder1/folder1_2')
132
+ folder1_2_1 = Place('folder1/folder1_2/folder1_2_1')
133
+
134
+ folder2 = Place('folder2')
135
+ folder2_1 = Place('folder2/folder2_1')
136
+ folder2_1_1 = Place('folder2/folder2_1/folder2_1_1')
137
+
138
+ folder3 = Place("\N{CYRILLIC SMALL LETTER PE}"
139
+ "\N{CYRILLIC SMALL LETTER A}"
140
+ "\N{CYRILLIC SMALL LETTER PE}"
141
+ "\N{CYRILLIC SMALL LETTER KA}"
142
+ "\N{CYRILLIC SMALL LETTER A}3")
143
+ folder3_1 = Place("\N{CYRILLIC SMALL LETTER PE}"
144
+ "\N{CYRILLIC SMALL LETTER A}"
145
+ "\N{CYRILLIC SMALL LETTER PE}"
146
+ "\N{CYRILLIC SMALL LETTER KA}"
147
+ "\N{CYRILLIC SMALL LETTER A}3/"
148
+ "\N{CYRILLIC SMALL LETTER PE}"
149
+ "\N{CYRILLIC SMALL LETTER A}"
150
+ "\N{CYRILLIC SMALL LETTER PE}"
151
+ "\N{CYRILLIC SMALL LETTER KA}"
152
+ "\N{CYRILLIC SMALL LETTER A}3_1")
153
 
154
  def setUp(self, folders=False, site=False):
155
  PlacelessSetup.setUp(self)
src/zope/app/component/tests/__init__.py CHANGED
@@ -14,10 +14,10 @@
14
  "Non-API test details."
15
 
16
 
 
17
  from zope.interface import implementer
18
  from zope.publisher.browser import BrowserView
19
  from zope.publisher.interfaces.browser import IBrowserPublisher
20
- from zope.browsermenu.menu import getFirstMenuItem
21
 
22
 
23
  @implementer(IBrowserPublisher)
@@ -39,10 +39,11 @@ def __call__(self):
39
  redirect_url = item['action']
40
  if not redirect_url.lower().startswith(('../', 'javascript:', '++')):
41
  self.request.response.redirect(redirect_url)
42
- return u''
43
- raise AssertionError("Should not get here") # pragma: no cover
 
44
 
45
- class LoginLogout(object):
46
  # Dummy implementation of zope.app.security.browser.auth.LoginLogout
47
 
48
  def __call__(self):
14
  "Non-API test details."
15
 
16
 
17
+ from zope.browsermenu.menu import getFirstMenuItem
18
  from zope.interface import implementer
19
  from zope.publisher.browser import BrowserView
20
  from zope.publisher.interfaces.browser import IBrowserPublisher
 
21
 
22
 
23
  @implementer(IBrowserPublisher)
39
  redirect_url = item['action']
40
  if not redirect_url.lower().startswith(('../', 'javascript:', '++')):
41
  self.request.response.redirect(redirect_url)
42
+ return ''
43
+ raise AssertionError("Should not get here") # pragma: no cover
44
+
45
 
46
+ class LoginLogout:
47
  # Dummy implementation of zope.app.security.browser.auth.LoginLogout
48
 
49
  def __call__(self):
src/zope/app/component/tests/test_bwc_imports.py CHANGED
@@ -15,13 +15,15 @@
15
  import importlib
16
  import unittest
17
 
 
18
  def _make_import_test(mod_name, attrname):
19
  def test(self):
20
  mod = importlib.import_module('zope.app.component.' + mod_name)
21
  self.assertIsNotNone(getattr(mod, attrname))
22
 
23
  return test
24
 
 
25
  class TestBWCImports(unittest.TestCase):
26
 
27
  for mod_name, attrname in (('contentdirective', 'ClassDirective'),
@@ -33,5 +35,6 @@ class TestBWCImports(unittest.TestCase):
33
  ('interfaces', 'INewLocalSite')):
34
  locals()['test_' + mod_name] = _make_import_test(mod_name, attrname)
35
 
 
36
  def test_suite():
37
  return unittest.defaultTestLoader.loadTestsFromName(__name__)
15
  import importlib
16
  import unittest
17
 
18
+
19
  def _make_import_test(mod_name, attrname):
20
  def test(self):
21
  mod = importlib.import_module('zope.app.component.' + mod_name)
22
  self.assertIsNotNone(getattr(mod, attrname))
23
 
24
  return test
25
 
26
+
27
  class TestBWCImports(unittest.TestCase):
28
 
29
  for mod_name, attrname in (('contentdirective', 'ClassDirective'),
35
  ('interfaces', 'INewLocalSite')):
36
  locals()['test_' + mod_name] = _make_import_test(mod_name, attrname)
37
 
38
+
39
  def test_suite():
40
  return unittest.defaultTestLoader.loadTestsFromName(__name__)
src/zope/app/component/tests/test_testing.py CHANGED
@@ -13,15 +13,17 @@
13
  ##############################################################################
14
 
15
  import unittest
16
- from zope.app.component import testing
17
 
18
  from zope.component.interfaces import ISite
19
 
 
 
 
20
  class TestTesting(testing.PlacefulSetup,
21
  unittest.TestCase):
22
 
23
  def setUp(self):
24
- super(TestTesting, self).setUp(site=True)
25
 
26
  def test_is_site(self):
27
  self.assertTrue(ISite.providedBy(self.rootFolder))
@@ -31,7 +33,7 @@ def test_build_sample_folder(self):
31
  tree1 = testing.buildSampleFolderTree()
32
  self.assertIsNotNone(tree1)
33
  self.assertIsNot(tree1, testing.buildSampleFolderTree())
34
- self.assertIn(u'folder1', tree1)
35
 
36
  def test_new_root(self):
37
  cur_root = self.rootFolder
@@ -44,5 +46,6 @@ def test_place_rebuilds_root(self):
44
  f2 = self.folder1
45
  self.assertIsNot(f1, f2)
46
 
 
47
  def test_suite():
48
  return unittest.defaultTestLoader.loadTestsFromName(__name__)
13
  ##############################################################################
14
 
15
  import unittest
 
16
 
17
  from zope.component.interfaces import ISite
18
 
19
+ from zope.app.component import testing
20
+
21
+
22
  class TestTesting(testing.PlacefulSetup,
23
  unittest.TestCase):
24
 
25
  def setUp(self):
26
+ super().setUp(site=True)
27
 
28
  def test_is_site(self):
29
  self.assertTrue(ISite.providedBy(self.rootFolder))
33
  tree1 = testing.buildSampleFolderTree()
34
  self.assertIsNotNone(tree1)
35
  self.assertIsNot(tree1, testing.buildSampleFolderTree())
36
+ self.assertIn('folder1', tree1)
37
 
38
  def test_new_root(self):
39
  cur_root = self.rootFolder
46
  f2 = self.folder1
47
  self.assertIsNot(f1, f2)
48
 
49
+
50
  def test_suite():
51
  return unittest.defaultTestLoader.loadTestsFromName(__name__)
src/zope/app/component/vocabulary.py CHANGED
@@ -14,8 +14,10 @@
14
 
15
  # BBB
16
 
17
- from zope.componentvocabulary.vocabulary import (
18
- UtilityTerm, UtilityVocabulary, InterfacesVocabulary,
19
- UtilityComponentInterfacesVocabulary, UtilityNameTerm,
20
- UtilityNames)
21
-
 
 
14
 
15
  # BBB
16
 
17
+ from zope.componentvocabulary.vocabulary import InterfacesVocabulary
18
+ from zope.componentvocabulary.vocabulary import \
19
+ UtilityComponentInterfacesVocabulary
20
+ from zope.componentvocabulary.vocabulary import UtilityNames
21
+ from zope.componentvocabulary.vocabulary import UtilityNameTerm
22
+ from zope.componentvocabulary.vocabulary import UtilityTerm
23
+ from zope.componentvocabulary.vocabulary import UtilityVocabulary
tox.ini CHANGED
@@ -1,9 +1,75 @@
 
 
1
  [tox]
 
2
  envlist =
3
- py27, pypy, py34, py35, py36, py37
 
 
 
 
 
 
 
4
 
5
  [testenv]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6
  commands =
7
- zope-testrunner --test-path=src []
 
 
 
 
 
8
  deps =
9
- .[test]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Generated from:
2
+ # https://github.com/zopefoundation/meta/tree/master/config/pure-python
3
  [tox]
4
+ minversion = 3.18
5
  envlist =
6
+ lint
7
+ py37
8
+ py38
9
+ py39
10
+ py310
11
+ py311
12
+ pypy3
13
+ coverage
14
 
15
  [testenv]
16
+ usedevelop = true
17
+ deps =
18
+ commands =
19
+ zope-testrunner --test-path=src {posargs:-vc}
20
+ extras =
21
+ test
22
+
23
+ [testenv:lint]
24
+ basepython = python3
25
+ skip_install = true
26
+ commands =
27
+ isort --check-only --diff {toxinidir}/src {toxinidir}/setup.py
28
+ flake8 src setup.py
29
+ check-manifest
30
+ check-python-versions
31
+ deps =
32
+ check-manifest
33
+ check-python-versions >= 0.19.1
34
+ wheel
35
+ flake8
36
+ isort
37
+
38
+ [testenv:isort-apply]
39
+ basepython = python3
40
+ skip_install = true
41
+ commands_pre =
42
+ deps =
43
+ isort
44
  commands =
45
+ isort {toxinidir}/src {toxinidir}/setup.py []
46
+
47
+ [testenv:coverage]
48
+ basepython = python3
49