0

I am developing a Python package which, on first use, creates a config file for the user. During this setup phase, the user is asked for input during two prompts. Corresponding calls are in the module's __init__.py. Because of this prompt, my builds on readthedocs fail (log).

How can I build my documentation nonetheles? Why is readthedocs trying to compile the code anyways?

MERose
  • 4,048
  • 7
  • 53
  • 79
  • 1
    Your library should simply never ever trigger any sort of user interaction simply by the fact of it being imported…!? – deceze Oct 07 '18 at 15:28
  • It's part of the setup up routine and only necessary the first time. The user needs to add some credentials, otherwise it can't be used in any meaningful way. How else would you solve the problem? – MERose Oct 07 '18 at 18:52
  • Your library should output a warning message about a missing config (and *maybe* ask for input, but that's probably impractical most of the time) and probably raise an exception, **when your main class is instantiated/main function is called**; not when you simply `import` the module. – deceze Oct 07 '18 at 19:09
  • You're probably right, I implemented a method the user needs to call and warning on import. For technical reasons it's important to have this warning as soon as possible. – MERose Oct 08 '18 at 13:33

1 Answers1

1

The problem is you are importing your module in conf.py:

project_root = os.path.dirname(cwd)
sys.path.insert(0, project_root)

import scopus  # <-- imported

# General configuration
needs_sphinx = '1.3'
extensions = [

And your project is not constrcuted well. I don't think just importing your module will cause prompt is a good idea.

import scopus  ->  
from scopus.utils import *  ->  
from scopus.utils.startup import *  ->    
....
if 'Authentication' not in config.sections():
    set_authentication(config, CONFIG_FILE)  # <-- cause prompt
....

Addtionally, even worse:

CONFIG_FILE = os.path.expanduser("~/.scopus/config.ini")
config = configparser.ConfigParser()
config.optionxform = str
config.read(CONFIG_FILE)

Reading file system.

Sraw
  • 18,892
  • 11
  • 54
  • 87
  • Hi @sraw, thanks for the feedback. Do I understand correctly that I must not import the module in `conf.py`? As for the rest: The module needs to have some user input to save their API Key. How would you solve the problem? – MERose Oct 07 '18 at 18:51
  • First, you definitely can import the module in `conf.py` as long as you keep your top `__init__.py` clean. Second, you can wrap the startup into a function which user will call. Somehow like `logging.basicConfig()`. – Sraw Oct 07 '18 at 18:57
  • Thanks, I'll consider that! And to the third point, why is it even worse to read the file system? That's where a lot of settings are stored. – MERose Oct 07 '18 at 19:41
  • Because you are reading the file system when user is importing this module. That force user to prepare everything before just importing your module(They haven't started to use it!). You should provide some function which allows user to load config. For example `load_config(file=None)`, and load default config by `load_config()`. – Sraw Oct 07 '18 at 19:53
  • Based on your and @deceze's comments I changed the structure of the project such that the user is not prompted on import. Thanks for the guidance! – MERose Oct 08 '18 at 13:34