0

I have a function:

def report(start=1, quantity=100, days_left=7, min_app_version=None):

I want to get argument names and default values, something like

{'start':1, 'quantity':100, 'days_left':7, 'min_app_version':None}

(or at least two lists) from outside this function

when I do

import inspect
print(inspect.signature(report))

I get

(*args, **kwargs)

Why doesn't 'inspect.signature' see function arguments?

SOLVED: THE PROBLEM WAS BECAUSE OF A DECORATOR

dimkor
  • 71
  • 1
  • 7
  • 2
    Seems to [work fine](https://ideone.com/NuYSRH) for me. – Cory Kramer Jul 09 '18 at 15:26
  • 3
    I have Python 3.6 installed and works ok: the signature printed is `(start=1, quantity=100, days_left=7, min_app_version=None)` – Andrej Kesely Jul 09 '18 at 15:26
  • 1
    Does `report` have any annotations or modified dynamically in any way? What does `inspect.getfullargspec(report)` show? – FHTMitchell Jul 09 '18 at 15:28
  • @FHTMitchell it shows: FullArgSpec(args=[], varargs='args', varkw='kwargs', defaults=None, kwonlyargs=[], kwonlydefaults=None, annotations={}) – dimkor Jul 09 '18 at 15:32
  • 1
    Great, glad you found a solution. You should post an answer to your own question (and show the code with the decorator). – FHTMitchell Jul 09 '18 at 15:34

2 Answers2

5

Even better than removing the decorator, you can tell the decorator to make the function wrapper look like the wrapped function to inspection tools using functools.wraps

Instead of

def decorator(f):
    def wrapper(*args, **kwargs):
        print("Wrapped")
        return f(*args, **kwargs)
    return wrapper

@decorator
def report(start=1, quantity=100, days_left=7, min_app_version=None):
    pass

print(inspect.signature(report))
# (*args, **kwargs)

You can do

from functools import wraps

def decorator(f):
    @wraps(f)
    def wrapper(*args, **kwargs):
        print("Wrapped")
        return f(*args, **kwargs)
    return wrapper

@decorator
def report(start=1, quantity=100, days_left=7, min_app_version=None):
    pass

print(inspect.signature(report))
# (start=1, quantity=100, days_left=7, min_app_version=None)
Patrick Haugh
  • 59,226
  • 13
  • 88
  • 96
2

If anyone ever get stuck with this error, just delete the function decorator.

@time_count
def report(start=1, quantity=100, days_left=7, min_app_version=None):

You can also help yourself with: How to strip decorators from a function in Python

dimkor
  • 71
  • 1
  • 7