Merge pull request #129 from plone/python3
Add Python 2 / 3 compatibility
This commit is contained in:
commit
d7c026964f
@ -14,7 +14,8 @@ New features:
|
|||||||
|
|
||||||
Bug fixes:
|
Bug fixes:
|
||||||
|
|
||||||
- *add item here*
|
- Add Python 2 / 3 compatibility
|
||||||
|
[pbauer]
|
||||||
|
|
||||||
|
|
||||||
3.0.4 (2017-11-24)
|
3.0.4 (2017-11-24)
|
||||||
|
@ -33,6 +33,9 @@ from zope.i18nmessageid import Message
|
|||||||
from zope.interface import alsoProvides
|
from zope.interface import alsoProvides
|
||||||
|
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
COMMENT_DESCRIPTION_PLAIN_TEXT = _(
|
COMMENT_DESCRIPTION_PLAIN_TEXT = _(
|
||||||
u'comment_description_plain_text',
|
u'comment_description_plain_text',
|
||||||
default=u'You can add a comment by filling out the form below. '
|
default=u'You can add a comment by filling out the form below. '
|
||||||
@ -152,11 +155,11 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
|||||||
if 'author_name' in data:
|
if 'author_name' in data:
|
||||||
author_name = data['author_name']
|
author_name = data['author_name']
|
||||||
if isinstance(author_name, str):
|
if isinstance(author_name, str):
|
||||||
author_name = unicode(author_name, 'utf-8')
|
author_name = six.text_type(author_name, 'utf-8')
|
||||||
if 'author_email' in data:
|
if 'author_email' in data:
|
||||||
author_email = data['author_email']
|
author_email = data['author_email']
|
||||||
if isinstance(author_email, str):
|
if isinstance(author_email, str):
|
||||||
author_email = unicode(author_email, 'utf-8')
|
author_email = six.text_type(author_email, 'utf-8')
|
||||||
|
|
||||||
# Set comment author properties for anonymous users or members
|
# Set comment author properties for anonymous users or members
|
||||||
portal_membership = getToolByName(context, 'portal_membership')
|
portal_membership = getToolByName(context, 'portal_membership')
|
||||||
@ -171,10 +174,10 @@ class CommentForm(extensible.ExtensibleForm, form.Form):
|
|||||||
if not fullname or fullname == '':
|
if not fullname or fullname == '':
|
||||||
fullname = member.getUserName()
|
fullname = member.getUserName()
|
||||||
elif isinstance(fullname, str):
|
elif isinstance(fullname, str):
|
||||||
fullname = unicode(fullname, 'utf-8')
|
fullname = six.text_type(fullname, 'utf-8')
|
||||||
author_name = fullname
|
author_name = fullname
|
||||||
if email and isinstance(email, str):
|
if email and isinstance(email, str):
|
||||||
email = unicode(email, 'utf-8')
|
email = six.text_type(email, 'utf-8')
|
||||||
# XXX: according to IComment interface author_email must not be
|
# XXX: according to IComment interface author_email must not be
|
||||||
# set for logged in users, cite:
|
# set for logged in users, cite:
|
||||||
# 'for anonymous comments only, set to None for logged in comments'
|
# 'for anonymous comments only, set to None for logged in comments'
|
||||||
@ -427,7 +430,7 @@ class CommentsViewlet(ViewletBase):
|
|||||||
"""
|
"""
|
||||||
if self.get_replies(workflow_actions) is not None:
|
if self.get_replies(workflow_actions) is not None:
|
||||||
try:
|
try:
|
||||||
self.get_replies(workflow_actions).next()
|
next(self.get_replies(workflow_actions))
|
||||||
return True
|
return True
|
||||||
except StopIteration: # pragma: no cover
|
except StopIteration: # pragma: no cover
|
||||||
pass
|
pass
|
||||||
|
@ -40,6 +40,9 @@ from zope.interface import implementer
|
|||||||
import logging
|
import logging
|
||||||
|
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
COMMENT_TITLE = _(
|
COMMENT_TITLE = _(
|
||||||
u'comment_title',
|
u'comment_title',
|
||||||
default=u'${author_name} on ${content}',
|
default=u'${author_name} on ${content}',
|
||||||
@ -122,7 +125,7 @@ class Comment(CatalogAware, WorkflowAware, DynamicType, Traversable,
|
|||||||
|
|
||||||
@property
|
@property
|
||||||
def __name__(self):
|
def __name__(self):
|
||||||
return self.comment_id and unicode(self.comment_id) or None
|
return self.comment_id and six.text_type(self.comment_id) or None
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def id(self):
|
def id(self):
|
||||||
@ -147,7 +150,7 @@ class Comment(CatalogAware, WorkflowAware, DynamicType, Traversable,
|
|||||||
text = self.text
|
text = self.text
|
||||||
if text is None:
|
if text is None:
|
||||||
return ''
|
return ''
|
||||||
if isinstance(text, unicode):
|
if isinstance(text, six.text_type):
|
||||||
text = text.encode('utf8')
|
text = text.encode('utf8')
|
||||||
transform = transforms.convertTo(
|
transform = transforms.convertTo(
|
||||||
targetMimetype,
|
targetMimetype,
|
||||||
@ -238,7 +241,7 @@ def notify_content_object_deleted(obj, event):
|
|||||||
if IAnnotatable.providedBy(obj):
|
if IAnnotatable.providedBy(obj):
|
||||||
conversation = IConversation(obj)
|
conversation = IConversation(obj)
|
||||||
while conversation:
|
while conversation:
|
||||||
del conversation[conversation.keys()[0]]
|
del conversation[list(conversation.keys())[0]]
|
||||||
|
|
||||||
|
|
||||||
def notify_comment_added(obj, event):
|
def notify_comment_added(obj, event):
|
||||||
@ -427,7 +430,7 @@ def notify_moderator(obj, event):
|
|||||||
# Send email
|
# Send email
|
||||||
try:
|
try:
|
||||||
mail_host.send(message, mto, sender, subject, charset='utf-8')
|
mail_host.send(message, mto, sender, subject, charset='utf-8')
|
||||||
except SMTPException, e:
|
except SMTPException as e:
|
||||||
logger.error('SMTP exception (%s) while trying to send an ' +
|
logger.error('SMTP exception (%s) while trying to send an ' +
|
||||||
'email notification to the comment moderator ' +
|
'email notification to the comment moderator ' +
|
||||||
'(from %s to %s, message: %s)',
|
'(from %s to %s, message: %s)',
|
||||||
|
@ -40,6 +40,9 @@ from zope.lifecycleevent import ObjectRemovedEvent
|
|||||||
import time
|
import time
|
||||||
|
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
@implementer(IConversation, IHideFromBreadcrumbs)
|
@implementer(IConversation, IHideFromBreadcrumbs)
|
||||||
class Conversation(Traversable, Persistent, Explicit):
|
class Conversation(Traversable, Persistent, Explicit):
|
||||||
"""A conversation is a container for all comments on a content object.
|
"""A conversation is a container for all comments on a content object.
|
||||||
@ -110,7 +113,7 @@ class Conversation(Traversable, Persistent, Explicit):
|
|||||||
def getComments(self, start=0, size=None):
|
def getComments(self, start=0, size=None):
|
||||||
"""Get unthreaded comments
|
"""Get unthreaded comments
|
||||||
"""
|
"""
|
||||||
count = 0l
|
count = 0
|
||||||
for comment in self._comments.values(min=start):
|
for comment in self._comments.values(min=start):
|
||||||
# Yield the acquisition wrapped comment
|
# Yield the acquisition wrapped comment
|
||||||
yield self[comment.id]
|
yield self[comment.id]
|
||||||
@ -138,7 +141,7 @@ class Conversation(Traversable, Persistent, Explicit):
|
|||||||
# Find top level threads
|
# Find top level threads
|
||||||
comments = self._children.get(root, None)
|
comments = self._children.get(root, None)
|
||||||
if comments is not None:
|
if comments is not None:
|
||||||
count = 0l
|
count = 0
|
||||||
for comment_id in comments.keys(min=start):
|
for comment_id in comments.keys(min=start):
|
||||||
|
|
||||||
# Abort if we have found all the threads we want
|
# Abort if we have found all the threads we want
|
||||||
@ -274,14 +277,14 @@ class Conversation(Traversable, Persistent, Explicit):
|
|||||||
return [v.__of__(self) for v in self._comments.values()]
|
return [v.__of__(self) for v in self._comments.values()]
|
||||||
|
|
||||||
def iterkeys(self):
|
def iterkeys(self):
|
||||||
return self._comments.iterkeys()
|
return six.iterkeys(self._comments)
|
||||||
|
|
||||||
def itervalues(self):
|
def itervalues(self):
|
||||||
for v in self._comments.itervalues():
|
for v in six.itervalues(self._comments):
|
||||||
yield v.__of__(self)
|
yield v.__of__(self)
|
||||||
|
|
||||||
def iteritems(self):
|
def iteritems(self):
|
||||||
for k, v in self._comments.iteritems():
|
for k, v in six.iteritems(self._comments):
|
||||||
yield (k, v.__of__(self),)
|
yield (k, v.__of__(self),)
|
||||||
|
|
||||||
def allowedContentTypes(self):
|
def allowedContentTypes(self):
|
||||||
@ -334,7 +337,7 @@ class ConversationReplies(object):
|
|||||||
|
|
||||||
def __init__(self, context):
|
def __init__(self, context):
|
||||||
self.conversation = context
|
self.conversation = context
|
||||||
self.comment_id = 0l
|
self.comment_id = 0
|
||||||
|
|
||||||
def addComment(self, comment):
|
def addComment(self, comment):
|
||||||
comment.in_reply_to = None
|
comment.in_reply_to = None
|
||||||
|
@ -17,7 +17,7 @@ Create a collection.
|
|||||||
>>> open('/tmp/testbrowser.html', 'w').write(browser.contents)
|
>>> open('/tmp/testbrowser.html', 'w').write(browser.contents)
|
||||||
>>> browser.getControl('form.widgets.IDublinCore.title').value = 'Foo Comment Collection'
|
>>> browser.getControl('form.widgets.IDublinCore.title').value = 'Foo Comment Collection'
|
||||||
>>> browser.getControl('Save').click()
|
>>> browser.getControl('Save').click()
|
||||||
>>> print browser.contents
|
>>> print(browser.contents)
|
||||||
<...Changes saved...
|
<...Changes saved...
|
||||||
>>> topic_url = browser.url
|
>>> topic_url = browser.url
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ Set the collection criteria.
|
|||||||
... browser.getControl('Add criteria').click()
|
... browser.getControl('Add criteria').click()
|
||||||
... browser.getControl('Comment').selected = True
|
... browser.getControl('Comment').selected = True
|
||||||
... browser.getControl('Save', index=0).click()
|
... browser.getControl('Save', index=0).click()
|
||||||
>>> print browser.contents
|
>>> print(browser.contents)
|
||||||
<...Changes saved...
|
<...Changes saved...
|
||||||
|
|
||||||
View the collection listing.
|
View the collection listing.
|
||||||
@ -66,7 +66,7 @@ Delete the commented content.
|
|||||||
>>> browser.open(urldoc1)
|
>>> browser.open(urldoc1)
|
||||||
>>> browser.getLink('Delete').click()
|
>>> browser.getLink('Delete').click()
|
||||||
>>> browser.getControl('Delete').click()
|
>>> browser.getControl('Delete').click()
|
||||||
>>> print browser.contents
|
>>> print(browser.contents)
|
||||||
<...Doc1 has been deleted...
|
<...Doc1 has been deleted...
|
||||||
|
|
||||||
The comments are no longer in the catalog.
|
The comments are no longer in the catalog.
|
||||||
|
@ -565,8 +565,8 @@ class TestCommentsViewlet(unittest.TestCase):
|
|||||||
replies = self.viewlet.get_replies()
|
replies = self.viewlet.get_replies()
|
||||||
self.assertEqual(len(tuple(replies)), 2)
|
self.assertEqual(len(tuple(replies)), 2)
|
||||||
replies = self.viewlet.get_replies()
|
replies = self.viewlet.get_replies()
|
||||||
replies.next()
|
next(replies)
|
||||||
replies.next()
|
next(replies)
|
||||||
self.assertRaises(StopIteration, replies.next)
|
self.assertRaises(StopIteration, replies.next)
|
||||||
|
|
||||||
def test_get_replies_on_non_annotatable_object(self):
|
def test_get_replies_on_non_annotatable_object(self):
|
||||||
@ -593,7 +593,7 @@ class TestCommentsViewlet(unittest.TestCase):
|
|||||||
('comment_review_workflow,')
|
('comment_review_workflow,')
|
||||||
)
|
)
|
||||||
# Check if workflow actions are available
|
# Check if workflow actions are available
|
||||||
reply = self.viewlet.get_replies(workflow_actions=True).next()
|
reply = next(self.viewlet.get_replies(workflow_actions=True))
|
||||||
self.assertTrue('actions' in reply)
|
self.assertTrue('actions' in reply)
|
||||||
self.assertEqual(
|
self.assertEqual(
|
||||||
reply['actions'][0]['id'],
|
reply['actions'][0]['id'],
|
||||||
|
@ -22,6 +22,9 @@ from zope.component import queryUtility
|
|||||||
import unittest
|
import unittest
|
||||||
|
|
||||||
|
|
||||||
|
import six
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from plone.dexterity.interfaces import IDexterityContent
|
from plone.dexterity.interfaces import IDexterityContent
|
||||||
DEXTERITY = True
|
DEXTERITY = True
|
||||||
@ -383,17 +386,17 @@ class ConversationTest(unittest.TestCase):
|
|||||||
self.assertTrue(comment2 in conversation.values())
|
self.assertTrue(comment2 in conversation.values())
|
||||||
|
|
||||||
# check if comment ids are in iterkeys
|
# check if comment ids are in iterkeys
|
||||||
self.assertTrue(new_id1 in conversation.iterkeys())
|
self.assertTrue(new_id1 in six.iterkeys(conversation))
|
||||||
self.assertTrue(new_id2 in conversation.iterkeys())
|
self.assertTrue(new_id2 in six.iterkeys(conversation))
|
||||||
self.assertFalse(123 in conversation.iterkeys())
|
self.assertFalse(123 in six.iterkeys(conversation))
|
||||||
|
|
||||||
# check if comment objects are in itervalues
|
# check if comment objects are in itervalues
|
||||||
self.assertTrue(comment1 in conversation.itervalues())
|
self.assertTrue(comment1 in six.itervalues(conversation))
|
||||||
self.assertTrue(comment2 in conversation.itervalues())
|
self.assertTrue(comment2 in six.itervalues(conversation))
|
||||||
|
|
||||||
# check if iteritems returns (key, comment object) pairs
|
# check if iteritems returns (key, comment object) pairs
|
||||||
self.assertTrue((new_id1, comment1) in conversation.iteritems())
|
self.assertTrue((new_id1, comment1) in six.iteritems(conversation))
|
||||||
self.assertTrue((new_id2, comment2) in conversation.iteritems())
|
self.assertTrue((new_id2, comment2) in six.iteritems(conversation))
|
||||||
|
|
||||||
# TODO test acquisition wrapping
|
# TODO test acquisition wrapping
|
||||||
# self.assertTrue(aq_base(aq_parent(comment1)) is conversation)
|
# self.assertTrue(aq_base(aq_parent(comment1)) is conversation)
|
||||||
|
@ -156,7 +156,7 @@ class ModerationBulkActionsViewTest(unittest.TestCase):
|
|||||||
|
|
||||||
# Make sure that the two comments have been deleted
|
# Make sure that the two comments have been deleted
|
||||||
self.assertEqual(len(self.conversation.objectIds()), 1)
|
self.assertEqual(len(self.conversation.objectIds()), 1)
|
||||||
comment = self.conversation.getComments().next()
|
comment = next(self.conversation.getComments())
|
||||||
self.assertTrue(comment)
|
self.assertTrue(comment)
|
||||||
self.assertEqual(comment, self.comment2)
|
self.assertEqual(comment, self.comment2)
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user