Skip to content

Commit

Permalink
Merge pull request #51 from zopefoundation/davisagli-py3
Browse files Browse the repository at this point in the history
[WIP] Python 3 support
  • Loading branch information
dataflake committed May 16, 2018
2 parents f75c0de + 5f7a084 commit 6d67f02
Show file tree
Hide file tree
Showing 39 changed files with 682 additions and 532 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
.eggs
.installed.cfg
.mr.developer.cfg
.Python
.tox
bin
build
Expand All @@ -21,6 +22,10 @@ local.cfg
parts
src
var
/include
/lib*
pip-selfcheck.json
/src
docs/_build/

# VirtualEnv on Windows:
Expand Down
5 changes: 5 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
sudo: false
language: python
cache:
directories:
- $TRAVIS_BUILD_DIR/eggs
python:
- "2.7"
- "3.5"
- "3.6"
install:
- pip install -U coverage coveralls
- pip install -U six==$(curl $(awk '$1 == "extends" {print $3}' buildout.cfg) 2>/dev/null | awk '$1 == "six" {print $3}')
Expand Down
14 changes: 12 additions & 2 deletions CHANGES.rst
Original file line number Diff line number Diff line change
@@ -1,8 +1,17 @@
Changelog
=========

1.10.1 (unreleased)
-------------------
2.0 (unreleased)
----------------

Breaking changes:

- Require Zope 4.0b4 as minimum supported Zope version and drop
explicit ``Zope2`` egg dependency.

- Drop Python 3.4 support

New features:

- Fixed tests with ``Products.ZCatalog 4.1``. [maurits]

Expand All @@ -12,6 +21,7 @@ Changelog
- Prevent AttributeError 'NoneType' object has no attribute 'decode'.
[maurits]

- Finished compatibility with Python 3.5 and 3.6

1.10.0 (2017-12-07)
-------------------
Expand Down
14 changes: 12 additions & 2 deletions Products/GenericSetup/OFSP/tests/test_exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,14 @@

import unittest

from Products.GenericSetup.interfaces import IBody
from Products.GenericSetup.testing import BodyAdapterTestCase
from Products.GenericSetup.testing import ExportImportZCMLLayer
from Products.GenericSetup.testing import DummySetupEnviron
from zope.component import getMultiAdapter

_FOLDER_BODY = """\
<?xml version="1.0"?>
_FOLDER_BODY = b"""\
<?xml version="1.0" encoding="utf-8"?>
<object name="foo_folder" meta_type="Folder">
<property name="title">Foo</property>
</object>
Expand Down Expand Up @@ -48,6 +51,13 @@ def setUp(self):
self._obj = Folder('foo_folder')
self._BODY = _FOLDER_BODY

def test_body_set_without_encoding(self):
context = DummySetupEnviron()
adapted = getMultiAdapter((self._obj, context), IBody)
adapted.body = self._BODY.replace(b'encoding="utf-8"', b'')
self._verifyImport(self._obj)
self.assertEqual(adapted.body, self._BODY)


def test_suite():
return unittest.TestSuite((
Expand Down
4 changes: 3 additions & 1 deletion Products/GenericSetup/PageTemplates/exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@

from .interfaces import IZopePageTemplate

import six


class ZopePageTemplateBodyAdapter(BodyAdapterBase):

Expand All @@ -32,7 +34,7 @@ def _exportBody(self):
"""Export the object as a file body.
"""
text = self.context.read()
if isinstance(text, unicode):
if isinstance(text, six.text_type):
return text.encode('utf-8')
return text

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
from Products.GenericSetup.testing import BodyAdapterTestCase
from Products.GenericSetup.testing import ExportImportZCMLLayer

_PAGETEMPLATE_BODY = """\
_PAGETEMPLATE_BODY = b"""\
<html>
<div>Foo</div>
</html>
Expand Down
8 changes: 4 additions & 4 deletions Products/GenericSetup/PluginIndexes/exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ def _importNode(self, node):
for child in node.childNodes:
if child.nodeName == 'indexed_attr':
indexed_attrs.append(
child.getAttribute('value').encode('utf-8'))
child.getAttribute('value'))
if _before != indexed_attrs:
self.context.indexed_attrs = indexed_attrs
self.context.clear()
Expand Down Expand Up @@ -114,8 +114,8 @@ def _importNode(self, node):
"""Import the object from the DOM node.
"""
_before = (self.context._since_field, self.context._until_field)
self.context._edit(node.getAttribute('since_field').encode('utf-8'),
node.getAttribute('until_field').encode('utf-8'))
self.context._edit(node.getAttribute('since_field'),
node.getAttribute('until_field'))
_after = (self.context._since_field, self.context._until_field)
if _before != _after:
self.context.clear()
Expand Down Expand Up @@ -157,7 +157,7 @@ def _importNode(self, node):
"""
_before = self.context.expr
self.context.setExpression(
node.getAttribute('expression').encode('utf-8'))
node.getAttribute('expression'))
_after = self.context.expr
if _before != _after:
self.context.clear()
Expand Down
47 changes: 38 additions & 9 deletions Products/GenericSetup/PluginIndexes/tests/test_exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,44 +18,44 @@
from Products.GenericSetup.testing import NodeAdapterTestCase
from Products.GenericSetup.testing import ExportImportZCMLLayer

_DATE_XML = """\
_DATE_XML = b"""\
<index name="foo_date" meta_type="DateIndex">
<property name="index_naive_time_as_local">True</property>
<property name="precision">1</property>
<property name="precision">0</property>
</index>
"""

_DATERANGE_XML = """\
_DATERANGE_XML = b"""\
<index name="foo_daterange" meta_type="DateRangeIndex" since_field="bar"
until_field="baz"/>
"""

_FIELD_XML = """\
_FIELD_XML = b"""\
<index name="foo_field" meta_type="FieldIndex">
<indexed_attr value="bar"/>
</index>
"""

_KEYWORD_XML = """\
_KEYWORD_XML = b"""\
<index name="foo_keyword" meta_type="KeywordIndex">
<indexed_attr value="bar"/>
</index>
"""

_ODDBALL_XML = """\
_ODDBALL_XML = b"""\
<index name="foo_keyword" meta_type="OddballIndex">
</index>
"""

_PATH_XML = """\
_PATH_XML = b"""\
<index name="foo_path" meta_type="PathIndex"/>
"""

_SET_XML = """\
_SET_XML = b"""\
<filtered_set name="bar" meta_type="PythonFilteredSet" expression="True"/>
"""

_TOPIC_XML = """\
_TOPIC_XML = b"""\
<index name="foo_topic" meta_type="TopicIndex">
<filtered_set name="bar" meta_type="PythonFilteredSet" expression="True"/>
<filtered_set name="baz" meta_type="PythonFilteredSet" expression="False"/>
Expand All @@ -75,8 +75,12 @@ def _getTargetClass(self):
def setUp(self):
from Products.PluginIndexes.DateIndex.DateIndex import DateIndex
self._obj = DateIndex('foo_date')
self._obj._setPropValue('precision', 0)
self._XML = _DATE_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'foo_date')


class DateRangeIndexNodeAdapterTests(NodeAdapterTestCase, unittest.TestCase):

Expand All @@ -96,6 +100,11 @@ def setUp(self):
self._obj = DateRangeIndex('foo_daterange')
self._XML = _DATERANGE_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'foo_daterange')
self.assertEqual(obj._since_field, 'bar')
self.assertEqual(obj._until_field, 'baz')


class FieldIndexNodeAdapterTests(NodeAdapterTestCase, unittest.TestCase):

Expand All @@ -114,6 +123,10 @@ def setUp(self):
self._obj = FieldIndex('foo_field')
self._XML = _FIELD_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'foo_field')
self.assertEqual(obj.indexed_attrs, ['bar'])


class KeywordIndexNodeAdapterTests(NodeAdapterTestCase, unittest.TestCase):

Expand All @@ -133,6 +146,10 @@ def setUp(self):
self._obj = KeywordIndex('foo_keyword')
self._XML = _KEYWORD_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'foo_keyword')
self.assertEqual(obj.indexed_attrs, ['bar'])


class PathIndexNodeAdapterTests(NodeAdapterTestCase, unittest.TestCase):

Expand All @@ -148,6 +165,9 @@ def setUp(self):
self._obj = PathIndex('foo_path')
self._XML = _PATH_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'foo_path')


class FilteredSetNodeAdapterTests(NodeAdapterTestCase, unittest.TestCase):

Expand All @@ -167,6 +187,10 @@ def setUp(self):
self._obj = PythonFilteredSet('bar', '')
self._XML = _SET_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'bar')
self.assertEqual(obj.getExpression(), 'True')


class TopicIndexNodeAdapterTests(NodeAdapterTestCase, unittest.TestCase):

Expand All @@ -186,6 +210,10 @@ def setUp(self):
self._obj = TopicIndex('foo_topic')
self._XML = _TOPIC_XML

def _verifyImport(self, obj):
self.assertEqual(obj.id, 'foo_topic')
self.assertEqual(len(obj.filteredSets), 2)


class UnchangedTests(unittest.TestCase):

Expand Down Expand Up @@ -248,6 +276,7 @@ def _no_clear(*a):
raise AssertionError("Don't clear me!")
index = DateIndex('foo_date')
index._setPropValue('index_naive_time_as_local', True)
index._setPropValue('precision', 0)
index.clear = _no_clear
adapted = DateIndexNodeAdapter(index, environ)
adapted.node = parseString(_DATE_XML).documentElement # no raise
Expand Down
6 changes: 5 additions & 1 deletion Products/GenericSetup/PythonScripts/exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@
"""PythonScript export / import support.
"""

import six

from zope.component import adapts

from Products.GenericSetup.interfaces import ISetupEnviron
Expand All @@ -31,11 +33,13 @@ class PythonScriptBodyAdapter(BodyAdapterBase):
def _exportBody(self):
"""Export the object as a file body.
"""
return self.context.read()
return self.context.read().encode('utf-8')

def _importBody(self, body):
"""Import the object from the file body.
"""
if six.PY3:
body = body.decode('utf-8')
body = body.replace('\r\n', '\n').replace('\r', '\n')
self.context.write(body)

Expand Down
10 changes: 9 additions & 1 deletion Products/GenericSetup/PythonScripts/tests/test_exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@
"""PythonScript export / import support unit tests.
"""

import six
import unittest

from Products.GenericSetup.testing import BodyAdapterTestCase
from Products.GenericSetup.testing import ExportImportZCMLLayer

_PYTHONSCRIPT_BODY = """\
_PYTHONSCRIPT_BODY = b"""\
## Script (Python) "foo_script"
##bind container=container
##bind context=context
Expand Down Expand Up @@ -47,6 +48,13 @@ def setUp(self):
self._obj = PythonScript('foo_script')
self._BODY = _PYTHONSCRIPT_BODY

def _verifyImport(self, obj):
# Imported script body should be a native string
expected = _PYTHONSCRIPT_BODY
if six.PY3:
expected = _PYTHONSCRIPT_BODY.decode('utf-8')
self.assertEqual(obj.read(), expected)


def test_suite():
return unittest.TestSuite((
Expand Down
6 changes: 3 additions & 3 deletions Products/GenericSetup/ZCTextIndex/exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,8 +52,8 @@ def _importNode(self, node):
for child in node.childNodes:
if child.nodeName == 'element':
element = element_factory.instantiate(
child.getAttribute('group').encode('utf-8'),
child.getAttribute('name').encode('utf-8'))
child.getAttribute('group'),
child.getAttribute('name'))
pipeline.append(element)
pipeline = tuple(pipeline)
if self.context._pipeline != pipeline:
Expand Down Expand Up @@ -108,7 +108,7 @@ def _importNode(self, node):
for child in node.childNodes:
if child.nodeName == 'indexed_attr':
indexed_attrs.append(
child.getAttribute('value').encode('utf-8'))
child.getAttribute('value'))
if self.context._indexed_attrs != indexed_attrs:
self.context._indexed_attrs = indexed_attrs
self.context.clear()
Expand Down
8 changes: 4 additions & 4 deletions Products/GenericSetup/ZCTextIndex/tests/test_exportimport.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,15 +20,15 @@
from Products.GenericSetup.testing import NodeAdapterTestCase
from Products.GenericSetup.testing import ExportImportZCMLLayer

_PLEXICON_XML = """\
_PLEXICON_XML = b"""\
<object name="foo_plexicon" meta_type="ZCTextIndex Lexicon">
<element name="Whitespace splitter" group="Word Splitter"/>
<element name="Case Normalizer" group="Case Normalizer"/>
<element name="Remove listed stop words only" group="Stop Words"/>
</object>
"""

_ZCTEXT_XML = """\
_ZCTEXT_XML = b"""\
<index name="foo_zctext" meta_type="ZCTextIndex">
<indexed_attr value="foo_zctext"/>
<indexed_attr value="baz_zctext"/>
Expand Down Expand Up @@ -109,7 +109,7 @@ def test_ZCLexicon(self):
from Products.GenericSetup.ZCTextIndex.exportimport \
import ZCLexiconNodeAdapter

_XML = """\
_XML = b"""\
<object name="foo_plexicon" meta_type="ZCTextIndex Lexicon">
<element name="foo" group="gs"/>
<element name="bar" group="gs"/>
Expand Down Expand Up @@ -140,7 +140,7 @@ def test_ZCTextIndex(self):
from Products.GenericSetup.testing import DummySetupEnviron
from Products.GenericSetup.ZCTextIndex.exportimport \
import ZCTextIndexNodeAdapter
_XML = """\
_XML = b"""\
<index name="foo_zctext" meta_type="ZCTextIndex">
<indexed_attr value="bar"/>
<extra name="index_type" value="Okapi BM25 Rank"/>
Expand Down

0 comments on commit 6d67f02

Please sign in to comment.