0

Why are default arguments in function signatures executed when loading a module? Example test.py:

import os


def environment_key(key=os.environ["MY_ENV_KEY"]):
    print(key)

When I load on the test.py on cmd line python -m test.py I get following error:

bash-4.2# python -m test.py
Traceback (most recent call last):
  File "/usr/lib64/python2.7/runpy.py", line 163, in _run_module_as_main
    mod_name, _Error)
  File "/usr/lib64/python2.7/runpy.py", line 102, in _get_module_details
    loader = get_loader(mod_name)
  File "/usr/lib64/python2.7/pkgutil.py", line 462, in get_loader
    return find_loader(fullname)
  File "/usr/lib64/python2.7/pkgutil.py", line 472, in find_loader
    for importer in iter_importers(fullname):
  File "/usr/lib64/python2.7/pkgutil.py", line 428, in iter_importers
    __import__(pkg)
  File "test.py", line 4, in <module>
    def environment_key(key=os.environ["MY_ENV_KEY"]):
  File "/usr/lib64/python2.7/UserDict.py", line 40, in __getitem__
    raise KeyError(key)
KeyError: 'MY_ENV_KEY'

I far as i can imagine, Python tries to initialise the default arguments at module load time. Can i prevent (lazy load) this behavior?

Thx

dvonessen
  • 177
  • 1
  • 8
  • 1
    While the duplicated question warns about using mutable default argument which is not the case here (strings are immutable), what you should take away from the duplicated question is that default arguments are evaluated only once, at the function definition time. – DeepSpace Mar 04 '21 at 12:03
  • 1
    https://stackoverflow.com/a/11416002/476 – deceze Mar 04 '21 at 12:03
  • In this particular case, `os.environ` shouldn't change at runtime, so if it doesn't exist at definition time, it also won't exist at call time, so "lazy loading" isn't really the solution. Perhaps you want `key=os.environ.get("MY_ENV_KEY")`? The default value will remain `None` then, but that's as good as it's going to get anyway. – deceze Mar 04 '21 at 12:06
  • Thank you for your clarification. @all deceze Yes you are right, but no one prevents me to modify the environ dict to add keys to it. It is not a good practice but sometimes I use this to test my modules. Think of it like getting arbitrary environment keys but if none is given return MY_ENV_KEY and assume that this key is in all execution environments present but in the pytest environment not. That makes the problem to import the module. – dvonessen Mar 04 '21 at 12:18

0 Answers0