def test_keywords_to_dict(self): keywords = parser.parse_expression('f(a=b, c=1, d=\'e\')').keywords d = ast_util.keywords_to_dict(keywords) # Make sure we generate a usable dict node by attaching it to a variable and # compiling everything. node = parser.parse_str('def f(b): pass').body[0] node.body.append(ast.Return(d)) result, _ = compiler.ast_to_object(node) self.assertDictEqual(result.f(3), {'a': 3, 'c': 1, 'd': 'e'})
def _wrap_to_py_func_no_return(self, node): # TODO(mdan): Properly handle varargs, etc. template = """ ag__.utils.wrap_py_func(func, None, (args,), kwargs, True) """ return templates.replace( template, func=node.func, args=node.args, kwargs=ast_util.keywords_to_dict(node.keywords))
def _wrap_to_py_func_no_return(self, node): # TODO(mdan): Properly handle varargs, etc. template = """ ag__.utils.wrap_py_func(func, None, (args,), kwargs, True) """ return templates.replace(template, func=node.func, args=node.args, kwargs=ast_util.keywords_to_dict( node.keywords))
def _wrap_to_py_func_single_return(self, node, dtype): # TODO(mdan): Properly handle varargs, etc. template = """ ag__.utils.wrap_py_func(func, dtype, (args,), kwargs, False) """ return templates.replace_as_expression( template, func=node.func, dtype=parser.parse_expression(dtype), args=node.args, kwargs=ast_util.keywords_to_dict(node.keywords))
def visit_Call(self, node): # TODO(mdan): Refactor converted_call as a 'Call' operator. # Calls to the internal 'ag__' module are never converted (though their # arguments might be). full_name = str(anno.getanno(node.func, anno.Basic.QN, default='')) if full_name.startswith('ag__.'): return self.generic_visit(node) # Calls to pdb.set_trace or ipdb.set_trace are never converted. We don't use # the normal mechanisms to bypass these literals because they are sensitive # to the frame they are being called from. # TODO(mdan): Generalize this to a "static whitelist" config. if full_name in ('pdb.set_trace', 'ipdb.set_trace'): return self.generic_visit(node) if (full_name == 'print' and not self.ctx.program.options.uses( converter.Feature.BUILTIN_FUNCTIONS)): return self.generic_visit(node) func = node.func starred_arg = None normal_args = [] for a in node.args: if isinstance(a, gast.Starred): assert starred_arg is None, 'Multiple *args should be impossible.' starred_arg = a else: a = self.visit(a) normal_args.append(a) if starred_arg is None: args = templates.replace_as_expression('(args,)', args=normal_args) else: args = templates.replace_as_expression('(args,) + tuple(stararg)', stararg=starred_arg.value, args=normal_args) kwargs_arg = None normal_keywords = [] for k in node.keywords: if k.arg is None: assert kwargs_arg is None, 'Multiple **kwargs should be impossible.' kwargs_arg = k else: k = self.visit(k) normal_keywords.append(k) if kwargs_arg is None: if not normal_keywords: kwargs = parser.parse_expression('None') else: kwargs = ast_util.keywords_to_dict(normal_keywords) else: kwargs = templates.replace_as_expression( 'dict(kwargs, **keywords)', kwargs=kwargs_arg.value, keywords=ast_util.keywords_to_dict(normal_keywords)) template = """ ag__.converted_call(func, options, args, kwargs) """ new_call = templates.replace_as_expression( template, func=func, options=self.ctx.program.options.to_ast( internal_convert_user_code=self.ctx.program.options.recursive), args=args, kwargs=kwargs) return new_call
def visit_Call(self, node): # TODO(mdan): Refactor converted_call as a 'Call' operator. # Calls to the internal 'ag__' module are never converted (though their # arguments might be). full_name = str(anno.getanno(node.func, anno.Basic.QN, default='')) if full_name.startswith('ag__.'): return self.generic_visit(node) if (full_name == 'print' and not self.ctx.program.options.uses(converter.Feature.BUILTIN_FUNCTIONS)): return self.generic_visit(node) if isinstance(node.func, gast.Attribute): func = gast.Str(node.func.attr) owner = node.func.value else: func = node.func owner = parser.parse_expression('None') starred_arg = None normal_args = [] for a in node.args: if isinstance(a, gast.Starred): assert starred_arg is None, 'Multiple *args should be impossible.' starred_arg = a else: normal_args.append(a) if starred_arg is None: args = templates.replace_as_expression('(args,)', args=normal_args) else: args = templates.replace_as_expression( '(args,) + tuple(stararg)', stararg=starred_arg.value, args=normal_args) kwargs_arg = None normal_keywords = [] for k in node.keywords: if k.arg is None: assert kwargs_arg is None, 'Multiple **kwargs should be impossible.' kwargs_arg = k else: normal_keywords.append(k) if kwargs_arg is None: kwargs = ast_util.keywords_to_dict(normal_keywords) else: kwargs = templates.replace_as_expression( 'dict(kwargs, **keywords)', kwargs=kwargs_arg.value, keywords=ast_util.keywords_to_dict(normal_keywords)) template = """ ag__.converted_call(func, owner, options, args, kwargs) """ new_call = templates.replace_as_expression( template, func=func, owner=owner, options=self.ctx.program.options.to_ast( self.ctx, internal_convert_user_code=self.ctx.program.options.recursive), args=args, kwargs=kwargs) return new_call
def visit_Call(self, node): full_name = str(anno.getanno(node.func, anno.Basic.QN, default='')) function_context_name = self.state[_Function].context_name node = self.generic_visit(node) # TODO(mdan): Refactor converted_call as a 'Call' operator. # Calls to the internal 'ag__' module are never converted (though their # arguments might be). if full_name.startswith('ag__.'): return node # Calls to the function context manager (inserted by function_scopes) are # also safe. if full_name.startswith(function_context_name + '.'): return node # Calls to pdb.set_trace or ipdb.set_trace are never converted. We don't use # the normal mechanisms to bypass these literals because they are sensitive # to the frame they are being called from. # TODO(mdan): Generalize this to a "static whitelist" config. if full_name in ('pdb.set_trace', 'ipdb.set_trace', 'breakpoint'): global set_trace_warned if not set_trace_warned: # TODO(mdan): Update and shorten once available on tensorflow.org. ag_logging.warn( 'Detected `pdb.set_trace()` in converted code. The code' ' generated by AutoGraph is not optimized for step-by-step' ' debugging. See https://github.com/tensorflow/tensorflow/' 'blob/master/tensorflow/python/autograph/g3doc/reference/' 'debugging.md.') set_trace_warned = True return node if (full_name == 'print' and not self.ctx.program.options.uses( converter.Feature.BUILTIN_FUNCTIONS)): return node func = node.func starred_arg = None normal_args = [] for a in node.args: if isinstance(a, gast.Starred): assert starred_arg is None, 'Multiple *args should be impossible.' starred_arg = a else: normal_args.append(a) if starred_arg is None: args = templates.replace_as_expression('(args,)', args=normal_args) else: args = templates.replace_as_expression('(args,) + tuple(stararg)', stararg=starred_arg.value, args=normal_args) kwargs_arg = None normal_keywords = [] for k in node.keywords: if k.arg is None: assert kwargs_arg is None, 'Multiple **kwargs should be impossible.' kwargs_arg = k else: normal_keywords.append(k) if kwargs_arg is None: if not normal_keywords: kwargs = parser.parse_expression('None') else: kwargs = ast_util.keywords_to_dict(normal_keywords) else: kwargs = templates.replace_as_expression( 'dict(kwargs, **keywords)', kwargs=kwargs_arg.value, keywords=ast_util.keywords_to_dict(normal_keywords)) template = """ ag__.converted_call(func, options, args, kwargs, function_ctx) """ new_call = templates.replace_as_expression( template, func=func, options=parser.parse_expression(function_context_name + '.callopts'), args=args, kwargs=kwargs, function_ctx=function_context_name) return new_call
def visit_Call(self, node): # TODO(mdan): Refactor converted_call as a 'Call' operator. # Calls to the internal 'ag__' module are never converted (though their # arguments might be). full_name = str(anno.getanno(node.func, anno.Basic.QN, default='')) if full_name.startswith('ag__.'): return self.generic_visit(node) if (full_name == 'print' and not self.ctx.program.options.uses(converter.Feature.BUILTIN_FUNCTIONS)): return self.generic_visit(node) if isinstance(node.func, gast.Attribute): func = gast.Str(node.func.attr) owner = node.func.value else: func = node.func owner = parser.parse_expression('None') starred_arg = None normal_args = [] for a in node.args: if isinstance(a, gast.Starred): assert starred_arg is None, 'Multiple *args should be impossible.' starred_arg = a else: a = self.visit(a) normal_args.append(a) if starred_arg is None: args = templates.replace_as_expression('(args,)', args=normal_args) else: args = templates.replace_as_expression( '(args,) + tuple(stararg)', stararg=starred_arg.value, args=normal_args) kwargs_arg = None normal_keywords = [] for k in node.keywords: if k.arg is None: assert kwargs_arg is None, 'Multiple **kwargs should be impossible.' kwargs_arg = k else: k = self.visit(k) normal_keywords.append(k) if kwargs_arg is None: kwargs = ast_util.keywords_to_dict(normal_keywords) else: kwargs = templates.replace_as_expression( 'dict(kwargs, **keywords)', kwargs=kwargs_arg.value, keywords=ast_util.keywords_to_dict(normal_keywords)) template = """ ag__.converted_call(func, owner, options, args, kwargs) """ new_call = templates.replace_as_expression( template, func=func, owner=owner, options=self.ctx.program.options.to_ast( internal_convert_user_code=self.ctx.program.options.recursive), args=args, kwargs=kwargs) return new_call