4

I have a simple function

import config 

def send_message(mailgunkey=config.MAILGUNKEY):
    """
    send an email
    """

It relies on a variable defined in my config.py file. I read the variables from local files on all my machines as I don't want to have my keys etc. in any repository. However, I recently got into the habit of using Sphinx. When generating the html docs the expression config.MAILGUNKEY is getting evaluated and the actual key is revealed in the html file. Is there an option to stop this kind of undesired action?

mzjn
  • 48,958
  • 13
  • 128
  • 248
tschm
  • 2,905
  • 6
  • 33
  • 45
  • 2
    You can't configure Sphinx to avoid this, by the way; it imports the code to generate the docs, at which time the argument default value is simply a string. – jonrsharpe Jan 15 '16 at 11:15
  • 2
    Related: http://stackoverflow.com/q/12082570/407651 – mzjn Jan 15 '16 at 11:50

3 Answers3

3

Consider using this approach:

import config 

def send_message(mailgunkey=None):
    """
    send an email
    """
    if mailgunkey is None:
        mailgunkey = config.MAILGUNKEY

In general, this approach gives you some important advantages:

  • lets your users pass None as the default;
  • allows changes to config.MAILGUNKEY even if your module has already been imported;
  • solves the problem of mutable default arguments (not your case, but still it's something to be aware of).

The second point is, in my opinion, something very important, as I would be very surprised to see that changes to a configuration variable at runtime have no effects.

Andrea Corbellini
  • 17,339
  • 3
  • 53
  • 69
  • Ok, it certainly solves my problem. Many thanks. However, I kind of dislike such features in Python. I very much prefer immutable arguments. Essentially I have to explain in my comment that the program is falling back to a value stored in home directory of the user in a file called xyz.cfg. Of course, I guess I could avoid such tricks by deleting the =None and force the user to specify a key everytime he is calling send_message (or define a partial function to simplify his/her life) – tschm Jan 15 '16 at 12:34
1

Another option would be to mock the module that has your secrets.

This avoids needing to change your code to generate documentation.

Assuming you are using autodoc; add the below to your conf.py:

autodoc_mock_imports = ["config","secrets",] 

https://www.sphinx-doc.org/en/master/usage/extensions/autodoc.html?highlight=autodoc_mock_imports%20#confval-autodoc_mock_imports

Jos Verlinde
  • 1,468
  • 12
  • 25
0

The autodoc_preserve_defaults configuration option was added in Sphinx 4.0.

The problem is solved by setting this option to True in conf.py. Default argument values of functions will not be evaluated and shown in the generated output.

mzjn
  • 48,958
  • 13
  • 128
  • 248