В Python достаточно часто интерфейсы функций частично или полностью "сворачивают" с помощью *args и **kwargs. Это вполне естественно для питонистов, но вызывает вопросы, при переходе с других языков. С самим "сворачиванием" никаких проблем нет. Сложности возникают при модификации аргументов: строятся проверки вокруг args и kwargs, вместо того, что бы "развернуть" интерфейс функции.

Представьте себе такой кейс: Есть две библиотеки, одна из которых имеет полностью прописанный интерфейс у функции foo. Вторая определяет функцию boo, которая вызывает foo. Интерфейс boo "свернут" с помощью *args и **kwargs.

def foo(arg1=None, arg2=None):
    pass

def boo(*args, **kwargs):
    foo(*args, **kwargs)

В коде проекта есть функция do_magic, которая использует boo.

def do_magic(*args, **kwargs):
    boo(*args, **kwargs)

Задача такая: если arg1 в do_magic прилетает со значением по умолчанию, то дальше его нужно отправить со значением True.

Первый вариант решения такой: arg1 может быть либо первым элементом в args, либо быть в kwargs. Значит можно добавить в функцию соответствующую проверку:

def do_magic(*args, **kwargs):
    if 'arg1' not in kwargs and len(args) == 0:
        kwargs['arg1'] = True
    boo(*args, **kwargs)

Работу мы свою выполнили. Мы учли, что arg1 может быть передан как именованный параметр, так и как не именованный параметр. Функция работает как надо. Но есть путь проще, элегантнее и с меньшим количеством кода.

def do_magic(arg1=True, *args, **kwargs):
    boo(arg1=arg1, *args, **kwargs)


c