Skip to content
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

Python 3.5 fixes #38

Merged
merged 5 commits into from
Mar 15, 2016
Merged

Python 3.5 fixes #38

merged 5 commits into from
Mar 15, 2016

Conversation

clintonb
Copy link
Contributor

ECOM-3765

@clintonb
Copy link
Contributor Author

@nedbat @cpennington please review

@@ -51,8 +51,8 @@
},

install_requires=[
'pylint==1.4.5',
'pylint-django==0.6.1',
'pylint>=1.5.4,<2.0.0',
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do not unpin pylint. It will cause a world of hurt in edx-platform.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need 1.5.x for Python 3.5. Hmm...how about I change this to 'pylint>=1.4.5,<2.0.0', and add pylint==1.4.5 to edx-platform? That allows for edx-platform to remain stable, and other users to get the latest compatible version. We also don't have to touch this package again just to update Pylint.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When I saw this pull request, I thought, "wait, didn't we do 3.5 already? Oh yeah, there was something that made it difficult." This is the thing. We could pin the version of pylint in edx-platform, but there's a larger problem: it's natural for pylint to add new checkers in new versions. This means that when pylint upgrades, there will likely be more violations found. Builds that depend on not exceeding some threshold of violations will then break. We don't want pin-ranges to mean that we could silently upgrade something that will break our builds. I'm not sure what to do about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pinning pylint here makes this library fragile. I'd rather consuming applications, especially edx-platform, pin pylint instead.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure how pinning makes it fragile? Part of the original goal of edx-lint was to ensure that all of our repos were linted the same. It does that mostly by using a common pylintrc, but a pinned pylint version can also help. So far, there doesn't seem to be a problem that is solved by unpinning pylint, so can we leave it pinned?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can pin to 1.5.4.

@nedbat
Copy link
Contributor

nedbat commented Mar 11, 2016

The tests don't pass for me locally on Python 3.5:

py35 create: /src/edx/src/edx-lint/.tox/py35
py35 installdeps: coverage
py35 inst: /src/edx/src/edx-lint/.tox/dist/edx-lint-0.5.0.zip
py35 installed: You are using pip version 7.1.2, however version 8.1.0 is available.,You should consider upgrading via the 'pip install --upgrade pip' command.,-f file:///Users/ned/Downloads/local_pypi,astroid==1.4.4,colorama==0.3.7,coverage==4.0.3,edx-lint==0.5.0,lazy-object-proxy==1.2.1,pylint==1.5.4,pylint-celery==0.3,pylint-django==0.7.1,pylint-plugin-utils==0.2.3,six==1.10.0,wheel==0.24.0,wrapt==1.10.6
py35 runtests: PYTHONHASHSEED='1755846706'
py35 runtests: commands[0] | coverage run -p -m unittest discover -b
Warning: option required-attributes is obsolete and it is slated for removal in Pylint 1.6.
.........EEEEEE
======================================================================
ERROR: test_appending_is_detected (test.test_tamper_evident.TamperEvidentFileTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 77, in test_appending_is_detected
    filename = self.write_tamper_evident(b"Am I OK?")
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 40, in write_tamper_evident
    TamperEvidentFile(filename).write(text, **kwargs)
  File "/src/edx/src/edx-lint/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith("\n"):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

======================================================================
ERROR: test_editing_is_detected (test.test_tamper_evident.TamperEvidentFileTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 86, in test_editing_is_detected
    filename = self.write_tamper_evident(b"Line 1\nLine 2\nLine 3\n")
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 40, in write_tamper_evident
    TamperEvidentFile(filename).write(text, **kwargs)
  File "/src/edx/src/edx-lint/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith("\n"):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

======================================================================
ERROR: test_hashline_formatting (test.test_tamper_evident.TamperEvidentFileTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 63, in test_hashline_formatting
    filename1 = self.write_tamper_evident(b"Hello!", hashline=b"XXX {} YYY")
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 40, in write_tamper_evident
    TamperEvidentFile(filename).write(text, **kwargs)
  File "/src/edx/src/edx-lint/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith("\n"):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

======================================================================
ERROR: test_oneline_file_is_detected (test.test_tamper_evident.TamperEvidentFileTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 96, in test_oneline_file_is_detected
    filename = self.write_tamper_evident(b"Am I OK?")
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 40, in write_tamper_evident
    TamperEvidentFile(filename).write(text, **kwargs)
  File "/src/edx/src/edx-lint/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith("\n"):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

======================================================================
ERROR: test_validating_a_good_file (test.test_tamper_evident.TamperEvidentFileTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 72, in test_validating_a_good_file
    filename = self.write_tamper_evident(b"Am I OK?")
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 40, in write_tamper_evident
    TamperEvidentFile(filename).write(text, **kwargs)
  File "/src/edx/src/edx-lint/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith("\n"):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

======================================================================
ERROR: test_writing (test.test_tamper_evident.TamperEvidentFileTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 46, in test_writing
    filename1 = self.write_tamper_evident(b"Hello!")
  File "/src/edx/src/edx-lint/test/test_tamper_evident.py", line 40, in write_tamper_evident
    TamperEvidentFile(filename).write(text, **kwargs)
  File "/src/edx/src/edx-lint/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith("\n"):
TypeError: endswith first arg must be bytes or a tuple of bytes, not str

----------------------------------------------------------------------
Ran 15 tests in 1.131s

FAILED (errors=6)
ERROR: InvocationError: '/src/edx/src/edx-lint/.tox/py35/bin/coverage run -p -m unittest discover -b'

I think the Travis builds are only running pylint?

@nedbat
Copy link
Contributor

nedbat commented Mar 11, 2016

Locally, master passes on 2.7 and 3.5, and I am running with pylint 1.4.5. What problems were you seeing?

@clintonb
Copy link
Contributor Author

Weird. This worked last night on my personal machine (3.5.?), and still works on Travis (3.5.0). It fails on my edX machine with Python 3.5.0.

- python: "2.7"
env: TOXARG="-e pylint"
env:
- TOXARG="-e pylint"
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This line made it so that Travis doesn't run tests, it only runs pylint.

@clintonb
Copy link
Contributor Author

Backstory: I'm working on a new library, edx-drf-extensions, that needs to support Python 2.7 and 3.5. When I use edx-lint==0.4.3, I get the following errors:

pylint --rcfile=pylintrc edx_rest_framework_extensions
Traceback (most recent call last):
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/pylint/lint.py", line 910, in get_ast
    return MANAGER.ast_from_file(filepath, modname, source=True)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/manager.py", line 112, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/builder.py", line 134, in file_build
    module = self._data_build(data, modname, path)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/builder.py", line 177, in _data_build
    module = rebuilder.visit_module(node, modname, node_file, package)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 148, in visit_module
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 148, in <listcomp>
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 238, in visit_assign
    newnode.value = self.visit(node.value, newnode)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 331, in visit_callfunc
    if node.starargs is not None:
AttributeError: 'Call' object has no attribute 'starargs'
************* Module edx_rest_framework_extensions.authentication
F:  1, 0: <class 'AttributeError'>: 'Call' object has no attribute 'starargs' (astroid-error)
Traceback (most recent call last):
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/pylint/lint.py", line 910, in get_ast
    return MANAGER.ast_from_file(filepath, modname, source=True)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/manager.py", line 112, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/builder.py", line 134, in file_build
    module = self._data_build(data, modname, path)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/builder.py", line 177, in _data_build
    module = rebuilder.visit_module(node, modname, node_file, package)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 148, in visit_module
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 148, in <listcomp>
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 915, in visit_class
    newnode = super(TreeRebuilder3k, self).visit_class(node, parent)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 345, in visit_class
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 345, in <listcomp>
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 238, in visit_assign
    newnode.value = self.visit(node.value, newnode)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 331, in visit_callfunc
    if node.starargs is not None:
AttributeError: 'Call' object has no attribute 'starargs'
************* Module edx_rest_framework_extensions.tests.factories
F:  1, 0: <class 'AttributeError'>: 'Call' object has no attribute 'starargs' (astroid-error)
Traceback (most recent call last):
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/pylint/lint.py", line 910, in get_ast
    return MANAGER.ast_from_file(filepath, modname, source=True)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/manager.py", line 112, in ast_from_file
    return AstroidBuilder(self).file_build(filepath, modname)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/builder.py", line 134, in file_build
    module = self._data_build(data, modname, path)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/builder.py", line 177, in _data_build
    module = rebuilder.visit_module(node, modname, node_file, package)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 148, in visit_module
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 148, in <listcomp>
    newnode.body = [self.visit(child, newnode) for child in node.body]
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 238, in visit_assign
    newnode.value = self.visit(node.value, newnode)
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 161, in visit
    return self._transform(visit_method(node, parent))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/astroid/rebuilder.py", line 331, in visit_callfunc
    if node.starargs is not None:
AttributeError: 'Call' object has no attribute 'starargs'
************* Module edx_rest_framework_extensions.tests.test_authentication
F:  1, 0: <class 'AttributeError'>: 'Call' object has no attribute 'starargs' (astroid-error)
make: *** [quality] Error 1

I have no issues when I manually update Pylint from 1.4.5 to 1.5.4. That's the actual issue I need to resolve here.

I'm not sure what happened last night with the bytes vs. string issue, prompting me to update that code; but, it is no longer an issue. I am reverting those changes now.

@clintonb
Copy link
Contributor Author

I've found the disconnect. The tests certainly work; however, in practice edx_lint write pylintrc fails with the following error:

(edx-drf-extensions)Clinton Blackburn's MacBook Pro:edx-drf-extensions cblackburn$ edx_lint write pylintrc
Checking existing copy of pylintrc
Reading edx_lint/files/pylintrc
Applying local tweaks from pylintrc_tweaks
Writing pylintrc
Traceback (most recent call last):
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/bin/edx_lint", line 9, in <module>
    load_entry_point('edx-lint==0.5.0', 'console_scripts', 'edx_lint')()
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/edx_lint/cmd/main.py", line 23, in main
    return write_main(argv[1:])
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/edx_lint/cmd/write.py", line 126, in write_main
    out_tef.write(str(output_text.getvalue()))
  File "/Users/cblackburn/.virtualenvs/edx-drf-extensions/lib/python3.5/site-packages/edx_lint/tamper_evident.py", line 37, in write
    if not text.endswith(b"\n"):
TypeError: endswith first arg must be str or a tuple of str, not bytes

@clintonb clintonb force-pushed the clintonb/python-3.5 branch 2 times, most recently from 78d4f01 to b66f228 Compare March 11, 2016 18:53
@@ -34,6 +34,10 @@ def write(self, text, hashline=b"# {}"):
to the file, with "{}" replaced with the hash.

"""
# Ensure we are working with bytes.
if isinstance(text, str):
text = str.encode(text)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This seems wrong for py2, where we expect a "str", and the .encode will do the wrong thing for non-ascii. The argument is documented as a bytestring, so why do we need these lines?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The argument being passed when running the command is of type str: https://github.com/edx/edx-lint/blob/master/edx_lint/cmd/write.py#L123. Perhaps a better solution is to update this method to accept str instead of bytes?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or remove the str from that line in write.py

@clintonb clintonb force-pushed the clintonb/python-3.5 branch 4 times, most recently from 22f3821 to 0e0d183 Compare March 11, 2016 20:29
"""
return main.main(argv)

@unittest.skip('Default test runners have issues finding the file.')
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Note that I've added a test that is broken for everything but PyCharm. Still trying to figure out why.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

#39 filed to address this issue in the future.

@clintonb
Copy link
Contributor Author

@nedbat let me know if you have additional feedback, or if we are good to merge.

@clintonb
Copy link
Contributor Author

@nedbat are we good to merge?

@nedbat
Copy link
Contributor

nedbat commented Mar 15, 2016

I have a feeling of dread about this, but I don't have a better solution, so 👍

@clintonb
Copy link
Contributor Author

🙊

clintonb added a commit that referenced this pull request Mar 15, 2016
@clintonb clintonb merged commit 7ada9bd into master Mar 15, 2016
@clintonb clintonb deleted the clintonb/python-3.5 branch March 15, 2016 15:39
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants