Skip to content

Commit

Permalink
Port to Python 3
Browse files Browse the repository at this point in the history
  • Loading branch information
jamadden committed Apr 20, 2017
1 parent 55044ec commit 05da517
Show file tree
Hide file tree
Showing 19 changed files with 199 additions and 152 deletions.
6 changes: 6 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
[run]
source = src

[report]
exclude_lines =
pragma: no cover
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ build/
dist/
*.egg-info/
.tox/
.coverage
htmlcov
15 changes: 13 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,9 +1,20 @@
language: python
sudo: false
python:
- 2.7
- pypy-5.4.1
- 3.5
- 3.6
install:
- pip install .
- pip install -U pip setuptools
- pip install -U coverage coveralls
- pip install -U -e .[test]
script:
- python setup.py test -q
- coverage run -m zope.testrunner --test-path=src --auto-color --auto-progress
notifications:
email: false
after_success:
- coveralls
cache: pip
before_cache:
- rm -f $HOME/.cache/pip/log/debug.log
3 changes: 2 additions & 1 deletion CHANGES.txt → CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,10 @@
Changes
=======

3.11.3 (unreleased)
4.0.0 (unreleased)
-------------------

- Add support for Python 3 and PyPy.
- Do not explicitly require ``zope.security [untrustedpython]``. Older
``zope.pagetemplate`` versions require it, newer ones do not.

Expand Down
1 change: 1 addition & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
include *.py
include *.txt
include *.rst
include buildout.cfg
recursive-include src *.pt
recursive-include src *.zcml
File renamed without changes.
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[bdist_wheel]
universal = 1
34 changes: 23 additions & 11 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,29 +20,40 @@
import os.path

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

version = '3.11.3dev'
version = '4.0.0.dev0'


setup(name='zope.app.pagetemplate',
version=version,
url='http://pypi.python.org/pypi/zope.app.pagetemplate',
url='http://github.com/zopefoundation/zope.app.pagetemplate',
author='Zope Corporation and Contributors',
author_email='zope-dev@zope.org',
description='PageTemplate integration for Zope 3',
long_description=(
read('README.txt')
read('README.rst')
+ '\n\n.. contents::\n\n' +
read('CHANGES.txt')
read('CHANGES.rst')
),
license='ZPL 2.1',
classifiers=['Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Framework :: Zope3',
],
classifiers=[
'Development Status :: 5 - Production/Stable',
'Environment :: Web Environment',
'Intended Audience :: Developers',
'License :: OSI Approved :: Zope Public License',
'Programming Language :: Python',
'Programming Language :: Python:: 2.7',
'Programming Language :: Python:: 3.5',
'Programming Language :: Python:: 3.6',
'Programming Language :: Python :: Implementation :: CPython',
'Programming Language :: Python :: Implementation :: PyPy',
'Natural Language :: English',
'Operating System :: OS Independent',
'Topic :: Internet :: WWW/HTTP',
'Framework :: Zope3'
],
packages=find_packages('src'),
package_dir={'': 'src'},
namespace_packages=['zope', 'zope.app'],
Expand All @@ -67,6 +78,7 @@ def read(*rnames):
'zope.component [hook,test]',
'zope.container',
'zope.publisher',
'zope.testrunner',
],
},
zip_safe=False,
Expand Down
3 changes: 1 addition & 2 deletions src/zope/app/pagetemplate/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
#
##############################################################################
"""Interfaces for apis to make available to TALES
$Id$
"""
from __future__ import print_function, absolute_import, division
__docformat__ = 'restructuredtext'

import zope.interface
Expand Down
3 changes: 0 additions & 3 deletions src/zope/app/pagetemplate/metaconfigure.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,6 @@
##############################################################################
"""ZCML configuration directives for configuring the default zope:
namespace in TALES.
$Id$
"""
__docformat__ = 'restructuredtext'

Expand All @@ -23,4 +21,3 @@
from zope.browserpage.metadirectives import IExpressionTypeDirective
from zope.browserpage.metaconfigure import expressiontype
from zope.browserpage.metaconfigure import registerType

2 changes: 0 additions & 2 deletions src/zope/app/pagetemplate/namedtemplate.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,6 @@
#
##############################################################################
"""
$Id$
"""

# BBB
Expand Down
1 change: 0 additions & 1 deletion src/zope/app/pagetemplate/simpleviewclass.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,6 @@
##############################################################################
"""Simple View Class
$Id$
"""
__docformat__ = 'restructuredtext'

Expand Down
16 changes: 9 additions & 7 deletions src/zope/app/pagetemplate/talesapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@
$Id$
"""
from __future__ import print_function, absolute_import, division
__docformat__ = 'restructuredtext'

from zope.interface import implements
from zope.interface import implementer
from zope.size.interfaces import ISized
from zope.security.interfaces import Unauthorized
from zope.tales.interfaces import ITALESFunctionNamespace
Expand All @@ -26,43 +27,44 @@
from zope.dublincore.interfaces import IZopeDublinCore
from zope.traversing.api import getName

@implementer(IDCTimes,
IDCDescriptiveProperties,
ITALESFunctionNamespace)
class ZopeTalesAPI(object):

implements(IDCTimes, IDCDescriptiveProperties, ITALESFunctionNamespace)

def __init__(self, context):
self.context = context

def setEngine(self, engine):
self._engine = engine

@property
def title(self):
a = IZopeDublinCore(self.context, None)
if a is None:
raise AttributeError('title')
return a.title
title = property(title)

@property
def description(self):
a = IZopeDublinCore(self.context, None)
if a is None:
raise AttributeError('description')
return a.description
description = property(description)

@property
def created(self):
a = IZopeDublinCore(self.context, None)
if a is None:
raise AttributeError('created')
return a.created
created = property(created)

@property
def modified(self):
a = IZopeDublinCore(self.context, None)
if a is None:
raise AttributeError('modified')
return a.modified
modified = property(modified)

def name(self):
return getName(self.context)
Expand Down
39 changes: 39 additions & 0 deletions src/zope/app/pagetemplate/tests/test_bwc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
##############################################################################
#
# Copyright (c) 2017 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
"""
Tests for deprecated/backwards-compatibility imports.
"""
from __future__ import print_function, absolute_import, division

import unittest

class TestBWC(unittest.TestCase):

def test_viewpagetemplatefile(self):
from zope.app.pagetemplate import viewpagetemplatefile

def test_i18n(self):
from zope.app.pagetemplate import i18n
self.assertIsNotNone(i18n.ZopeMessageFactory)

def test_metaconfigure(self):
from zope.app.pagetemplate import metaconfigure
self.assertIsNotNone(metaconfigure.clear)

def test_simpleviewclass(self):
from zope.app.pagetemplate import simpleviewclass
self.assertIsNotNone(simpleviewclass.simple)

def test_suite():
return unittest.defaultTestLoader.loadTestsFromName(__name__)
109 changes: 44 additions & 65 deletions src/zope/app/pagetemplate/tests/test_talesapi.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,24 +12,24 @@
#
##############################################################################
"""Tales API Tests
$Id$
"""
from __future__ import print_function, absolute_import, division

from datetime import datetime
from doctest import DocTestSuite
from zope.interface import implements
import unittest

from zope.interface import implementer
from zope.size.interfaces import ISized
from zope.traversing.interfaces import IPhysicallyLocatable
from zope.dublincore.interfaces import IZopeDublinCore

from zope.app.pagetemplate.talesapi import ZopeTalesAPI

@implementer(IZopeDublinCore, # not really, but who's checking. ;)
IPhysicallyLocatable, # not really
ISized)
class TestObject(object):

implements(IZopeDublinCore, # not really, but who's checking. ;)
IPhysicallyLocatable, # not really
ISized)

description = u"This object stores some number of apples"
title = u"apple cart"
created = datetime(2000, 10, 1, 23, 11, 00)
Expand All @@ -44,63 +44,42 @@ def sizeForDisplay(self):
def getName(self):
return u'apples'

testObject = TestObject()

def title():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.title
u'apple cart'
"""

def description():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.description
u'This object stores some number of apples'
"""

def name():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.name()
u'apples'
"""

def title_or_name():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.title_or_name()
u'apple cart'
>>> testObject = TestObject()
>>> testObject.title = u""
>>> api = ZopeTalesAPI(testObject)
>>> api.title_or_name()
u'apples'
"""

def size():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.size()
u'5 apples'
"""

def modified():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.modified
datetime.datetime(2003, 1, 2, 3, 4, 5)
"""

def created():
"""
>>> api = ZopeTalesAPI(testObject)
>>> api.created
datetime.datetime(2000, 10, 1, 23, 11)
"""

class TestAPI(unittest.TestCase):

def test_title(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject.title, api.title)

def test_description(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject.description, api.description)

def test_name(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject().getName(), api.name())

def test_title_or_name(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject.title, api.title_or_name())

testObject2 = TestObject()
testObject2.title = u""
api = ZopeTalesAPI(testObject2)
self.assertEqual(u'apples', api.title_or_name())

def test_size(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject().sizeForDisplay(), api.size())

def test_modified(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject.modified, api.modified)

def test_created(self):
api = ZopeTalesAPI(TestObject())
self.assertEqual(TestObject.created, api.created)


def test_suite():
return DocTestSuite()
return unittest.defaultTestLoader.loadTestsFromName(__name__)
Loading

0 comments on commit 05da517

Please sign in to comment.