Disallow functions from being executed as default parameters of others funcs or allow them to be executed at runtime for clarity

Functions that declare functions in default arguments always execute the function at the first run time.

This is confusing and results in extra code.

Maybe I’m too lazy.

I made a small botnet with different consoles and processes that are accessed through a private local network for my work. Each worker has its own dynamic console based on the custom thread name. I noticed that the printouts were always thread 0 at the beginning.

Example:

Thread name = ‘pepe’

def server_print(message, threadname = threading.current_thread().name):
    print(threadname + message)

Example result:
MainThread 0 + message

Expected result:
Pepe + message

I am aware that it may be poorly stated, but perhaps it is good to consider whether it is valid to allow the execution of functions as default arguments.

This isn’t backwards compatible, as it would prevent e.g. a frozenset to be used as default value:

def foo(bar=frozenset()):
    ...
3 Likes

This sounds like the same idea as Dynamic evaluation of function argument list initializer just a few threads down, which itself is the same idea as many deferred evaluation ideas that were proposed before.

1 Like

I think the best way to avoid a problem like this is to use a linter that will point out the problem in your editor.

3 Likes

As is mentioned by @sirosen in this post, pylint and flake8-bugbear provides the tool to check for these conditions and provide you a warning in your code editor (I haven’t tried them yet, but it should draw a wavy yellow line in VSCode when the conditions you configured are met).

This is not exactly the same as you requested (disallow), but should work for your use case.

1 Like
def better(arg: list[int] | None = None) -> list[int]:
    if arg is None:
        arg = create_list()

    arg.append(4)
    return arg

Exactly, I ended up doing something like what you show.