Skip to content

Commit

Permalink
Drop Python 3.3 and 100% coverage
Browse files Browse the repository at this point in the history
- Test compatibility with zope.component 4.4
- 100% coverage on any given version of python, simplifying tox.ini
- Drop _u compat function and _compat module
- Badges
- Whitespace and import cleanups.
- Add tests on PyPy3.5
  • Loading branch information
jamadden committed Aug 2, 2017
1 parent 2f91ea0 commit 150b260
Show file tree
Hide file tree
Showing 16 changed files with 393 additions and 325 deletions.
13 changes: 6 additions & 7 deletions .coveragerc
@@ -1,12 +1,11 @@
[run]
branch = True
source = zope.browsermenu

[report]
precision = 2

[paths]
source =
src/
.tox/py*/lib/python*/site-packages/
.tox/pypy*/site-packages/
exclude_lines =
pragma: no cover
if __name__ == '__main__':
raise NotImplementedError
self.fail
raise AssertionError
26 changes: 12 additions & 14 deletions .travis.yml
@@ -1,22 +1,20 @@
language: python
sudo: false
python:
- 2.7
- 3.3
- 3.4
- 3.5
- 3.6
- pypy-5.4.1
- 2.7
- 3.4
- 3.5
- 3.6
- pypy
- pypy3.5-5.8.0
install:
- pip install -U pip setuptools zope.testrunner
- pip install -U coveralls coverage
- pip install -U -e ".[test]"
- pip install -U pip setuptools
- pip install -U coverage coveralls
- pip install -U -e .[test]
script:
- coverage run -m zope.testrunner --test-path=src --auto-color
- coverage run -m zope.testrunner --test-path=src
after_success:
- coveralls
- coveralls
notifications:
email: false
email: false
cache: pip
before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
24 changes: 14 additions & 10 deletions CHANGES.rst
@@ -1,19 +1,26 @@
Changes
=======
=========
Changes
=========

4.3 (unreleased)
================

- Nothing changed yet.
4.3.0 (unreleased)
==================

- Drop support for Python 3.3.

- Add support for PyPy3 3.5.

4.2 (2017-05-28)
================
- Fix test compatibility with zope.component 4.4.0.

4.2.0 (2017-05-28)
==================

- Add support for Python 3.5 and 3.6.

- Drop support for Python 2.6 and 3.2.

- Drop support for 'setup.py test'.

4.1.1 (2015-06-05)
==================

Expand All @@ -29,13 +36,11 @@ Changes

- Add support for testing on Travis.


4.1.0a1 (2013-02-22)
====================

- Add support for Python 3.3.


4.0.0 (2012-07-04)
==================

Expand All @@ -49,7 +54,6 @@ Changes

- Drop support for Python 2.4 and 2.5.


3.9.1 (2010-04-30)
==================

Expand Down
18 changes: 15 additions & 3 deletions README.rst
@@ -1,10 +1,22 @@
``zope.browsermenu``
====================
======================
``zope.browsermenu``
======================

.. image:: https://img.shields.io/pypi/v/zope.browsermenu.svg
:target: https://pypi.python.org/pypi/zope.browsermenu/
:alt: Latest release

.. image:: https://img.shields.io/pypi/pyversions/zope.browsermenu.svg
:target: https://pypi.org/project/zope.browsermenu/
:alt: Supported Python versions

.. image:: https://travis-ci.org/zopefoundation/zope.browsermenu.png?branch=master
:target: https://travis-ci.org/zopefoundation/zope.browsermenu

.. note::
.. image:: https://coveralls.io/repos/github/zopefoundation/zope.browsermenu/badge.svg?branch=master
:target: https://coveralls.io/github/zopefoundation/zope.browsermenu?branch=master

.. note::
This package is at present not reusable without depending on a large
chunk of the Zope Toolkit and its assumptions. It is maintained by the
`Zope Toolkit project <http://docs.zope.org/zopetoolkit/>`_.
Expand Down
14 changes: 8 additions & 6 deletions setup.py
Expand Up @@ -16,18 +16,21 @@
import os
from setuptools import setup, find_packages


def read(*rnames):
with open(os.path.join(os.path.dirname(__file__), *rnames)) as f:
return f.read()

long_description = (read('README.rst') + '\n\n' + read('CHANGES.rst'))

TESTS_REQUIRE = [
'zope.testing',
'zope.testrunner',
]

setup(
name='zope.browsermenu',
version='4.3.dev0',
url='http://pypi.python.org/pypi/zope.browsermenu/',
version='4.3.0.dev0',
url='http://github.com/zopefoundation/zope.browsermenu/',
author='Zope Foundation and Contributors',
author_email='zope-dev@zope.org',
classifiers=[
Expand All @@ -38,7 +41,6 @@ def read(*rnames):
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.3',
'Programming Language :: Python :: 3.4',
'Programming Language :: Python :: 3.5',
'Programming Language :: Python :: 3.6',
Expand Down Expand Up @@ -69,9 +71,9 @@ def read(*rnames):
'zope.traversing>3.7',
],
extras_require={
'test': ['zope.testing'],
'test': TESTS_REQUIRE,
},
tests_require=['zope.testing', 'zope.testrunner'],
tests_require=TESTS_REQUIRE,
include_package_data=True,
zip_safe=False,
)
32 changes: 0 additions & 32 deletions src/zope/browsermenu/_compat.py

This file was deleted.

21 changes: 8 additions & 13 deletions src/zope/browsermenu/field.py
Expand Up @@ -16,7 +16,6 @@
__docformat__ = 'restructuredtext'

from zope.component import queryUtility
from zope.component.interfaces import ComponentLookupError
from zope.configuration.exceptions import ConfigurationError
from zope.configuration.fields import GlobalObject
from zope.schema import ValidationError
Expand Down Expand Up @@ -74,7 +73,7 @@ class MenuField(GlobalObject):
Test 3: Get the menu from the Site Manager
------------------------------------------
>>> from zope.component import provideUtility
>>> provideUtility(menu1, IMenuItemType, 'menu1')
Expand All @@ -85,23 +84,19 @@ class MenuField(GlobalObject):
def fromUnicode(self, u):
name = str(u.strip())

try:
value = queryUtility(IMenuItemType, name)
except ComponentLookupError:
# The component architecture is not up and running.
pass
else:
if value is not None:
self.validate(value)
return value
# queryUtility can never raise ComponentLookupError
value = queryUtility(IMenuItemType, name)
if value is not None:
self.validate(value)
return value

try:
value = self.context.resolve('zope.app.menus.'+name)
value = self.context.resolve('zope.app.menus.' + name)
except ConfigurationError as v:
try:
value = self.context.resolve(name)
except ConfigurationError as v:
raise ValidationError(v)

self.validate(value)
return value
40 changes: 18 additions & 22 deletions src/zope/browsermenu/menu.py
Expand Up @@ -29,13 +29,13 @@
from zope.browsermenu.interfaces import IBrowserMenu, IMenuItemType
from zope.browsermenu.interfaces import IBrowserMenuItem, IBrowserSubMenuItem
from zope.browsermenu.interfaces import IMenuAccessView
from ._compat import _u


@implementer(IBrowserMenu)
class BrowserMenu(object):
"""Browser Menu"""

def __init__(self, id, title=_u(''), description=_u('')):
def __init__(self, id, title=u'', description=u''):
self.id = id
self.title = title
self.description = description
Expand All @@ -47,8 +47,8 @@ def getMenuItems(self, object, request):
"""Return menu item entries in a TAL-friendly form."""

result = []
for name, item in getAdapters((object, request),
self.getMenuItemType()):
for _name, item in getAdapters((object, request),
self.getMenuItemType()):
if item.available():
result.append(item)

Expand All @@ -60,16 +60,14 @@ def getMenuItems(self, object, request):
ifaces = list(providedBy(removeSecurityProxy(object)).__iro__)
max_key = len(ifaces)
def iface_index(item):
iface = item._for
if not iface:
iface = Interface
iface = item._for or Interface
if IInterface.providedBy(iface):
return ifaces.index(iface)
if isinstance(removeSecurityProxy(object), item._for):
# directly specified for class, this goes first.
return -1
# no idea. This goes last.
return max_key
return max_key # pragma: no cover
result = [(iface_index(item), item.order, item.title, item)
for item in result]
result.sort()
Expand All @@ -78,7 +76,7 @@ def iface_index(item):
{'title': title,
'description': item.description,
'action': item.action,
'selected': (item.selected() and _u('selected')) or _u(''),
'selected': (item.selected() and u'selected') or u'',
'icon': item.icon,
'extra': item.extra,
'submenu': (IBrowserSubMenuItem.providedBy(item) and
Expand All @@ -92,9 +90,9 @@ def iface_index(item):
class BrowserMenuItem(BrowserView):
"""Browser Menu Item Class"""

title = _u('')
description = _u('')
action = _u('')
title = u''
description = u''
action = u''
extra = None
order = 0
permission = None
Expand All @@ -110,7 +108,7 @@ def available(self):
if not checkPermission(self.permission, self.context):
return False

elif self.action != _u(''):
elif self.action != u'':
# Otherwise, test access by attempting access
path = self.action
l = self.action.find('?')
Expand All @@ -127,18 +125,18 @@ def available(self):
# we're assuming that view pages are callable
# this is a pretty sound assumption
if not canAccess(view, '__call__'):
return False
return False # pragma: no cover

# Make sure that we really want to see this menu item
if self.filter is not None:

try:
include = self.filter(Engine.getContext(
context = self.context,
nothing = None,
request = self.request,
modules = sys.modules,
))
context=self.context,
nothing=None,
request=self.request,
modules=sys.modules,
))
except Unauthorized:
return False
else:
Expand Down Expand Up @@ -171,9 +169,7 @@ class BrowserSubMenuItem(BrowserMenuItem):
submenuId = None

def selected(self):
if self.action is _u(''):
return False
return super(BrowserSubMenuItem, self).selected()
return False if self.action == u'' else super(BrowserSubMenuItem, self).selected()


def getMenu(id, object, request):
Expand Down

0 comments on commit 150b260

Please sign in to comment.