Пример #1
0
  def _rename_compilable_function(self, node):
    assert anno.hasanno(node.func, 'live_val')
    assert anno.hasanno(node.func, 'fqn')
    target_entity = anno.getanno(node.func, 'live_val')
    target_fqn = anno.getanno(node.func, 'fqn')

    if not self._should_compile(node, target_fqn):
      return node

    if anno.hasanno(node, 'is_constructor'):
      new_name = self.context.namer.compiled_class_name(
          target_fqn, live_entity=target_entity)
      do_rename = True
    else:
      if anno.hasanno(node.func, 'parent_type'):
        owner_type = anno.getanno(node.func, 'parent_type')
      else:
        # Fallback - not reliable.
        owner_type = inspect_utils.getmethodclass(target_entity)
      new_name, do_rename = self.context.namer.compiled_function_name(
          target_fqn, live_entity=target_entity, owner_type=owner_type)

    if do_rename:
      if target_entity is not None:
        if tf_inspect.ismethod(target_entity):
          # The renaming process will transform it into a regular function.
          # TODO(mdan): Is this complete? How does it work with nested members?
          node.args = [node.func.value] + node.args
      node.func = templates.replace('func_name', func_name=new_name)[0]
    return node
Пример #2
0
    def _rename_compilable_function(self, node):
        assert anno.hasanno(node.func, 'live_val')
        assert anno.hasanno(node.func, 'fqn')
        target_entity = anno.getanno(node.func, 'live_val')
        target_fqn = anno.getanno(node.func, 'fqn')

        if not self._should_compile(node, target_fqn):
            return node

        if anno.hasanno(node, 'is_constructor'):
            new_name = self.context.namer.compiled_class_name(
                target_fqn, live_entity=target_entity)
            do_rename = True
        else:
            if anno.hasanno(node.func, 'parent_type'):
                owner_type = anno.getanno(node.func, 'parent_type')
            else:
                # Fallback - not reliable.
                owner_type = inspect_utils.getmethodclass(target_entity)
            new_name, do_rename = self.context.namer.compiled_function_name(
                target_fqn, live_entity=target_entity, owner_type=owner_type)

        if do_rename:
            if target_entity is not None:
                if tf_inspect.ismethod(target_entity):
                    # The renaming process will transform it into a regular function.
                    # TODO(mdan): Is this complete? How does it work with nested members?
                    node.args = [node.func.value] + node.args
            node.func = templates.replace('func_name', func_name=new_name)[0]
        return node
Пример #3
0
  def test_getmethodclass_locals(self):

    def local_function():
      pass

    class LocalClass(object):

      def member_function(self):
        pass

      @decorator
      def decorated_member(self):
        pass

      @function_decorator()
      def fn_decorated_member(self):
        pass

      @wrapping_decorator()
      def wrap_decorated_member(self):
        pass

    self.assertEqual(
        inspect_utils.getmethodclass(local_function, {}), None)

    ns = {'LocalClass': LocalClass}
    self.assertEqual(
        inspect_utils.getmethodclass(LocalClass.member_function, ns),
        LocalClass)
    self.assertEqual(
        inspect_utils.getmethodclass(LocalClass.decorated_member, ns),
        LocalClass)
    self.assertEqual(
        inspect_utils.getmethodclass(LocalClass.fn_decorated_member, ns),
        LocalClass)
    self.assertEqual(
        inspect_utils.getmethodclass(LocalClass.wrap_decorated_member, ns),
        LocalClass)

    test_obj = LocalClass()
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.member_function, ns),
        LocalClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.decorated_member, ns),
        LocalClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.fn_decorated_member, ns),
        LocalClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.wrap_decorated_member, ns),
        LocalClass)
    def test_getmethodclass(self):

        self.assertEqual(inspect_utils.getmethodclass(free_function), None)
        self.assertEqual(inspect_utils.getmethodclass(free_factory()), None)

        self.assertEqual(
            inspect_utils.getmethodclass(TestClass.member_function), TestClass)
        self.assertEqual(
            inspect_utils.getmethodclass(TestClass.decorated_member),
            TestClass)
        self.assertEqual(
            inspect_utils.getmethodclass(TestClass.fn_decorated_member),
            TestClass)
        self.assertEqual(
            inspect_utils.getmethodclass(TestClass.wrap_decorated_member),
            TestClass)
        self.assertEqual(inspect_utils.getmethodclass(TestClass.static_method),
                         TestClass)
        self.assertEqual(inspect_utils.getmethodclass(TestClass.class_method),
                         TestClass)

        test_obj = TestClass()
        self.assertEqual(
            inspect_utils.getmethodclass(test_obj.member_function), TestClass)
        self.assertEqual(
            inspect_utils.getmethodclass(test_obj.decorated_member), TestClass)
        self.assertEqual(
            inspect_utils.getmethodclass(test_obj.fn_decorated_member),
            TestClass)
        self.assertEqual(
            inspect_utils.getmethodclass(test_obj.wrap_decorated_member),
            TestClass)
        self.assertEqual(inspect_utils.getmethodclass(test_obj.static_method),
                         TestClass)
        self.assertEqual(inspect_utils.getmethodclass(test_obj.class_method),
                         TestClass)
Пример #5
0
  def test_getmethodclass(self):

    self.assertEqual(
        inspect_utils.getmethodclass(free_function), None)
    self.assertEqual(
        inspect_utils.getmethodclass(free_factory()), None)

    self.assertEqual(
        inspect_utils.getmethodclass(TestClass.member_function),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(TestClass.decorated_member),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(TestClass.fn_decorated_member),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(TestClass.wrap_decorated_member),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(TestClass.static_method),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(TestClass.class_method),
        TestClass)

    test_obj = TestClass()
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.member_function),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.decorated_member),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.fn_decorated_member),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.wrap_decorated_member),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.static_method),
        TestClass)
    self.assertEqual(
        inspect_utils.getmethodclass(test_obj.class_method),
        TestClass)
Пример #6
0
def converted_call(f, recursive, verbose, arg_types, *args, **kwargs):
  """Compiles a function call inline."""
  # TODO(mdan): This needs cleanup.
  # In particular, we may want to avoid renaming functions altogether.

  if conversion.is_whitelisted_for_graph(f):
    return f(*args, **kwargs)

  unknown_arg_value = object()  # Sentinel for arguments of unknown value

  if tf_inspect.isbuiltin(f):
    return builtins.dynamic_builtin(f, *args, **kwargs)

  if tf_inspect.isfunction(f) or tf_inspect.ismethod(f):
    # Regular functions
    target_entity = f
    arg_map_target = f
    effective_args = args
    f_class = inspect_utils.getmethodclass(f)

    if f_class is not None:
      partial_types = (f_class,)
    else:
      partial_types = ()

  elif tf_inspect.isclass(f):
    # Constructors
    target_entity = f
    arg_map_target = f.__init__
    effective_args = (unknown_arg_value,) + args
    partial_types = ()

  elif hasattr(f, '__call__') and hasattr(f, '__class__'):
    # Callable objects
    target_entity = f.__call__
    arg_map_target = f.__call__
    effective_args = (f,) + args
    partial_types = (f.__class__,)

  else:
    NotImplementedError('unknown callable type "%s"' % type(f))

  arg_values = tf_inspect.getcallargs(arg_map_target, *args, **kwargs)
  for name, arg in arg_values.items():
    if arg is unknown_arg_value:
      continue
    arg_class = arg.__class__
    # If arg_value_hints specifies any name, use that instead.
    if name not in arg_types:
      arg_types[name] = (arg_class.__name__, arg_class)

  # When called from within a decorator, this is the only indication that
  # the function is a method - it appears that the decorator is applied
  # before the method is bound.
  if not partial_types:
    if 'self' in arg_values:
      if tf_inspect.isclass(arg_values['self'].__class__):
        partial_types = (arg_values['self'].__class__,)
    elif 'cls' in arg_values:
      if tf_inspect.isclass(arg_values['cls']):
        partial_types = (arg_values['cls'],)

  converted_f = to_graph(
      target_entity,
      recursive=recursive,
      verbose=verbose,
      arg_values=arg_values,
      arg_types=arg_types,
      partial_types=partial_types)
  return converted_f(*effective_args, **kwargs)
Пример #7
0
def converted_call(f, recursive, verbose, arg_types, *args, **kwargs):
    """Compiles a function call inline."""
    # TODO(mdan): This needs cleanup.
    # In particular, we may want to avoid renaming functions altogether.

    if conversion.is_whitelisted_for_graph(f):
        return f(*args, **kwargs)

    unknown_arg_value = object()  # Sentinel for arguments of unknown value

    if tf_inspect.isbuiltin(f):
        return builtins.dynamic_builtin(f, *args, **kwargs)

    if tf_inspect.isfunction(f) or tf_inspect.ismethod(f):
        # Regular functions
        target_entity = f
        arg_map_target = f
        effective_args = args
        f_class = inspect_utils.getmethodclass(f)

        if f_class is not None:
            partial_types = (f_class, )
        else:
            partial_types = ()

    elif tf_inspect.isclass(f):
        # Constructors
        target_entity = f
        arg_map_target = f.__init__
        effective_args = (unknown_arg_value, ) + args
        partial_types = ()

    elif hasattr(f, '__call__') and hasattr(f, '__class__'):
        # Callable objects
        target_entity = f.__call__
        arg_map_target = f.__call__
        effective_args = (f, ) + args
        partial_types = (f.__class__, )

    else:
        NotImplementedError('unknown callable type "%s"' % type(f))

    arg_values = tf_inspect.getcallargs(arg_map_target, *args, **kwargs)
    for name, arg in arg_values.items():
        if arg is unknown_arg_value:
            continue
        arg_class = arg.__class__
        # If arg_value_hints specifies any name, use that instead.
        if name not in arg_types:
            arg_types[name] = (arg_class.__name__, arg_class)

    # When called from within a decorator, this is the only indication that
    # the function is a method - it appears that the decorator is applied
    # before the method is bound.
    if not partial_types:
        if 'self' in arg_values:
            if tf_inspect.isclass(arg_values['self'].__class__):
                partial_types = (arg_values['self'].__class__, )
        elif 'cls' in arg_values:
            if tf_inspect.isclass(arg_values['cls']):
                partial_types = (arg_values['cls'], )

    converted_f = to_graph(target_entity,
                           recursive=recursive,
                           verbose=verbose,
                           arg_values=arg_values,
                           arg_types=arg_types,
                           partial_types=partial_types)
    return converted_f(*effective_args, **kwargs)