You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@beam.apache.org by ro...@apache.org on 2016/09/30 23:48:37 UTC

[1/3] incubator-beam git commit: Use keyword arguments in fnc calls

Repository: incubator-beam
Updated Branches:
  refs/heads/python-sdk dc92438fa -> 731a77152


Use keyword arguments in fnc calls


Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/f94eb53b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/f94eb53b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/f94eb53b

Branch: refs/heads/python-sdk
Commit: f94eb53b8b1fbf405d6fa62baeb9b9ee9090c1de
Parents: 5e87980
Author: Maria Garcia Herrero <ma...@google.com>
Authored: Fri Sep 30 10:41:38 2016 -0700
Committer: Robert Bradshaw <ro...@google.com>
Committed: Fri Sep 30 16:48:05 2016 -0700

----------------------------------------------------------------------
 .../apache_beam/utils/annotations_test.py       | 51 ++++++++++++--------
 1 file changed, 32 insertions(+), 19 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/f94eb53b/sdks/python/apache_beam/utils/annotations_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/utils/annotations_test.py b/sdks/python/apache_beam/utils/annotations_test.py
index af89590..854098c 100644
--- a/sdks/python/apache_beam/utils/annotations_test.py
+++ b/sdks/python/apache_beam/utils/annotations_test.py
@@ -30,10 +30,12 @@ class AnnotationTests(unittest.TestCase):
       def fnc_test_deprecated_with_since_current():
         return 'lol'
       fnc_test_deprecated_with_since_current()
-      self.check_annotation(w, 1, DeprecationWarning,
-                            'fnc_test_deprecated_with_since_current',
-                            'deprecated',
-                            [('since', True), ('instead', True)])
+      self.check_annotation(warning=w, warning_size=1,
+                            warning_type=DeprecationWarning,
+                            fnc_name='fnc_test_deprecated_with_since_current',
+                            annotation_type='deprecated',
+                            label_check_list=[('since', True),
+                                              ('instead', True)])
 
   def test_deprecated_without_current(self):
     with warnings.catch_warnings(record=True) as w:
@@ -41,9 +43,12 @@ class AnnotationTests(unittest.TestCase):
       def fnc_test_deprecated_without_current():
         return 'lol'
       fnc_test_deprecated_without_current()
-      self.check_annotation(w, 1, DeprecationWarning,
-                            'fnc_test_deprecated_without_current', 'deprecated',
-                            [('since', True), ('instead', False)])
+      self.check_annotation(warning=w, warning_size=1,
+                            warning_type=DeprecationWarning,
+                            fnc_name='fnc_test_deprecated_without_current',
+                            annotation_type='deprecated',
+                            label_check_list=[('since', True),
+                                              ('instead', False)])
 
   def test_deprecated_without_since_should_fail(self):
     with warnings.catch_warnings(record=True) as w:
@@ -61,9 +66,11 @@ class AnnotationTests(unittest.TestCase):
       def fnc_test_experimental_with_current():
         return 'lol'
       fnc_test_experimental_with_current()
-      self.check_annotation(w, 1, FutureWarning,
-                            'fnc_test_experimental_with_current',
-                            'experimental', [('instead', True)])
+      self.check_annotation(warning=w, warning_size=1,
+                            warning_type=FutureWarning,
+                            fnc_name='fnc_test_experimental_with_current',
+                            annotation_type='experimental',
+                            label_check_list=[('instead', True)])
 
   def test_experimental_without_current(self):
     with warnings.catch_warnings(record=True) as w:
@@ -71,9 +78,11 @@ class AnnotationTests(unittest.TestCase):
       def fnc_test_experimental_without_current():
         return 'lol'
       fnc_test_experimental_without_current()
-      self.check_annotation(w, 1, FutureWarning,
-                            'fnc_test_experimental_without_current',
-                            'experimental', [('instead', False)])
+      self.check_annotation(warning=w, warning_size=1,
+                            warning_type=FutureWarning,
+                            fnc_name='fnc_test_experimental_without_current',
+                            annotation_type='experimental',
+                            label_check_list=[('instead', False)])
 
   def test_frequency(self):
     """Tests that the filter 'once' is sufficient to print once per
@@ -89,12 +98,16 @@ class AnnotationTests(unittest.TestCase):
       fnc_test_annotate_frequency()
       fnc_test_annotate_frequency()
       fnc2_test_annotate_frequency()
-      self.check_annotation([w[0]], 1, FutureWarning,
-                            'fnc_test_annotate_frequency', 'experimental',
-                            [])
-      self.check_annotation([w[1]], 1, FutureWarning,
-                            'fnc2_test_annotate_frequency', 'experimental',
-                            [])
+      self.check_annotation(warning=[w[0]], warning_size=1,
+                            warning_type=FutureWarning,
+                            fnc_name='fnc_test_annotate_frequency',
+                            annotation_type='experimental',
+                            label_check_list=[])
+      self.check_annotation(warning=[w[1]], warning_size=1,
+                            warning_type=FutureWarning,
+                            fnc_name='fnc2_test_annotate_frequency',
+                            annotation_type='experimental',
+                            label_check_list=[])
 
   # helper function
   def check_annotation(self, warning, warning_size, warning_type, fnc_name,


[3/3] incubator-beam git commit: Closes #1001

Posted by ro...@apache.org.
Closes #1001


Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/731a7715
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/731a7715
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/731a7715

Branch: refs/heads/python-sdk
Commit: 731a7715233f91599dd10133c58cdf97c87d6564
Parents: dc92438 f94eb53
Author: Robert Bradshaw <ro...@google.com>
Authored: Fri Sep 30 16:48:15 2016 -0700
Committer: Robert Bradshaw <ro...@google.com>
Committed: Fri Sep 30 16:48:15 2016 -0700

----------------------------------------------------------------------
 sdks/python/apache_beam/utils/annotations.py    |  99 +++++++++++++++
 .../apache_beam/utils/annotations_test.py       | 126 +++++++++++++++++++
 2 files changed, 225 insertions(+)
----------------------------------------------------------------------



[2/3] incubator-beam git commit: Add annotation to mark deprecated or experimental APIs via decorators.

Posted by ro...@apache.org.
Add annotation to mark deprecated or experimental APIs via decorators.


Project: http://git-wip-us.apache.org/repos/asf/incubator-beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-beam/commit/5e87980b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-beam/tree/5e87980b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-beam/diff/5e87980b

Branch: refs/heads/python-sdk
Commit: 5e87980b3cd19bd62aec585808f3f7a349486a79
Parents: dc92438
Author: Maria Garcia Herrero <ma...@google.com>
Authored: Sat Sep 24 02:05:46 2016 -0700
Committer: Robert Bradshaw <ro...@google.com>
Committed: Fri Sep 30 16:48:05 2016 -0700

----------------------------------------------------------------------
 sdks/python/apache_beam/utils/annotations.py    |  99 ++++++++++++++++
 .../apache_beam/utils/annotations_test.py       | 113 +++++++++++++++++++
 2 files changed, 212 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/5e87980b/sdks/python/apache_beam/utils/annotations.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/utils/annotations.py b/sdks/python/apache_beam/utils/annotations.py
new file mode 100644
index 0000000..aa53554
--- /dev/null
+++ b/sdks/python/apache_beam/utils/annotations.py
@@ -0,0 +1,99 @@
+#
+# 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.
+#
+
+""" Deprecated and experimental annotations.
+
+Annotations come in two flavors: deprecated and experimental
+
+The 'deprecated' annotation requires a 'since" parameter to specify
+what version deprecated it.
+Both 'deprecated' and 'experimental' annotations can specify the
+current recommended version to use by means of a 'current' parameter.
+
+The following example illustrates how to annotate coexisting versions of the
+same function 'multiply'.
+def multiply(arg1, arg2):
+  print arg1, '*', arg2, '=',
+  return arg1*arg2
+
+# This annotation marks 'old_multiply' as deprecated since 'v.1' and suggests
+# using 'multiply' instead.
+@deprecated(since='v.1', current='multiply')
+def old_multiply(arg1, arg2):
+  result = 0
+  for i in xrange(arg1):
+      result += arg2
+  print arg1, '*', arg2, '(the old way)=',
+  return result
+
+# This annotation marks 'exp_multiply' as experimental and suggests
+# using 'multiply' instead.
+@experimental(since='v.1', current='multiply')
+def exp_multiply(arg1, arg2):
+  print arg1, '*', arg2, '(the experimental way)=',
+  return (arg1*arg2)*(arg1/arg2)*(arg2/arg1)
+
+# Set a warning filter to control how often warnings are produced
+warnings.simplefilter("always")
+print multiply(5, 6)
+print old_multiply(5,6)
+print exp_multiply(5,6)
+"""
+
+import warnings
+from functools import partial
+from functools import wraps
+
+# Produce only the first occurrence of matching warnings regardless of
+# location per line of execution. Since the number of lines of execution
+# depends on the concrete runner, the number of warnings produced will
+# vary depending on the runner.
+warnings.simplefilter("once")
+
+
+def annotate(label, since, current):
+  """Decorates a function with a deprecated or experimental annotation.
+
+  Args:
+    label: the kind of annotation ('deprecated' or 'experimental').
+    since: the version that causes the annotation.
+    current: the suggested replacement function.
+
+  Returns:
+    The decorator for the function.
+  """
+  def _annotate(fnc):
+    @wraps(fnc)
+    def inner(*args, **kwargs):
+      if label == 'deprecated':
+        warning_type = DeprecationWarning
+      else:
+        warning_type = FutureWarning
+      message = '%s is %s' % (fnc.__name__, label)
+      if label == 'deprecated':
+        message += ' since %s' % since
+      message += '. Use %s instead.'% current if current else '.'
+      warnings.warn(message, warning_type)
+      return fnc(*args, **kwargs)
+    return inner
+  return _annotate
+
+# Use partial application to customize each annotation.
+# 'current' will be optional in both deprecated and experimental
+# while 'since' will be mandatory for deprecated.
+deprecated = partial(annotate, label='deprecated', current=None)
+experimental = partial(annotate, label='experimental', current=None, since=None)

http://git-wip-us.apache.org/repos/asf/incubator-beam/blob/5e87980b/sdks/python/apache_beam/utils/annotations_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/utils/annotations_test.py b/sdks/python/apache_beam/utils/annotations_test.py
new file mode 100644
index 0000000..af89590
--- /dev/null
+++ b/sdks/python/apache_beam/utils/annotations_test.py
@@ -0,0 +1,113 @@
+#
+# 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.
+#
+
+import unittest
+import warnings
+from annotations import deprecated
+from annotations import experimental
+
+
+class AnnotationTests(unittest.TestCase):
+  # Note: use different names for each of the the functions decorated
+  # so that a warning is produced for each of them.
+  def test_deprecated_with_since_current(self):
+    with warnings.catch_warnings(record=True) as w:
+      @deprecated(since='v.1', current='multiply')
+      def fnc_test_deprecated_with_since_current():
+        return 'lol'
+      fnc_test_deprecated_with_since_current()
+      self.check_annotation(w, 1, DeprecationWarning,
+                            'fnc_test_deprecated_with_since_current',
+                            'deprecated',
+                            [('since', True), ('instead', True)])
+
+  def test_deprecated_without_current(self):
+    with warnings.catch_warnings(record=True) as w:
+      @deprecated(since='v.1')
+      def fnc_test_deprecated_without_current():
+        return 'lol'
+      fnc_test_deprecated_without_current()
+      self.check_annotation(w, 1, DeprecationWarning,
+                            'fnc_test_deprecated_without_current', 'deprecated',
+                            [('since', True), ('instead', False)])
+
+  def test_deprecated_without_since_should_fail(self):
+    with warnings.catch_warnings(record=True) as w:
+      with self.assertRaises(TypeError):
+
+        @deprecated()
+        def fnc_test_deprecated_without_since_should_fail():
+          return 'lol'
+        fnc_test_deprecated_without_since_should_fail()
+      assert len(w) == 0
+
+  def test_experimental_with_current(self):
+    with warnings.catch_warnings(record=True) as w:
+      @experimental(current='multiply')
+      def fnc_test_experimental_with_current():
+        return 'lol'
+      fnc_test_experimental_with_current()
+      self.check_annotation(w, 1, FutureWarning,
+                            'fnc_test_experimental_with_current',
+                            'experimental', [('instead', True)])
+
+  def test_experimental_without_current(self):
+    with warnings.catch_warnings(record=True) as w:
+      @experimental()
+      def fnc_test_experimental_without_current():
+        return 'lol'
+      fnc_test_experimental_without_current()
+      self.check_annotation(w, 1, FutureWarning,
+                            'fnc_test_experimental_without_current',
+                            'experimental', [('instead', False)])
+
+  def test_frequency(self):
+    """Tests that the filter 'once' is sufficient to print once per
+    warning independently of location."""
+    with warnings.catch_warnings(record=True) as w:
+      @experimental()
+      def fnc_test_annotate_frequency():
+        return 'lol'
+
+      @experimental()
+      def fnc2_test_annotate_frequency():
+        return 'lol'
+      fnc_test_annotate_frequency()
+      fnc_test_annotate_frequency()
+      fnc2_test_annotate_frequency()
+      self.check_annotation([w[0]], 1, FutureWarning,
+                            'fnc_test_annotate_frequency', 'experimental',
+                            [])
+      self.check_annotation([w[1]], 1, FutureWarning,
+                            'fnc2_test_annotate_frequency', 'experimental',
+                            [])
+
+  # helper function
+  def check_annotation(self, warning, warning_size, warning_type, fnc_name,
+                       annotation_type, label_check_list):
+    self.assertEqual(1, warning_size)
+    self.assertTrue(issubclass(warning[-1].category, warning_type))
+    self.assertIn(fnc_name + ' is ' + annotation_type, str(warning[-1].message))
+    for label in label_check_list:
+      if label[1] is True:
+        self.assertIn(label[0], str(warning[-1].message))
+      else:
+        self.assertNotIn(label[0], str(warning[-1].message))
+
+
+if __name__ == '__main__': # It doesn't like these 2 lines
+  unittest.main()