2

Is there a way (preferably using the ast module) to know if a function has a required number of arguments?

For example, if a user interface allows a user to insert a python expression for example "sum(x)" but the user has mistakenly typed "sum()" is there a way to validate that expression before runtime?

I have called ast.dump on every node in the symbol tree but the information on these symbols seems insufficient for this kind of analysis?

For example:

#own debug code added to ast.py
def visit(self, node):
  print(dump(node),True, False)
  method = 'visit_' + node.__class__.__name__
  visitor = getattr(self, method, self.generic_visit)
  return visitor(node)  

yields:

'Module(body=[Expr(value=Call(func=Attribute(value=Name(id='Math', ctx=Load()),
 attr='cos', ctx=Load()), args=[Num(n=0.5)], 
 keywords=[], starargs=None, kwargs=None))])'

Which doesn't really differ from a function like print() which does not require a specific number of arguments.

8
  • 2
    You'd have to resolve the object being called and analyse that. Python doesn't know this either until you actually execute the call. Commented Sep 26, 2014 at 15:03
  • How do you define "required argument" for a Python function? Where is this defined? Commented Sep 26, 2014 at 15:03
  • 2
    I'd refrain from naming your module ast.py. Commented Sep 26, 2014 at 15:04
  • @Tichodroma: positional arguments on the callable object, presumably. But the AST of the call expression won't show this because that isn't known until you actually run the code. Commented Sep 26, 2014 at 15:09
  • @Tichodroma I'm trying to think of a way to pre-empt 'TypeError: sum expected at least 1 arguments, got 0' at runtime. I'm actually not sure how this is defined for the sum() built-in function Commented Sep 26, 2014 at 15:12

1 Answer 1

1

You cannot see from a call expression what arguments the callable expects. Python leaves this entirely to the callable at runtime.

For static code analysis your only option is to resolve the callable (hoping that it is not too dynamic in nature, e.g. will change at the runtime), and for C-defined objects have your own database of signatures. This is the route the Komodo CodeIntel library takes (OSS, used in other projects such as SublimeCodeIntel). C-based extensions are supported with CIX files, which essentially contain callable signatures.

At runtime, you can use inspect.signature() to introspect call signatures. C functions are only partially supported at the moment, only those that use the Argument Clinic have signature info stored, see What are __signature__ and __text_signature__ used for in Python 3.4

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.