4

I have been told that doing this would be a not-very-good practice (it is present in the main answer of Python pattern for sharing configuration throughout application though):

configfile.py

SOUNDENABLED = 1
FILEPATH = 'D:\\TEMP\\hello.txt'

main.py

import configfile

if configfile.SOUNDENABLED == 1:
    ....

f = open(configfile.FILEPATH, 'a')
...

This is confirmed by the fact that many people use INI files for local configuration with ConfigParser module or iniparse or other similar modules.

Question: Why would using an INI file for local configuration + an INI parser Python module be better than just importing a configfile.py file containing the right config values as constants?

Basj
  • 41,386
  • 99
  • 383
  • 673

4 Answers4

5

The only concern here is that a .py can have arbitrary Python code, so it has a potential to break your program in arbitrary ways.

If you can trust your users to use it responsibly, there's nothing wrong with this setup. If fact, at one of my previous occupations, we were doing just that, without any problems that I'm aware of. Just on the contrary: it allowed users to eliminate duplication by autogenerating repetitive parts and importing other config files.

Another concern is if you have many files, the configuration ones are better be separated from regular code ones, so users know which files they are supposed to be able to edit (the above link addresses this, too).

Community
  • 1
  • 1
ivan_pozdeev
  • 33,874
  • 19
  • 107
  • 152
3

Importing a module executes any code that it contains. Nothing restricts your configfile.py to containing only definitions. Down the line, this is a recipe for security concerns and obscure errors. Also, you are bound to Python's module search path for finding the configuration file. What if you want to place the configuration file somewhere else, or if there is a name conflict?

alexis
  • 48,685
  • 16
  • 101
  • 161
  • Thanks. I don't remember, isn't there no way to import a module from a specific location, like `/boot/config.py` ? (e.g. on rapsberry pi) – Basj Dec 02 '16 at 11:15
  • Yeah there is, [using importlib](http://stackoverflow.com/q/67631/699305) for example. But it's not nearly as straightforward as `import `, or as `open()` for that matter. – alexis Dec 02 '16 at 13:01
2

This is a perfectly acceptable practice. Some examples of well-known projects using this method are Django and gunicorn.

Daniel Roseman
  • 588,541
  • 66
  • 880
  • 895
  • Thanks. Can you add some links to the relevant files on github for future reference, so we can see that it's an acceptable practice? – Basj Dec 02 '16 at 11:11
  • I've linked to the docs, both of which explicitly state the settings is a normal Python file. – Daniel Roseman Dec 02 '16 at 11:12
  • 1
    Thanks. How do they do to be able to 1) import the relevant config .py file from another directory? 2) be sure that the file isn't deleted when you deploy a new version of Django? – Basj Dec 02 '16 at 11:14
  • I don't understand what you mean. The settings go in your own project, not in the third-party library; they allow you to define the way you want the app to be configured. – Daniel Roseman Dec 02 '16 at 11:17
  • As a side note django users don't import the settings file directly. Instead they import django.conf.settings, which imports the users settings file, and builds a proxy object around it, allowing, among other things, the definition of defaults values, without those defaults having to be defined in the settings file, or otherwise imported by the users settings file. https://github.com/django/django/blob/master/django/conf/__init__.py – Trevor Ian Peacock Dec 02 '16 at 12:03
1

It could be better for some reasons

  1. The only extension that config file could have is py.
  2. You cannot distribute your program with configs in separate directory unless you put an __init__.py into this directory
  3. Nasty users of your program can put any python script in config and do bad things.

For example, the YouCompleteMe autocompletion engine stores config in python module, .ycm_extra_conf.py. By default, each time config is imported, it asks you, whether you sure that the file is safe to be executed.

  1. How would you change configuration without restarting your app?

Generally, allowing execution of code that came from somewhere outside is a vulnerability, that could lead to very serious consequences.

However, if you don't care about these, for example, you are developing web application that executes only on your server, this is an acceptable practice to put configuration into python module. Django does so.

Anton K
  • 670
  • 6
  • 19
  • Thanks. I don't really agree with 3. : Python is interpreted, so this means that you have access to all source files. Then if a nasty user wants to put malicious code, he doesn't need to put it in `configfile.py`, he can do it in `main.py`, don't you think so? – Basj Dec 02 '16 at 11:09
  • @Basj what if config file is loaded from somewhere else, e.g. remote filesystem which you don't really trust? – Anton K Dec 02 '16 at 11:15