Comment by saila

Comment by saila 9 days ago

4 replies

The call to logging.basicConfig happens at import time, which could cause issues in certain scenarios. For a one-off script, it's probably fine, but for a production app, you'd probably want to set up logging during app startup from whatever your main entry point is.

The Python standard library has a configparser module, which should be used instead of custom code. It's safer and easier than manual parsing. The standard library also has a tomllib module, which would be an even better option IMO.

cinntaile 8 days ago

Regarding your first paragraph, we still don't understand what the issue actually is.

  • necovek 7 days ago

    Logging configuration is done at import time for "utils" module.

    Imagine code like this:

    main.py:

      import logging
      logging.basicConfig(...)
    
      logging.info("foo") # uses above config
      
      if __name__ == "__main__":
          import utils # your config is overridden with the one in utils
          logging.info("bar") # uses utils configuration
          ...
    
    Or two "commands", one importing utils and another not: they would non-obviously use different logging configuration.

    It gets even crazier: you could import utils to set the configuration, override it, but a second import would not re-set it, as module imports are cached.

    Basically, don't do it and no unexpected, confusing behaviour anywhere.

    • bumblehean 7 days ago

      As a non Python developer, what would be the use-case(s) for importing a module inside of the main function instead of importing it at the top of main.py with the others?

      • necovek 7 days ago

        Since the entire evaluation and running is dynamic, you don't need to import (and thus evaluate) a module in certain branches.

        Eg. that `if __name__` trick is used to allow a module to be both a runnable script and importable module.

        Top it off with plenty of common libraries being dog-slow to import because they are doing some of the anti-pattern stuff too, and you end up executing a lot of code when you just want to import a single module.

        Eg. I've seen large Python projects that take 75s just importing all the modules because they are listing imports at the top, and many are executing code during import — imagine wanting to run a simple unit test, and your test runner takes 75s just to get to the point where it can run that 0.01s test for your "quick" TDD iteration.

        You can also look at Instagram's approach to solving this over at their engineering blog.