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 2017/10/12 22:54:39 UTC
[03/18] beam git commit: Add special work to handle indexable return
types. Introduce a base IndexableTypeConstraint.
Add special work to handle indexable return types. Introduce a base IndexableTypeConstraint.
Project: http://git-wip-us.apache.org/repos/asf/beam/repo
Commit: http://git-wip-us.apache.org/repos/asf/beam/commit/f364248b
Tree: http://git-wip-us.apache.org/repos/asf/beam/tree/f364248b
Diff: http://git-wip-us.apache.org/repos/asf/beam/diff/f364248b
Branch: refs/heads/master
Commit: f364248b984e8ff884a34b37d49a17fa1a50cc26
Parents: 5cc6b5f
Author: Holden Karau <ho...@us.ibm.com>
Authored: Fri Sep 1 20:51:18 2017 -0700
Committer: Robert Bradshaw <ro...@gmail.com>
Committed: Thu Oct 12 15:50:08 2017 -0700
----------------------------------------------------------------------
.../apache_beam/typehints/trivial_inference.py | 20 +++++++++++++-
.../typehints/trivial_inference_test.py | 5 ++++
sdks/python/apache_beam/typehints/typehints.py | 28 +++++++++++++++++---
3 files changed, 49 insertions(+), 4 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/beam/blob/f364248b/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 51d3db2..a68bd18 100644
--- a/sdks/python/apache_beam/typehints/trivial_inference.py
+++ b/sdks/python/apache_beam/typehints/trivial_inference.py
@@ -107,7 +107,10 @@ class FrameState(object):
def __init__(self, f, local_vars=None, stack=()):
self.f = f
- self.co = f.__code__
+ if sys.version_info[0] >= 3:
+ self.co = f.__code__
+ else:
+ self.co = f.func_code
self.vars = list(local_vars)
self.stack = list(stack)
@@ -362,7 +365,22 @@ def infer_return_type_func(f, input_types, debug=False, depth=0):
else:
return_type = Any
state.stack[-pop_count:] = [return_type]
+ elif (opname == 'BINARY_SUBSCR'
+ and isinstance(state.stack[1], Const)
+ and isinstance(state.stack[0], typehints.IndexableTypeConstraint)):
+ if debug:
+ print("Executing special case binary subscript")
+ idx = state.stack.pop()
+ src = state.stack.pop()
+ try:
+ state.stack.append(src._constraint_for_index(idx.value))
+ except Exception as e:
+ if debug:
+ print("Exception {0} during special case indexing".format(e))
+ state.stack.append(Any)
elif opname in simple_ops:
+ if debug:
+ print("Executing simple op " + opname)
simple_ops[opname](state, arg)
elif opname == 'RETURN_VALUE':
returns.add(state.stack[-1])
http://git-wip-us.apache.org/repos/asf/beam/blob/f364248b/sdks/python/apache_beam/typehints/trivial_inference_test.py
----------------------------------------------------------------------
diff --git a/sdks/python/apache_beam/typehints/trivial_inference_test.py b/sdks/python/apache_beam/typehints/trivial_inference_test.py
index 8af9dd6..7b7b6a8 100644
--- a/sdks/python/apache_beam/typehints/trivial_inference_test.py
+++ b/sdks/python/apache_beam/typehints/trivial_inference_test.py
@@ -32,6 +32,11 @@ class TrivialInferenceTest(unittest.TestCase):
def testIdentity(self):
self.assertReturnType(int, lambda x: x, [int])
+ def testIndexing(self):
+ self.assertReturnType(int, lambda x: x[0], [typehints.Tuple[int, str]])
+ self.assertReturnType(str, lambda x: x[1], [typehints.Tuple[int, str]])
+ self.assertReturnType(str, lambda x: x[1], [typehints.List[str]])
+
def testTuples(self):
self.assertReturnType(
typehints.Tuple[typehints.Tuple[()], int], lambda x: ((), x), [int])
http://git-wip-us.apache.org/repos/asf/beam/blob/f364248b/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 a27dd7e..b78ead2 100644
--- a/sdks/python/apache_beam/typehints/typehints.py
+++ b/sdks/python/apache_beam/typehints/typehints.py
@@ -65,6 +65,7 @@ In addition, type-hints can be used to implement run-time type-checking via the
import collections
import copy
+import sys
import types
__all__ = [
@@ -184,7 +185,17 @@ def bind_type_variables(type_constraint, bindings):
return type_constraint
-class SequenceTypeConstraint(TypeConstraint):
+class IndexableTypeConstraint(TypeConstraint):
+ """An internal common base-class for all type constraints with indexing.
+ E.G. SequenceTypeConstraint + Tuple's of fixed size.
+ """
+
+ def _constraint_for_index(self, idx):
+ """Returns the type at the given index."""
+ raise NotImplementedError
+
+
+class SequenceTypeConstraint(IndexableTypeConstraint):
"""A common base-class for all sequence related type-constraint classes.
A sequence is defined as an arbitrary length homogeneous container type. Type
@@ -214,6 +225,10 @@ class SequenceTypeConstraint(TypeConstraint):
def _inner_types(self):
yield self.inner_type
+ def _constraint_for_index(self, idx):
+ """Returns the type at the given index."""
+ return self.inner_type
+
def _consistent_with_check_(self, sub):
return (isinstance(sub, self.__class__)
and is_consistent_with(sub.inner_type, self.inner_type))
@@ -314,8 +329,11 @@ def validate_composite_type_param(type_param, error_msg_prefix):
parameter for a :class:`CompositeTypeHint`.
"""
# Must either be a TypeConstraint instance or a basic Python type.
+ possible_classes = [type, TypeConstraint]
+ if sys.version_info[0] == 2:
+ possible_classes.append(types.ClassType)
is_not_type_constraint = (
- not isinstance(type_param, (type, TypeConstraint))
+ not isinstance(type_param, tuple(possible_classes))
and type_param is not None)
is_forbidden_type = (isinstance(type_param, type) and
type_param in DISALLOWED_PRIMITIVE_TYPES)
@@ -546,7 +564,7 @@ class TupleHint(CompositeTypeHint):
for elem in sub.tuple_types)
return super(TupleSequenceConstraint, self)._consistent_with_check_(sub)
- class TupleConstraint(TypeConstraint):
+ class TupleConstraint(IndexableTypeConstraint):
def __init__(self, type_params):
self.tuple_types = tuple(type_params)
@@ -566,6 +584,10 @@ class TupleHint(CompositeTypeHint):
for t in self.tuple_types:
yield t
+ def _constraint_for_index(self, idx):
+ """Returns the type at the given index."""
+ return self.tuple_types[idx]
+
def _consistent_with_check_(self, sub):
return (isinstance(sub, self.__class__)
and len(sub.tuple_types) == len(self.tuple_types)