Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ lint:
echo 'Checking type annotations...'; \
mypy --py2 shopify_python tests/shopify_python --ignore-missing-imports; \
fi
@pycodestyle
@pycodestyle --exclude=tests/functional/two_arg_exception2.py,tests/functional/two_arg_exception3.py

autolint: autopep8 lint

Expand Down
5 changes: 3 additions & 2 deletions shopify_python/google_styleguide.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ class GoogleStyleGuideChecker(checkers.BaseChecker):
"For example: x = 1 if cond else 2. "
"Conditional Expressions okay to use for one-liners. "
"In other cases prefer to use a complete if statement. "),
'C6014': ('Prefer operator module function %(op)s to lambda function %(lambda_fun)s',
'C6014': ('Prefer operator module function %(op)s to lambda function',
'lambda-func',
"For common operations like multiplication, use the functions from the operator module"
"instead of lambda functions. For example, prefer operator.mul to lambda x, y: x * y."),
Expand Down Expand Up @@ -230,7 +230,8 @@ def __dont_use_archaic_raise_syntax(self, node): # type: (astroid.Raise) -> Non
children = list(node.get_children())
if len(children) > 1 and not isinstance(children[1], astroid.Name):
self.add_message('two-arg-exception', node=node)
elif len(children) == 1 and isinstance(children[0], six.string_types):
elif(len(children) == 1 and isinstance(children[0], astroid.Const) and
isinstance(children[0].value, six.string_types)):
Copy link
Contributor

Choose a reason for hiding this comment

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

This is a bug fix. It went unnoticed because string-exception wasn't previously tested.

self.add_message('string-exception', node=node)

def __dont_catch_standard_error(self, node): # type: (astroid.ExceptHandler) -> None
Expand Down
Empty file added tests/functional/__init__.py
Empty file.
6 changes: 6 additions & 0 deletions tests/functional/catch_standard_error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# pylint: disable=undefined-variable,missing-docstring

try:
callThisFunction()
except StandardError: # [catch-standard-error]
pass
1 change: 1 addition & 0 deletions tests/functional/catch_standard_error.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
catch-standard-error:5::Caught StandardError
38 changes: 38 additions & 0 deletions tests/functional/complex_list_comp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# pylint: disable=undefined-variable, missing-docstring


def fcn_to_fail():
result = [(x, y) for x in range(10) for y in range(5) if x * y > 10] # [complex-list-comp]
return result


def one_to_pass():
result = []
for first in range(10):
for second in range(5):
result.append((first, second))
return result


def two_to_pass():
for first in xrange(5):
for second in xrange(5):
if first != second:
for third in xrange(5):
if second != third:
yield (first, second, third)


def three_to_pass():
return ((first, complicated_transform(first))
for first in long_generator_function(parameter)
if first is not None)


def four_to_pass():
squares = [x * x for x in range(10)]
return squares


def five_to_pass():
eat(jelly_bean for jelly_bean in jelly_beans if jelly_bean.color == 'black')
1 change: 1 addition & 0 deletions tests/functional/complex_list_comp.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
complex-list-comp:5:fcn_to_fail:Multiple generators in list comprehension
11 changes: 11 additions & 0 deletions tests/functional/cond_expr.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# pylint: disable=invalid-name,used-before-assignment,missing-docstring

if xeo > 5: # [cond-expr]
xeo = 5
else:
xeo = 6

if xeo > 5:
xeo = 5
else:
beo = 6
1 change: 1 addition & 0 deletions tests/functional/cond_expr.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
cond-expr:3::Use Conditional Expressions for one-liners, for example x = 1 if cond else 2.
17 changes: 17 additions & 0 deletions tests/functional/except_too_long.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# pylint: disable=undefined-variable,invalid-name,missing-docstring

try:
letsRunThisFunction()
except Error as error: # [except-too-long]
x = "this time"
y = "next time"
for i in range(0, 50):
x += y
for i in range(0, 50):
y += x
GetToThisFunc(x, y)

try:
runThisFcnAgain()
finally:
runNextFcn()
1 change: 1 addition & 0 deletions tests/functional/except_too_long.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
except-too-long:5::Except body has 32 nodes
19 changes: 19 additions & 0 deletions tests/functional/finally_too_long.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
# pylint: disable=undefined-variable,invalid-name,missing-docstring

try: # [finally-too-long]
letsRunThisFunction()
except Error as error:
pass
finally:
x = "this time"
y = "next time"
for i in range(0, 50):
x += y
for i in range(0, 50):
y += x
GetToThisFunc(x, y)

try:
runThisFcnAgain()
finally:
runNextFcn()
1 change: 1 addition & 0 deletions tests/functional/finally_too_long.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
finally-too-long:3::Finally body has 29 nodes
30 changes: 30 additions & 0 deletions tests/functional/global_variable.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# pylint: disable=invalid-name,too-few-public-methods,missing-docstring,unpacking-non-sequence,undefined-variable

my_int = 77 # [global-variable]


class Integers(object):
one = 1
two = 2
three = 3
four = 4
five = 5


module_var, other_module_var = 10 # [global-variable, global-variable]

another_module_var = 1 # [global-variable]

__version__ = '0.0.0'

CONSTANT = 10

_OTHER_CONSTANT = sum(x)

Point = namedtuple('Point', ['x', 'y'])

_Point = namedtuple('_Point', ['x', 'y'])


class MyClass(object):
class_var = 10
4 changes: 4 additions & 0 deletions tests/functional/global_variable.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
global-variable:3::my_int declared at the module level (i.e. global)
global-variable:14::module_var declared at the module level (i.e. global)
global-variable:14::other_module_var declared at the module level (i.e. global)
global-variable:16::another_module_var declared at the module level (i.e. global)
4 changes: 4 additions & 0 deletions tests/functional/import_full_path.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# pylint: disable=no-name-in-module,unused-import,multiple-import-items,missing-docstring

from . import string # [import-full-path]
from .. import string, os # [import-full-path, import-full-path]
3 changes: 3 additions & 0 deletions tests/functional/import_full_path.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import-full-path:3::.string imported relatively
import-full-path:4::.os imported relatively
import-full-path:4::.string imported relatively
11 changes: 11 additions & 0 deletions tests/functional/import_modules_only.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# pylint: disable=import-error,unused-import,ungrouped-imports,missing-docstring

import os
import io
from os.path import join # [import-modules-only]
from io import FileIO # [import-modules-only]
from os import environ # [import-modules-only]
from nonexistent_package import nonexistent_module # [import-modules-only]
import shopify_python
from shopify_python import google_styleguide
from shopify_python import shopify_styleguide
4 changes: 4 additions & 0 deletions tests/functional/import_modules_only.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import-modules-only:5::os.path.join is not a module or cannot be imported
import-modules-only:6::io.FileIO is not a module or cannot be imported
import-modules-only:7::os.environ is not a module or cannot be imported
import-modules-only:8::nonexistent_package.nonexistent_module is not a module or cannot be imported
26 changes: 26 additions & 0 deletions tests/functional/lambda_func.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# pylint: disable=missing-docstring,deprecated-lambda
import operator as o
import functools as f

map(lambda x: - x, [1, 2, 3]) # [lambda-func]
map(o.neg, [1, 2, 3])


def foo1():
return map(lambda x: + x, [1, 2, 3]) # [lambda-func]


def foo2():
return map(o.abs, [1, 2, 3])


f.reduce(lambda x, y: x + y, [1, 2, 3, 4]) # [lambda-func]
f.reduce(o.add, [1, 2, 3, 4])


def foo3():
return f.reduce(lambda x, y: x + y, [1, 2, 3, 4]) # [lambda-func]


def foo4():
return f.reduce(o.add, [1, 2, 3, 4])
4 changes: 4 additions & 0 deletions tests/functional/lambda_func.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
lambda-func:5:<lambda>:Prefer operator module function operator.neg to lambda function
lambda-func:10:foo1.<lambda>:Prefer operator module function operator.pos to lambda function
lambda-func:17:<lambda>:Prefer operator module function operator.add to lambda function
lambda-func:22:foo3.<lambda>:Prefer operator module function operator.add to lambda function
7 changes: 7 additions & 0 deletions tests/functional/multiple_import_items.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# pylint: disable=missing-docstring,import-error,unused-import, import-modules-only

import first
from first import second
from third import Fourth, Fifth # [multiple-import-items]
from sixth import Sixth, seventh, Eighth # [multiple-import-items]
import eighth
2 changes: 2 additions & 0 deletions tests/functional/multiple_import_items.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
multiple-import-items:5::Statement imports multiple items from third
multiple-import-items:6::Statement imports multiple items from sixth
5 changes: 5 additions & 0 deletions tests/functional/string_exception.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pylint: disable=unreachable,undefined-variable,missing-docstring

raise Exception('this is the error message')
raise Exception
raise 'This is the error message' # [string-exception]
1 change: 1 addition & 0 deletions tests/functional/string_exception.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
string-exception:5::Raised deprecated string-exception
17 changes: 17 additions & 0 deletions tests/functional/try_too_long.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# pylint: disable=invalid-name,undefined-variable,missing-docstring

try:
pass
except Error as error:
pass

try: # [try-too-long]
x = 50
y = 70
for i in range(0, 50):
x = x * i
for i in range(0, 50):
y = y * x * i
LogThisValue(y / x)
except Error as error:
pass
1 change: 1 addition & 0 deletions tests/functional/try_too_long.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
try-too-long:8::Try body has 36 nodes
5 changes: 5 additions & 0 deletions tests/functional/two_arg_exception2.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pylint: disable=unreachable,undefined-variable,missing-docstring

raise Exception('this is the error message')
raise Exception
raise MyException, 'message' # [two-arg-exception]
3 changes: 3 additions & 0 deletions tests/functional/two_arg_exception2.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[testoptions]
Copy link
Contributor

@solackerman solackerman Jun 21, 2017

Choose a reason for hiding this comment

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

the two-arg-exception is a lint error in python2, and a syntax error in python 3. This file controls which python version is allowed to run the lint test.

max_pyver=3.0

1 change: 1 addition & 0 deletions tests/functional/two_arg_exception2.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
two-arg-exception:5::Raised two-argument exception
5 changes: 5 additions & 0 deletions tests/functional/two_arg_exception3.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
# pylint: disable=unreachable,undefined-variable,missing-docstring

raise Exception('this is the error message')
raise Exception
raise MyException, 'message' # [syntax-error]
3 changes: 3 additions & 0 deletions tests/functional/two_arg_exception3.rc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[testoptions]
min_pyver=3.0

1 change: 1 addition & 0 deletions tests/functional/two_arg_exception3.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
syntax-error:5::invalid syntax (<string>, line 5)
4 changes: 4 additions & 0 deletions tests/functional/use_simple_lambdas.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# pylint: disable=missing-docstring,pointless-statement

lambda x, y: x if x % 2 == 0 else y
lambda x, y: (x * 2 * 3 + 4) if x % 2 == 0 else (y * 2 * 3 + 4) # [use-simple-lambdas]
1 change: 1 addition & 0 deletions tests/functional/use_simple_lambdas.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
use-simple-lambdas:4:<lambda>:Lambda has 24 nodes
2 changes: 2 additions & 0 deletions tests/shopify_python/__init__.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
from shopify_python import google_styleguide
from shopify_python import shopify_styleguide
13 changes: 10 additions & 3 deletions tests/shopify_python/test_google_styleguide.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,13 +95,20 @@ class MyClass(object):
def test_using_archaic_raise_fails(self):
root = astroid.builder.parse("""
raise MyException, 'Error message'
raise 'Error message'
""")
node = root.body[0]
message = pylint.testutils.Message('two-arg-exception', node=node)
with self.assertAddsMessages(message):
self.walk(root)

root = astroid.builder.parse("""
raise 'Error message'
""")
node = root.body[0]
message = pylint.testutils.Message('string-exception', node=node)
with self.assertAddsMessages(message):
self.walk(root)
Copy link
Contributor

Choose a reason for hiding this comment

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

unit testing string-exception here.


@pytest.mark.skipif(sys.version_info < (3, 0), reason="Tests code that is Python 2 incompatible")
def test_using_reraise_passes(self):
root = astroid.builder.parse("""
Expand Down Expand Up @@ -251,7 +258,7 @@ def unaryfnc():
unary_message = pylint.testutils.Message('lambda-func', node=ulam_fail, args={
'op': 'operator.{}'.format(op_name),
'lambda_fun': 'lambda x: {}'.format(expression)
})
})
with self.assertAddsMessages(unary_message):
self.walk(unary_root)

Expand Down Expand Up @@ -280,7 +287,7 @@ def binaryfnc():
binary_message = pylint.testutils.Message('lambda-func', node=binary_fail.body, args={
'op': 'operator.{}'.format(op_name),
'lambda_fun': 'lambda x, y: {}'.format(expression)
})
})
with self.assertAddsMessages(binary_message):
self.walk(binary_root)

Expand Down
Loading