-
-
Notifications
You must be signed in to change notification settings - Fork 79
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[WIP] Python 3 support #542
Conversation
@pbauer wohoo! Are you sprinting remotely? Wanna do a video call connection? That worked quite well with Asko at the last sprint. :) |
Not really, I simply tried to get it running. The main issue for now is that plone.restapi tests have a hard dependency on Archetypes 😭. You should get rid of that. Then I will continue porting it to python 3. |
@pbauer right. This dependency should be purely optional though. cc @lukasgraf @buchi |
@pbauer in what way is the AT dependency causing issues for you? But that would probably not solve your issue either I would assume. So is the only option to remove the AT dependency entirely, and have the AT parts completely untested (via CI)? |
@lukasgraf that would be good. Then we need to make all code, tests and test-layers that use archetypes optional depending on if AT can be imported or not. |
@pbauer I see - so it's mostly about the imports in the test code failing if AT isn't available, not so much about the actual package dependency in the
|
I did a similar approach for plone.app.iterate: plone/plone.app.iterate#61 |
I was a little annoyed by the merge of plone.restapi ruining the python3 build. The problem was not only the tests, there also are hard imports from Products.Archetypes in restapi itself (e.g. in services/content/add.py) and several places where the code seems to bew ritten wit AT as default content in mind. This PR is by no menas done but I have to focus on other tasks for now so please either continue working on this or start the separation and porting to python 3 fresh. |
By the way, tests of |
That is definitely unintended and we need to fix this. Thanks for your efforts! |
I think we should separate the Python 3 migration from getting rid of the AT dependency. Let's do the latter first and the look into Python 3 as Philip wrote. |
tests are failing and branch needs a rebase, but this seems to be almost ready now: $ pylint --py3k --disable=no-absolute-import src/plone/restapi/
No config file found, using default configuration
--------------------------------------------------------------------
Your code has been rated at 10.00/10 (previous run: 10.00/10, +0.00) |
from zope.interface import Interface | ||
from zope.interface import implementer | ||
|
||
from .mixins import OrderingMixin |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be an absolute import instead.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
+1
if pre_errors is not None: | ||
for field_name, error_message in pre_errors.items(): | ||
if field_name in errors: | ||
errors[field_name] += " %s" % error_message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use single quotes and .format()
instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If we don't enforce such a style decision we shouldn't require people to stick with it IMHO.
if post_errors is not None: | ||
for field_name, error_message in post_errors.items(): | ||
if field_name in errors: | ||
errors[field_name] += " %s" % error_message |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use single quotes and .format()
instead?
if version == 'current': | ||
return self.context | ||
else: | ||
repo_tool = getToolByName(self.context, "portal_repository") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
we should use single quotes here.
from zope.interface import implementer | ||
|
||
try: | ||
from Products.CMFPlone.factory import _IMREALLYPLONE5 # noqa |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this # noqa
needs to be more specific.
@@ -79,8 +79,8 @@ def traverse(self, path='/plone', accept='application/json', method='GET'): | |||
request.environ['PATH_TRANSLATED'] = path | |||
request.environ['HTTP_ACCEPT'] = accept | |||
request.environ['REQUEST_METHOD'] = method | |||
request._auth = 'Basic %s' % b64encode( | |||
'%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) | |||
auth = '%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use .format()
instead?
request._auth = 'Basic %s' % b64encode( | ||
'%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) | ||
auth = '%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) | ||
request._auth = 'Basic %s' % b64encode(auth.encode('utf8')).decode('utf8') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use .format()
instead?
@@ -34,8 +34,8 @@ def traverse(self, path='/plone', accept='application/json', method='GET'): | |||
request.environ['PATH_TRANSLATED'] = path | |||
request.environ['HTTP_ACCEPT'] = accept | |||
request.environ['REQUEST_METHOD'] = method | |||
request._auth = 'Basic %s' % b64encode( | |||
'%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) | |||
auth = '%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use .format()
instead?
request._auth = 'Basic %s' % b64encode( | ||
'%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) | ||
auth = '%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) | ||
request._auth = 'Basic %s' % b64encode(auth.encode('utf8')).decode('utf8') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use .format()
instead?
@@ -39,7 +43,7 @@ def test_batched(self): | |||
obj = self.serialize(registry) | |||
expected = ['@id', 'items_total', 'items', 'batching'] | |||
self.assertEqual(set(expected), set(obj.keys())) | |||
self.assertEqual(obj['items_total'], len(range(1, 100))) | |||
self.assertEqual(obj['items_total'], len(list(range(1, 100)))) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be written: self.assertEqual(obj['items_total'], 99)
@@ -98,8 +98,8 @@ def traverse(self, path='/plone', accept='application/json', | |||
request.environ['PATH_TRANSLATED'] = path | |||
request.environ['HTTP_ACCEPT'] = accept | |||
request.environ['REQUEST_METHOD'] = method | |||
request._auth = 'Basic %s' % b64encode( | |||
'%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) | |||
auth = '%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use .format()
instead?
request._auth = 'Basic %s' % b64encode( | ||
'%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD)) | ||
auth = '%s:%s' % (SITE_OWNER_NAME, SITE_OWNER_PASSWORD) | ||
request._auth = 'Basic %s' % b64encode(auth.encode('utf8')).decode('utf8') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
shouldn't we use .format()
instead?
src/plone/restapi/batching.py
Outdated
@@ -116,7 +116,7 @@ def _url_with_params(self, params): | |||
# result of parse_qsl into a dict! | |||
|
|||
# Drop params to be updated, then prepend new params in order | |||
qs_params = filter(lambda x: x[0] not in params.keys(), qs_params) | |||
qs_params = [x for x in qs_params if x[0] not in list(params.keys())] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
this should be written: qs_params = [x for x in qs_params if x[0] not in list(params)]
Folks, this is still a work in progress. If you want to help with that work, feel free, but otherwise please wait with the comments until it's marked ready for review. |
Ack - I'm out 👍 |
At this point the todo list before it's ready for review is:
I put my name next to the one I'm working on; if someone else wants to work on one of the other items edit this comment and add your name to claim it. |
@lukasgraf yeah. That sounds like a good idea. I still don't understand how those changes ended up in this branch in the first place. Maybe somebody accidentally committed the doc changes... |
@davisagli yeah. That's correct. I will merge my branch into this one then to get it green... |
Oh. Seems somebody already merged my fix. :) |
I know @davisagli does not like this but I did a quick first review of this PR. Now I am not that afraid of having to do the review to be honest, which is good. Apart from the standard py3 stuff that I see I am wondering if there isn't a better way to make the AT dependency optional. So far what we do is to include AT-specific code via zcml conditionals. Since David also excluded those code fragments via if/else I suppose that is not sufficient when running things on Python 3. @lukasgraf @buchi since you folks wrote the AT code, what is your opinion? Does the current way of excluding the AT-specific code via import + if/else makes sense to you? Would it be an alternative to factor out the AT-specific code into some kind of subpackage within plone.restapi? Or would it be an option to make a plone.restapi release without AT for Plone 5.2? @pbauer we plan to drop AT support for Python 3, correct? Question is: is it worth the effort to support AT on Plone 5.2 / Python 2.7. |
@tisto AT is going to be deprecated in Plone 6, not before; I see no reason to make it Python 3 compatible, but it must work on Plone 5.2 with Python 2.7. |
@hvelarde we are talking about exposing AT via plone.restapi. Whatever we do with plone.restapi, it goes far beyond anything we ever promised or imagined. |
I've cleaned out as many HAS_AT checks as I could. |
AT is deprecated with Plone 5.2. It will continue to work on Python 2 with Plone 5.2 but I do not think it will still work with 6.0 unless someone else takes care of this. I would have liked to spare us the effort of supporting AT in 5.2 but then we'd have had to deprecate it in 5.1 already. |
No description provided.