Skip to content

Commit

Permalink
Merge pull request #71 from plone/python3
Browse files Browse the repository at this point in the history
py3 compatibility
  • Loading branch information
jensens committed Feb 8, 2019
2 parents 9f5c18c + a287651 commit 3528945
Show file tree
Hide file tree
Showing 27 changed files with 251 additions and 179 deletions.
26 changes: 18 additions & 8 deletions .travis.yml
@@ -1,28 +1,38 @@
language: python
python: 2.7
sudo: false
env:
- PLONE_VERSION=4.x
- PLONE_VERSION=5.x
matrix:
include:
- python: "2.7"
env: PLONE_VERSION=4.3.x
- python: "2.7"
env: PLONE_VERSION=5.1.x
- python: "2.7"
env: PLONE_VERSION=5.2.x
- python: "3.6"
env: PLONE_VERSION=5.2.x
- python: "3.7"
env: PLONE_VERSION=5.2.x
dist: xenial
sudo: true
fast_finish: true
cache:
pip: true
directories:
- $HOME/buildout-cache
matrix:
fast_finish: true
before_install:
- mkdir -p $HOME/buildout-cache/{eggs,downloads}
- mkdir $HOME/.buildout
- echo "[buildout]" > $HOME/.buildout/default.cfg
- echo "download-cache = $HOME/buildout-cache/downloads" >> $HOME/.buildout/default.cfg
- echo "eggs-directory = $HOME/buildout-cache/eggs" >> $HOME/.buildout/default.cfg
- pip install zc.buildout
- sed -ie "s#test-4.x.cfg#test-$PLONE_VERSION.cfg#" buildout.cfg
- sed -ie "s#test-x.x.x.cfg#test-$PLONE_VERSION.cfg#" buildout.cfg
install:
- buildout -N -t 3 annotate
- buildout -N -t 3
script:
- bin/code-analysis
# Run code-analysis, except on Python 3.6, which mysteriously fails to find zc.buildout.
- python --version 2> /dev/stdout | grep 3.6 || bin/code-analysis
- bin/test
after_success:
- bin/createcoverage -d 'htmlcov'
Expand Down
8 changes: 4 additions & 4 deletions CHANGES.rst
@@ -1,10 +1,10 @@
Changelog
=========

4.2.1 (unreleased)
4.3.0 (unreleased)
------------------

Breaking chnages:
Breaking changes:

- Nothing changed yet.

Expand All @@ -16,8 +16,8 @@ Bug fixes:

New features:

- Nothing changed yet.

- python3 compatibility
[petschki]

4.2.0 (2018-07-02)
------------------
Expand Down
25 changes: 1 addition & 24 deletions buildout.cfg
@@ -1,33 +1,10 @@
[buildout]
extends =
https://raw.githubusercontent.com/collective/buildout.plonetest/master/test-4.x.cfg
https://raw.githubusercontent.com/collective/buildout.plonetest/master/qa.cfg
test-x.x.x.cfg

package-name = plone.app.blocks
package-extras = [test]

parts +=
createcoverage

extensions = mr.developer
auto-checkout =
plone.jsonserializer
plone.subrequest
plone.tiles

[sources]
plone.jsonserializer = git git://github.com/plone/plone.jsonserializer.git
plone.tiles = git git://github.com/plone/plone.tiles.git branch=master
plone.subrequest = git git://github.com/plone/plone.subrequest.git

[code-analysis]
directory = plone
flake8-ignore = E501,C901

[versions]
setuptools =
zc.buildout =
coverage = >=3.7
plone.behavior = >=1.1
plone.app.blocks =

7 changes: 4 additions & 3 deletions plone/app/blocks/indexing.py
Expand Up @@ -8,8 +8,9 @@
from zope.annotation.interfaces import IAnnotations
from zope.component import adapter
from zope.interface import implementer
import pkg_resources

import pkg_resources
import six

try:
pkg_resources.get_distribution('collective.dexteritytextindexer')
Expand All @@ -26,7 +27,7 @@
def concat(*args):
result = ''
for value in args:
if isinstance(value, unicode):
if isinstance(value, six.text_type):
value = value.encode('utf-8', 'replace')
if value:
result = ' '.join((result, value))
Expand Down Expand Up @@ -57,7 +58,7 @@ def LayoutSearchableText(obj):
data = annotations[key]
for field_name in ('title', 'label', 'content'):
val = data.get(field_name)
if isinstance(val, basestring):
if isinstance(val, six.string_types):
text.append(val)

try:
Expand Down
18 changes: 11 additions & 7 deletions plone/app/blocks/layoutbehavior.py
@@ -1,14 +1,19 @@
# -*- coding: utf-8 -*-
import json
import logging
import six
import zope.deferredimport

from Acquisition import aq_base
from Acquisition import aq_inner
from Acquisition import aq_parent
from lxml import etree
from lxml import html
from plone.app.blocks.interfaces import _
from plone.app.blocks.interfaces import DEFAULT_AJAX_LAYOUT_REGISTRY_KEY
from plone.app.blocks.interfaces import DEFAULT_CONTENT_LAYOUT_REGISTRY_KEY
from plone.app.blocks.interfaces import DEFAULT_SITE_LAYOUT_REGISTRY_KEY
from plone.app.blocks.interfaces import ILayoutField
from plone.app.blocks.interfaces import _
from plone.app.blocks.utils import applyTilePersistent
from plone.app.blocks.utils import resolveResource
from plone.autoform.directives import omitted
Expand All @@ -19,25 +24,22 @@
from plone.memoize import view
from plone.registry.interfaces import IRegistry
from plone.rfc822.interfaces import IPrimaryField
from plone.supermodel.directives import fieldset
from plone.supermodel import model
from plone.supermodel.directives import fieldset
from plone.tiles.data import defaultTileDataStorage
from plone.tiles.interfaces import ITile
from plone.tiles.interfaces import ITileDataStorage
from plone.tiles.interfaces import ITileType
from repoze.xmliter.utils import getHTMLSerializer
from zExceptions import NotFound
from zope import schema
from zope.component import adapter
from zope.component import getUtility
from zope.component import queryUtility
from zope.deprecation import deprecate
from zope import schema
from zope.interface import implementer
from zope.interface import Interface
from zope.interface import implementer
from zope.interface import provider
import json
import logging
import zope.deferredimport

logger = logging.getLogger('plone.app.blocks')

Expand Down Expand Up @@ -175,6 +177,8 @@ def content_layout(self):
path = self.content_layout_path()
try:
resolved = resolveResource(path)
if isinstance(resolved, six.text_type):
resolved = resolved.encode('utf-8')
layout = applyTilePersistent(path, resolved)
except (NotFound, RuntimeError, IOError):
pass
Expand Down
16 changes: 6 additions & 10 deletions plone/app/blocks/panel.py
@@ -1,10 +1,6 @@
# -*- coding: utf-8 -*-
from plone.app.blocks import utils
from urllib import urlencode
from urlparse import parse_qs
from urlparse import urljoin
from urlparse import urlparse
from urlparse import urlunparse
from six.moves.urllib import parse


def merge(request, pageTree, removePanelLinks=False, removeLayoutLink=True):
Expand All @@ -23,15 +19,15 @@ def merge(request, pageTree, removePanelLinks=False, removeLayoutLink=True):
if request.getVirtualRoot():
# plone.subrequest deals with VHM requests
baseURL = ''
layoutHref = urljoin(baseURL, layoutHref) # turn the link absolute
layoutHref = parse.urljoin(baseURL, layoutHref) # noqa: turn the link absolute
# Pass special ajax_load parameter forward to allow layout indirection
# views to select, for example, default AJAX layout instead of full layout.
if request.form.get('ajax_load'):
parts = list(urlparse(layoutHref))
query = parse_qs(parts[4])
parts = list(parse.urlparse(layoutHref))
query = parse.parse_qs(parts[4])
query['ajax_load'] = request.form.get('ajax_load')
parts[4] = urlencode(query)
layoutHref = urlunparse(parts)
parts[4] = parse.urlencode(query)
layoutHref = parse.urlunparse(parts)
layoutTree = utils.resolve(layoutHref)
if layoutTree is None:
return None
Expand Down
26 changes: 19 additions & 7 deletions plone/app/blocks/resource.py
@@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from Acquisition import aq_parent
from App.config import getConfiguration
from ConfigParser import SafeConfigParser
from OFS.interfaces import ITraversable
from Products.CMFCore.utils import getToolByName
from plone.app.blocks.interfaces import CONTENT_LAYOUT_FILE_NAME
from plone.app.blocks.interfaces import CONTENT_LAYOUT_MANIFEST_FORMAT
from plone.app.blocks.interfaces import CONTENT_LAYOUT_RESOURCE_NAME
Expand All @@ -21,7 +21,8 @@
from plone.resource.traversal import ResourceTraverser
from plone.resource.utils import iterDirectoriesOfType
from plone.subrequest import ISubRequest
from Products.CMFCore.utils import getToolByName
from six.moves.configparser import ConfigParser
from six.moves.urllib import parse
from zExceptions import NotFound
from zope.annotation import IAnnotations
from zope.component import adapter
Expand All @@ -34,8 +35,7 @@
from zope.site.hooks import getSite

import logging
import urlparse

import six

logger = logging.getLogger('plone.app.blocks')

Expand Down Expand Up @@ -80,8 +80,17 @@ def __setitem__(self, key, val):


def getLayoutsFromManifest(fp, _format, directory_name):
parser = SafeConfigParser(None, multidict)
parser.readfp(fp)
# support multiple sections with the same name in manifest.cfg

if six.PY2:
parser = ConfigParser(None, multidict)
parser.readfp(fp)
else:
data = fp.read()
if isinstance(data, six.binary_type):
data = data.decode()
parser = ConfigParser(dict_type=multidict, strict=False)
parser.read_string(data)

layouts = {}
for section in parser.sections():
Expand Down Expand Up @@ -275,9 +284,12 @@ def layout(self):
if pathContext is None:
break

if isinstance(layout, six.binary_type):
layout = layout.decode()

path = layout
if pathContext is not None:
path = urlparse.urljoin(pathContext.absolute_url_path(), layout)
path = parse.urljoin(pathContext.absolute_url_path(), layout)

return path

Expand Down
2 changes: 1 addition & 1 deletion plone/app/blocks/testing.py
Expand Up @@ -110,4 +110,4 @@ def tearDown(self):
bases=(BLOCKS_FIXTURE,), name="Blocks:Functional")
BLOCKS_FUNCTIONAL_TESTING_PRETTY_PRINT = FunctionalTesting(
bases=(PRETTY_PRINT_FIXTURE, BLOCKS_FIXTURE,),
name="Blocks:Functional Pretty Printing")
name="Blocks:FunctionalPrettyPrinting")
10 changes: 5 additions & 5 deletions plone/app/blocks/tests/context.rst
Expand Up @@ -23,10 +23,10 @@ and page layouts, respectively::
... </html>
... """ % self.context.Title()

>>> from zope.interface import implements
>>> from zope.interface import implementer
>>> from plone.app.blocks.interfaces import IBlocksTransformEnabled
>>> class PageLayout(BrowserView):
... implements(IBlocksTransformEnabled)
>>> @implementer(IBlocksTransformEnabled)
... class PageLayout(BrowserView):
... __name__ = 'page-layout'
... def __call__(self):
... return u"""
Expand All @@ -45,7 +45,7 @@ relative URL.
Next, we initialize and register the browser views as ZCML handlers would::

>>> from zope.interface import Interface
>>> from Products.Five.security import protectClass
>>> from AccessControl.security import protectClass
>>> protectClass(SiteLayout, 'zope2.View')
>>> protectClass(PageLayout, 'zope2.View')

Expand All @@ -67,7 +67,7 @@ the default title of the portal object, ``Plone site`` will be used::

>>> portal = layer['portal']
>>> browser.open(portal.absolute_url() + '/@@page-layout')
>>> print browser.contents
>>> print(browser.contents)
<!DOCTYPE html...
<title>Plone site</title>...
<div data-panel="content">Plone site</div>...
16 changes: 8 additions & 8 deletions plone/app/blocks/tests/esi.rst
Expand Up @@ -83,7 +83,7 @@ Register these in the same way that the ZCML handlers would, more or less.

.. code-block:: python
>>> from Products.Five.security import protectClass
>>> from AccessControl.security import protectClass
>>> protectClass(NonESITile, 'zope2.View')
>>> protectClass(SimpleESITile, 'zope2.View')
Expand Down Expand Up @@ -144,10 +144,10 @@ instead just referencing a view containing the layout directly.
... </html>
... """
>>> from zope.interface import implements
>>> from zope.interface import implementer
>>> from plone.app.blocks.interfaces import IBlocksTransformEnabled
>>> class Page(BrowserView):
... implements(IBlocksTransformEnabled)
>>> @implementer(IBlocksTransformEnabled)
... class Page(BrowserView):
... __name__ = 'test-page'
... def __call__(self):
... return pageHTML
Expand Down Expand Up @@ -176,7 +176,7 @@ Some cleanup is needed to cover lxml platform discrepancies...

.. code-block:: python
>>> print browser.contents.replace('<head><meta', '<head>\n\t<meta')
>>> print(browser.contents.replace('<head><meta', '<head>\n\t<meta'))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
Expand Down Expand Up @@ -230,7 +230,7 @@ tiles should be rendered as ESI links. See `plone.tiles`_ for more details.
.. code-block:: python
>>> browser.open(portal.absolute_url() + '/@@test-page')
>>> print browser.contents.replace('<head><meta', '<head>\n\t<meta')
>>> print(browser.contents.replace('<head><meta', '<head>\n\t<meta'))
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns:esi="http://www.edge-delivery.org/esi/1.0" xmlns="http://www.w3.org/1999/xhtml">
<head>
Expand Down Expand Up @@ -275,13 +275,13 @@ When ESI rendering takes place, the following URLs will be called:
.. code-block:: python
>>> browser.open("http://nohost/plone/@@test.tile3/tile4/@@esi-body?foo=bar")
>>> print browser.contents
>>> print(browser.contents)
<p>
ESI tile with query string foo=bar
</p>
>>> browser.open("http://nohost/plone/@@test.tile3/tile2/@@esi-body?")
>>> print browser.contents
>>> print(browser.contents)
<p>
ESI tile with query string
</p>
Expand Down

0 comments on commit 3528945

Please sign in to comment.