You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by dh...@apache.org on 2016/06/27 19:30:19 UTC
[1/2] incubator-beam git commit: Closes #538
Repository: incubator-beam
Updated Branches:
refs/heads/python-sdk 21c819f81 -> 3464a909b
Closes #538
Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/3464a909
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/3464a909
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/3464a909
Branch: refs/heads/python-sdk
Commit: 3464a909befafb74146bfc49492b267b1da25234
Parents: 21c819f f71c1dd
Author: Dan Halperin <dh...@google.com>
Authored: Mon Jun 27 12:30:02 2016 -0700
Committer: Dan Halperin <dh...@google.com>
Committed: Mon Jun 27 12:30:02 2016 -0700
----------------------------------------------------------------------
sdks/python/.pylintrc | 174 +++++++++++++++++++
sdks/python/apache_beam/coders/coders.py | 2 +-
sdks/python/apache_beam/coders/stream_test.py | 2 +-
.../apache_beam/examples/streaming_wordcount.py | 2 +-
sdks/python/apache_beam/examples/wordcount.py | 4 +-
.../apache_beam/examples/wordcount_debugging.py | 6 +-
sdks/python/apache_beam/io/bigquery.py | 2 +-
.../apache_beam/transforms/combiners_test.py | 7 +-
sdks/python/apache_beam/transforms/core.py | 17 +-
.../apache_beam/transforms/ptransform_test.py | 43 +++--
.../apache_beam/transforms/trigger_test.py | 25 +--
.../apache_beam/typehints/trivial_inference.py | 3 +-
sdks/python/apache_beam/typehints/typehints.py | 5 +-
sdks/python/run_pylint.sh | 48 +++++
sdks/python/tox.ini | 2 +
15 files changed, 292 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
[2/2] incubator-beam git commit: Pylint integration for Python SDK
Posted by dh...@apache.org.
Pylint integration for Python SDK
Runs pylint on modified files under sdks/python/**/*.py.
Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/f71c1ddd
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/f71c1ddd
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/f71c1ddd
Branch: refs/heads/python-sdk
Commit: f71c1dddb10d4a8b0f8c8ed8722e6662781d19f9
Parents: 21c819f
Author: Ahmet Altay <al...@google.com>
Authored: Fri Jun 24 14:04:27 2016 -0700
Committer: Dan Halperin <dh...@google.com>
Committed: Mon Jun 27 12:30:02 2016 -0700
----------------------------------------------------------------------
sdks/python/.pylintrc | 174 +++++++++++++++++++
sdks/python/apache_beam/coders/coders.py | 2 +-
sdks/python/apache_beam/coders/stream_test.py | 2 +-
.../apache_beam/examples/streaming_wordcount.py | 2 +-
sdks/python/apache_beam/examples/wordcount.py | 4 +-
.../apache_beam/examples/wordcount_debugging.py | 6 +-
sdks/python/apache_beam/io/bigquery.py | 2 +-
.../apache_beam/transforms/combiners_test.py | 7 +-
sdks/python/apache_beam/transforms/core.py | 17 +-
.../apache_beam/transforms/ptransform_test.py | 43 +++--
.../apache_beam/transforms/trigger_test.py | 25 +--
.../apache_beam/typehints/trivial_inference.py | 3 +-
sdks/python/apache_beam/typehints/typehints.py | 5 +-
sdks/python/run_pylint.sh | 48 +++++
sdks/python/tox.ini | 2 +
15 files changed, 292 insertions(+), 50 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/.pylintrc
----------------------------------------------------------------------
diff --git a/sdks/python/.pylintrc b/sdks/python/.pylintrc
new file mode 100644
index 0000000..edf13ee
--- /dev/null
+++ b/sdks/python/.pylintrc
@@ -0,0 +1,174 @@
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+[MASTER]
+# Ignore auto-generated files.
+ignore=clients,windmill_pb2.py,windmill_service_pb2.py
+
+[BASIC]
+# Regular expression which should only match the name
+# of functions or classes which do not require a docstring.
+no-docstring-rgx=(__.*__|main)
+
+# Min length in lines of a function that requires a docstring.
+docstring-min-length=10
+
+# Regular expression which should only match correct module names. The
+# leading underscore is sanctioned for private modules by Google's style
+# guide.
+#
+# There are exceptions to the basic rule (_?[a-z][a-z0-9_]*) to cover
+# requirements of Python's module system and of the presubmit framework.
+module-rgx=^(_?[a-z][a-z0-9_]*)|__init__|PRESUBMIT|PRESUBMIT_unittest$
+
+# Regular expression which should only match correct module level names
+const-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Regular expression which should only match correct class attribute
+class-attribute-rgx=^(_?[A-Z][A-Z0-9_]*|__[a-z0-9_]+__|_?[a-z][a-z0-9_]*)$
+
+# Regular expression which should only match correct class names
+class-rgx=^_?[A-Z][a-zA-Z0-9]*$
+
+# Regular expression which should only match correct function names.
+# 'camel_case' and 'snake_case' group names are used for consistency of naming
+# styles across functions and methods.
+function-rgx=^(?:(?P<camel_case>_?[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_?[a-z][a-z0-9_]*))$
+
+# Regular expression which should only match correct method names.
+# 'camel_case' and 'snake_case' group names are used for consistency of naming
+# styles across functions and methods. 'exempt' indicates a name which is
+# consistent with all naming styles.
+method-rgx=^(?:(?P<exempt>__[a-z0-9_]+__|next)|(?P<camel_case>_{0,2}[A-Z][a-zA-Z0-9]*)|(?P<snake_case>_{0,2}[a-z][a-z0-9_]*))$
+
+# Regular expression which should only match correct instance attribute names
+attr-rgx=^_{0,2}[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct argument names
+argument-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct variable names
+variable-rgx=^[a-z][a-z0-9_]*$
+
+# Regular expression which should only match correct list comprehension /
+# generator expression variable names
+inlinevar-rgx=^[a-z][a-z0-9_]*$
+
+# List of builtins function names that should not be used, separated by a comma
+bad-functions=input,apply,reduce
+
+# Good variable names which should always be accepted, separated by a comma
+good-names=main,_
+
+# Bad variable names which should always be refused, separated by a comma
+bad-names=
+
+[MESSAGES CONTROL]
+disable =
+ abstract-method,
+ arguments-differ,
+ attribute-defined-outside-init,
+ bad-builtin,
+ bad-option-value,
+ bad-super-call,
+ broad-except,
+ consider-using-enumerate,
+ cyclic-import,
+ design,
+ expression-not-assigned,
+ fixme,
+ function-redefined,
+ global-statement,
+ import-error,
+ import-self,
+ invalid-name,
+ locally-disabled,
+ locally-enabled,
+ misplaced-bare-raise,
+ missing-docstring,
+ multiple-statements,
+ no-member,
+ no-name-in-module,
+ no-self-argument,
+ no-self-use,
+ no-value-for-parameter,
+ not-callable,
+ pointless-statement,
+ protected-access,
+ raising-non-exception,
+ redefined-builtin,
+ redefined-outer-name,
+ redefined-variable-type,
+ redundant-keyword-arg,
+ reimported,
+ relative-import,
+ similarities,
+ simplifiable-if-statement,
+ super-init-not-called,
+ undefined-variable,
+ unexpected-keyword-arg,
+ ungrouped-imports,
+ unidiomatic-typecheck,
+ unnecessary-lambda,
+ unneeded-not,
+ unused-argument,
+ unused-import,
+ unused-variable,
+ unused-wildcard-import,
+ used-before-assignment,
+ wildcard-import,
+ wrong-import-order,
+ wrong-import-position,
+
+
+[REPORTS]
+# Tells whether to display a full report or only the messages
+reports=no
+
+[CLASSES]
+# List of method names used to declare (i.e. assign) instance attributes.
+defining-attr-methods=__init__,__new__,setUp
+
+# "class_" is also a valid for the first argument to a class method.
+valid-classmethod-first-arg=cls,class_
+
+[FORMAT]
+# Maximum number of characters on a single line.
+max-line-length=80
+
+# Maximum number of lines in a module
+max-module-lines=99999
+
+# String used as indentation unit. (2 spaces.)
+indent-string=' '
+
+# Number of spaces of indent required.
+indent-after-paren=4
+
+# Regexp for a line that is allowed to be longer than the limit.
+# Long import lines or URLs in comments or pydocs.
+ignore-long-lines=(?x)
+ (^\s*(import|from)\s
+ |^\s*(\#\ )?<?(https?|ftp):\/\/[^\s\/$.?#].[^\s]*>?$
+ )
+
+[VARIABLES]
+# Tells whether we should check for unused import in __init__ files.
+init-import=no
+
+# A regular expression matching names used for dummy variables (i.e. not used).
+dummy-variables-rgx=^\*{0,2}(_$|unused_|dummy_|args|kwargs)
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/coders/coders.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/coders/coders.py b/sdks/python/apache_beam/coders/coders.py
index 24a1f3e..6d5b10a 100644
--- a/sdks/python/apache_beam/coders/coders.py
+++ b/sdks/python/apache_beam/coders/coders.py
@@ -152,7 +152,7 @@ class Coder(object):
def __eq__(self, other):
# pylint: disable=protected-access
return (self.__class__ == other.__class__
- and self._dict_without_impl() == other._dict_without_impl())
+ and self._dict_without_impl() == other._dict_without_impl())
# pylint: enable=protected-access
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/coders/stream_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/coders/stream_test.py b/sdks/python/apache_beam/coders/stream_test.py
index 463ccf7..f2163ca 100644
--- a/sdks/python/apache_beam/coders/stream_test.py
+++ b/sdks/python/apache_beam/coders/stream_test.py
@@ -83,7 +83,7 @@ class StreamTest(unittest.TestCase):
base = -1.7
self.run_read_write_var_int64(
[int(base**pow)
- for pow in range(1, int(63 * math.log(2) / math.log(-base)))])
+ for pow in range(1, int(63 * math.log(2) / math.log(-base)))])
def test_large_var_int64(self):
self.run_read_write_var_int64([0, 2**63 - 1, -2**63, 2**63 - 3])
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/examples/streaming_wordcount.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/examples/streaming_wordcount.py b/sdks/python/apache_beam/examples/streaming_wordcount.py
index 685e742..eda74dd 100644
--- a/sdks/python/apache_beam/examples/streaming_wordcount.py
+++ b/sdks/python/apache_beam/examples/streaming_wordcount.py
@@ -53,7 +53,7 @@ def run(argv=None):
# Capitalize the characters in each line.
transformed = (lines
| (beam.FlatMap('split',
- lambda x: re.findall(r'[A-Za-z\']+', x))
+ lambda x: re.findall(r'[A-Za-z\']+', x))
.with_output_types(unicode))
| beam.Map('pair_with_one', lambda x: (x, 1))
| beam.WindowInto(window.FixedWindows(15, 0))
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/examples/wordcount.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/examples/wordcount.py b/sdks/python/apache_beam/examples/wordcount.py
index b369294..fc02e91 100644
--- a/sdks/python/apache_beam/examples/wordcount.py
+++ b/sdks/python/apache_beam/examples/wordcount.py
@@ -28,8 +28,8 @@ import apache_beam as beam
empty_line_aggregator = beam.Aggregator('emptyLines')
average_word_size_aggregator = beam.Aggregator('averageWordLength',
- beam.combiners.MeanCombineFn(),
- float)
+ beam.combiners.MeanCombineFn(),
+ float)
class WordExtractingDoFn(beam.DoFn):
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/examples/wordcount_debugging.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/examples/wordcount_debugging.py b/sdks/python/apache_beam/examples/wordcount_debugging.py
index c06ab04..c989b6a 100644
--- a/sdks/python/apache_beam/examples/wordcount_debugging.py
+++ b/sdks/python/apache_beam/examples/wordcount_debugging.py
@@ -122,7 +122,8 @@ def run(argv=None):
# each word and filter by a list of words.
filtered_words = (
p | beam.io.Read('read', beam.io.TextFileSource(known_args.input))
- | CountWords() | beam.ParDo('FilterText', FilterTextFn('Flourish|stomach')))
+ | CountWords()
+ | beam.ParDo('FilterText', FilterTextFn('Flourish|stomach')))
# assert_that is a convenient PTransform that checks a PCollection has an
# expected value. Asserts are best used in unit tests with small data sets but
@@ -132,7 +133,8 @@ def run(argv=None):
# of the Pipeline implies that the expectations were met. Learn more at
# https://cloud.google.com/dataflow/pipelines/testing-your-pipeline on how to
# test your pipeline.
- beam.assert_that(filtered_words, beam.equal_to([('Flourish', 3), ('stomach', 1)]))
+ beam.assert_that(
+ filtered_words, beam.equal_to([('Flourish', 3), ('stomach', 1)]))
# Format the counts into a PCollection of strings and write the output using a
# "Write" transform that has side effects.
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/io/bigquery.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/io/bigquery.py b/sdks/python/apache_beam/io/bigquery.py
index 030f821..9d33134 100644
--- a/sdks/python/apache_beam/io/bigquery.py
+++ b/sdks/python/apache_beam/io/bigquery.py
@@ -46,7 +46,7 @@ of the side table. The execution framework may use some caching techniques to
share the side inputs between calls in order to avoid excessive reading::
main_table = pipeline | beam.io.Read(beam.io.BigQuerySource('very_big_table')
- side_table = pipeline | beam.io.Read(beam.io.BigQuerySource('not_so_big_table')
+ side_table = pipeline | beam.io.Read(beam.io.BigQuerySource('not_big_table')
results = (
main_table
| beam.Map('process data',
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/transforms/combiners_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/transforms/combiners_test.py b/sdks/python/apache_beam/transforms/combiners_test.py
index b753a17..112c591 100644
--- a/sdks/python/apache_beam/transforms/combiners_test.py
+++ b/sdks/python/apache_beam/transforms/combiners_test.py
@@ -109,7 +109,8 @@ class CombineTest(unittest.TestCase):
pcoll = pipeline | Create(
'start-perkey', [('a', x) for x in [6, 3, 1, 1, 9, 1, 5, 2, 0, 6]])
result_ktop = pcoll | beam.CombinePerKey('top-perkey', combiners.Largest(5))
- result_kbot = pcoll | beam.CombinePerKey('bot-perkey', combiners.Smallest(4))
+ result_kbot = pcoll | beam.CombinePerKey(
+ 'bot-perkey', combiners.Smallest(4))
assert_that(result_ktop, equal_to([('a', [9, 6, 6, 5, 3])]), label='k:top')
assert_that(result_kbot, equal_to([('a', [0, 1, 1, 1])]), label='k:bot')
pipeline.run()
@@ -158,8 +159,8 @@ class CombineTest(unittest.TestCase):
p
| Create([('a', 100, 0.0), ('b', 10, -1), ('c', 1, 100)])
| beam.CombineGlobally(combine.TupleCombineFn(max,
- combine.MeanCombineFn(),
- sum)).without_defaults())
+ combine.MeanCombineFn(),
+ sum)).without_defaults())
assert_that(result, equal_to([('c', 111.0 / 3, 99.0)]))
p.run()
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/transforms/core.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/transforms/core.py b/sdks/python/apache_beam/transforms/core.py
index 3a0eb30..445367f 100644
--- a/sdks/python/apache_beam/transforms/core.py
+++ b/sdks/python/apache_beam/transforms/core.py
@@ -437,7 +437,7 @@ class CallableWrapperCombineFn(CombineFn):
'All functions for a Combine PTransform must accept a '
'single argument compatible with: Iterable[Any]. '
'Instead a function with input type: %s was received.'
- % input_args[0])
+ % input_args[0])
input_args = (element_type(input_args[0]),) + input_args[1:]
# TODO(robertwb): Assert output type is consistent with input type?
hints = fn_hints.copy()
@@ -813,10 +813,12 @@ class CombineGlobally(PTransform):
return transform
combined = (pcoll
- | add_input_types(Map('KeyWithVoid', lambda v: (None, v))
- .with_output_types(KV[None, pcoll.element_type]))
- | CombinePerKey('CombinePerKey', self.fn, *self.args, **self.kwargs)
- | Map('UnKey', lambda (k, v): v))
+ | add_input_types(Map('KeyWithVoid', lambda v: (None, v))
+ .with_output_types(
+ KV[None, pcoll.element_type]))
+ | CombinePerKey(
+ 'CombinePerKey', self.fn, *self.args, **self.kwargs)
+ | Map('UnKey', lambda (k, v): v))
if not self.has_defaults and not self.as_view:
return combined
@@ -884,7 +886,7 @@ class CombineValues(PTransformWithSideInputs):
def apply(self, pcoll):
args, kwargs = util.insert_values_in_args(
- self.args, self.kwargs, self.side_inputs)
+ self.args, self.kwargs, self.side_inputs)
input_type = pcoll.element_type
key_type = None
@@ -1027,7 +1029,8 @@ class GroupByKey(PTransform):
'GroupByKey operation "%s"' % self.label)
reify_output_type = KV[key_type, typehints.WindowedValue[value_type]]
- gbk_input_type = KV[key_type, Iterable[typehints.WindowedValue[value_type]]]
+ gbk_input_type = (
+ KV[key_type, Iterable[typehints.WindowedValue[value_type]]])
gbk_output_type = KV[key_type, Iterable[value_type]]
return (pcoll
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/transforms/ptransform_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/transforms/ptransform_test.py b/sdks/python/apache_beam/transforms/ptransform_test.py
index 3244473..8ae7a37 100644
--- a/sdks/python/apache_beam/transforms/ptransform_test.py
+++ b/sdks/python/apache_beam/transforms/ptransform_test.py
@@ -286,7 +286,7 @@ class PTransformTest(unittest.TestCase):
vals_2 = [2, 4, 6, 8, 10, 12, 14]
pipeline = Pipeline('DirectPipelineRunner')
pcoll = pipeline | beam.Create('start', ([('a', x) for x in vals_1] +
- [('b', x) for x in vals_2]))
+ [('b', x) for x in vals_2]))
result = pcoll | beam.CombinePerKey('mean', self._MeanCombineFn())
assert_that(result, equal_to([('a', sum(vals_1) / len(vals_1)),
('b', sum(vals_2) / len(vals_2))]))
@@ -297,7 +297,7 @@ class PTransformTest(unittest.TestCase):
vals_2 = [2, 4, 6, 8, 10, 12, 14]
pipeline = Pipeline('DirectPipelineRunner')
pcoll = pipeline | beam.Create('start', ([('a', x) for x in vals_1] +
- [('b', x) for x in vals_2]))
+ [('b', x) for x in vals_2]))
result = pcoll | beam.CombinePerKey(sum)
assert_that(result, equal_to([('a', sum(vals_1)), ('b', sum(vals_2))]))
pipeline.run()
@@ -307,7 +307,7 @@ class PTransformTest(unittest.TestCase):
vals_2 = [2, 4, 6, 8, 10, 12, 14]
pipeline = Pipeline('DirectPipelineRunner')
pcoll = pipeline | beam.Create('start', ([('a', x) for x in vals_1] +
- [('b', x) for x in vals_2]))
+ [('b', x) for x in vals_2]))
divisor = pipeline | beam.Create('divisor', [2])
result = pcoll | beam.CombinePerKey(
lambda vals, d: max(v for v in vals if v % d == 0),
@@ -790,9 +790,9 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
d = (self.p
| beam.Create('s', ['t', 'e', 's', 't']).with_output_types(str)
| beam.FlatMap('dup', lambda x: [x + x])
- .with_input_types(str).with_output_types(str)
+ .with_input_types(str).with_output_types(str)
| beam.FlatMap('upper', lambda x: [x.upper()])
- .with_input_types(str).with_output_types(str))
+ .with_input_types(str).with_output_types(str))
assert_that(d, equal_to(['TT', 'EE', 'SS', 'TT']))
self.p.run()
@@ -803,7 +803,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
with self.assertRaises(typehints.TypeCheckError) as e:
d = (self.p
| beam.Create('s', [1, 2, 3, 4]).with_output_types(int)
- | beam.Map('upper', lambda x: x.upper()).with_input_types(str).with_output_types(str))
+ | beam.Map('upper', lambda x: x.upper())
+ .with_input_types(str).with_output_types(str))
self.assertEqual("Type hint violation for 'upper': "
"requires <type 'str'> but got <type 'int'> for x",
@@ -813,7 +814,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
# No error should be raised if this type-checks properly.
d = (self.p
| beam.Create('s', [1, 2, 3, 4]).with_output_types(int)
- | beam.Map('to_str', lambda x: str(x)).with_input_types(int).with_output_types(str))
+ | beam.Map('to_str', lambda x: str(x))
+ .with_input_types(int).with_output_types(str))
assert_that(d, equal_to(['1', '2', '3', '4']))
self.p.run()
@@ -853,7 +855,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
with self.assertRaises(typehints.TypeCheckError) as e:
(self.p
| beam.Create('strs', ['1', '2', '3', '4', '5']).with_output_types(str)
- | beam.Map('lower', lambda x: x.lower()).with_input_types(str).with_output_types(str)
+ | beam.Map('lower', lambda x: x.lower())
+ .with_input_types(str).with_output_types(str)
| beam.Filter('below 3', lambda x: x < 3).with_input_types(int))
self.assertEqual("Type hint violation for 'below 3': "
@@ -864,7 +867,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
# No error should be raised if this type-checks properly.
d = (self.p
| beam.Create('strs', ['1', '2', '3', '4', '5']).with_output_types(str)
- | beam.Map('to int', lambda x: int(x)).with_input_types(str).with_output_types(int)
+ | beam.Map('to int', lambda x: int(x))
+ .with_input_types(str).with_output_types(int)
| beam.Filter('below 3', lambda x: x < 3).with_input_types(int))
assert_that(d, equal_to([1, 2]))
self.p.run()
@@ -894,7 +898,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
(self.p
| beam.Create('str', range(5)).with_output_types(int)
| beam.Filter('half', half)
- | beam.Map('to bool', lambda x: bool(x)).with_input_types(int).with_output_types(bool))
+ | beam.Map('to bool', lambda x: bool(x))
+ .with_input_types(int).with_output_types(bool))
def test_group_by_key_only_output_type_deduction(self):
d = (self.p
@@ -982,7 +987,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
# checking was disabled above.
(self.p
| beam.Create('t', [1, 2, 3]).with_output_types(int)
- | beam.Map('lower', lambda x: x.lower()).with_input_types(str).with_output_types(str))
+ | beam.Map('lower', lambda x: x.lower())
+ .with_input_types(str).with_output_types(str))
def test_run_time_type_checking_enabled_type_violation(self):
self.p.options.view_as(TypeOptions).pipeline_type_check = False
@@ -1020,7 +1026,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
# Pipeline checking is off, but the above function should satisfy types at
# run-time.
result = (self.p
- | beam.Create('t', ['t', 'e', 's', 't', 'i', 'n', 'g']).with_output_types(str)
+ | beam.Create('t', ['t', 'e', 's', 't', 'i', 'n', 'g'])
+ .with_output_types(str)
| beam.Map('gen keys', group_with_upper_ord)
| beam.GroupByKey('O'))
@@ -1232,9 +1239,9 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
self.assertEqual(
"All functions for a Combine PTransform must accept a "
- "single argument compatible with: Iterable[Any]. "
- "Instead a function with input type: <type 'int'> was received.",
- e.exception.message)
+ "single argument compatible with: Iterable[Any]. "
+ "Instead a function with input type: <type 'int'> was received.",
+ e.exception.message)
def test_combine_pipeline_type_propagation_using_decorators(self):
@with_output_types(int)
@@ -1532,7 +1539,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
d = (self.p
| beam.Create('c', ['t', 'e', 's', 't']).with_output_types(str)
- | beam.Map('dup key', lambda x: (x, x)).with_output_types(typehints.KV[str, str])
+ | beam.Map('dup key', lambda x: (x, x))
+ .with_output_types(typehints.KV[str, str])
| combine.Count.PerKey('count dups'))
self.assertCompatible(typehints.KV[str, int], d.element_type)
@@ -1565,7 +1573,8 @@ class PTransformTypeCheckTestCase(TypeHintTestCase):
self.p.options.view_as(TypeOptions).runtime_type_check = True
d = (self.p
- | beam.Create('w', [True, True, False, True, True]).with_output_types(bool)
+ | beam.Create('w', [True, True, False, True, True])
+ .with_output_types(bool)
| combine.Count.PerElement('count elems'))
self.assertCompatible(typehints.KV[bool, int], d.element_type)
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/transforms/trigger_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/transforms/trigger_test.py b/sdks/python/apache_beam/transforms/trigger_test.py
index 5d4d7a8..fee9b1b 100644
--- a/sdks/python/apache_beam/transforms/trigger_test.py
+++ b/sdks/python/apache_beam/transforms/trigger_test.py
@@ -175,17 +175,18 @@ class TriggerTest(unittest.TestCase):
late=AfterCount(1)),
AccumulationMode.ACCUMULATING,
[(1, 'a'), (15, 'b'), (7, 'c'), (30, 'd')],
- {IntervalWindow(1, 25): [
- set('abc'), # early
- set('abc'), # on time
- set('abcxy') # late
- ],
- IntervalWindow(30, 40): [
- set('d'), # on time
- ],
- IntervalWindow(1, 40): [
- set('abcdxyz') # late
- ],
+ {
+ IntervalWindow(1, 25): [
+ set('abc'), # early
+ set('abc'), # on time
+ set('abcxy') # late
+ ],
+ IntervalWindow(30, 40): [
+ set('d'), # on time
+ ],
+ IntervalWindow(1, 40): [
+ set('abcdxyz') # late
+ ],
},
2,
late_data=[(1, 'x'), (2, 'y'), (21, 'z')])
@@ -374,7 +375,7 @@ class TriggerPipelineTest(unittest.TestCase):
| beam.FlatMap(lambda t: [('A', t), ('B', t + 5)])
| beam.Map(lambda (k, t): TimestampedValue((k, t), t))
| beam.WindowInto(FixedWindows(10), trigger=AfterCount(3),
- accumulation_mode=AccumulationMode.DISCARDING)
+ accumulation_mode=AccumulationMode.DISCARDING)
| beam.GroupByKey()
| beam.Map(lambda (k, v): ('%s-%s' % (k, len(v)), set(v))))
assert_that(result, equal_to(
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/typehints/trivial_inference.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/typehints/trivial_inference.py b/sdks/python/apache_beam/typehints/trivial_inference.py
index 55d580d..82ce765 100644
--- a/sdks/python/apache_beam/typehints/trivial_inference.py
+++ b/sdks/python/apache_beam/typehints/trivial_inference.py
@@ -237,7 +237,8 @@ def infer_return_type(c, input_types, debug=False, depth=5):
return infer_return_type_func(c.im_func, input_types, debug, depth)
elif isinstance(c, BoundMethod):
input_types = [c.unbound.im_class] + input_types
- return infer_return_type_func(c.unbound.im_func, input_types, debug, depth)
+ return infer_return_type_func(
+ c.unbound.im_func, input_types, debug, depth)
elif isinstance(c, (type, types.ClassType)):
if c in typehints.DISALLOWED_PRIMITIVE_TYPES:
return {
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/apache_beam/typehints/typehints.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/typehints/typehints.py b/sdks/python/apache_beam/typehints/typehints.py
index c109dc6..5e31fd1 100644
--- a/sdks/python/apache_beam/typehints/typehints.py
+++ b/sdks/python/apache_beam/typehints/typehints.py
@@ -15,7 +15,7 @@
# limitations under the License.
#
-"""Syntax and semantics for type-hinting custom-functions/PTransforms in the SDK.
+"""Syntax & semantics for type-hinting custom-functions/PTransforms in the SDK.
This module defines type-hinting objects and the corresponding syntax for
type-hinting function arguments, function return types, or PTransform object
@@ -322,7 +322,8 @@ def _unified_repr(o):
Returns:
A qualified name for the passed Python object fit for string formatting.
"""
- return repr(o) if isinstance(o, (TypeConstraint, types.NoneType)) else o.__name__
+ return repr(o) if isinstance(
+ o, (TypeConstraint, types.NoneType)) else o.__name__
def check_constraint(type_constraint, object_instance):
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/run_pylint.sh
----------------------------------------------------------------------
diff --git a/sdks/python/run_pylint.sh b/sdks/python/run_pylint.sh
new file mode 100755
index 0000000..e8062c0
--- /dev/null
+++ b/sdks/python/run_pylint.sh
@@ -0,0 +1,48 @@
+#!/bin/bash
+#
+# Licensed to the Apache Software Foundation (ASF) under one or more
+# contributor license agreements. See the NOTICE file distributed with
+# this work for additional information regarding copyright ownership.
+# The ASF licenses this file to You under the Apache License, Version 2.0
+# (the "License"); you may not use this file except in compliance with
+# the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+# See the License for the specific language governing permissions and
+# limitations under the License.
+#
+
+# This script will run pylint on files that changed compared to the current
+# HEAD of the branch.
+#
+# Use "pylint apache_beam" to run pylint all files.
+#
+# The exit-code of the script indicates success or a failure.
+
+BASE_BRANCH=python-sdk
+
+set -e
+set -o pipefail
+
+# Retrieve base branch for comparison. Travis does not fetch it by default.
+git remote set-branches --add origin $BASE_BRANCH
+git fetch
+
+# Get the name of the files that changed compared to the HEAD of the branch.
+# Filter the output to .py files only. Rewrite the paths relative to the
+# sdks/python folder.
+CHANGED_FILES=$(git diff --name-only origin/$BASE_BRANCH apache_beam \
+ | { grep ".py$" || true; } \
+ | sed 's/sdks\/python\///g')
+
+if test "$CHANGED_FILES"; then
+ echo "Running pylint on changed files:"
+ echo "$CHANGED_FILES"
+ pylint $CHANGED_FILES
+else
+ echo "Not running pylint. No eligible files."
+fi
http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f71c1ddd/sdks/python/tox.ini
----------------------------------------------------------------------
diff --git a/sdks/python/tox.ini b/sdks/python/tox.ini
index c0208b5..356de57 100644
--- a/sdks/python/tox.ini
+++ b/sdks/python/tox.ini
@@ -19,6 +19,8 @@
envlist = py27
[testenv:py27]
+deps=pylint
commands =
python setup.py test
+ {toxinidir}/run_pylint.sh
passenv = TRAVIS*