1

I would like to find out disadvantages of using exec for imports. One of the files serves as interface towards real implementations of specific functionalities depending on chosen project (framework is intended to work on several projects).

First use-case goes like this:

exec ("from API.%s.specific_API_%s import *" % (project, project))

This way I don't have to hard code anything except the variable project which is injected in the interface-module itself.

This is the other way:

if project == 'project_one':
    from API.project_one.specific_API_project_one import *
elif project == 'project_two':
    from API.project_two.specific_API_project_two import *
elif project == 'project_three':
    from API.project_three.specific_API_project_three import *

This way I have to alter this interface-file each time new project is added to be supported.

khelwood
  • 55,782
  • 14
  • 81
  • 108
Sir DrinksCoffeeALot
  • 593
  • 2
  • 11
  • 20
  • A possible third way would be to use `importlib.import_module` which takes a string argument to do the importing. This is probably better than using `exec` – AbrahamCoding Feb 12 '19 at 08:58

1 Answers1

3
  1. If you need programmatic way to import modules, please use importlib or __import__ (for really specific cases). Reasons — don't re-invent the wheel, there's way to do what you want without exec. If your project variable coming from outer world, exec is a huge security issue.
  2. Wildcard imports considered bad practice — it makes harder to maintain your codebase afterwards.

Oversimplified example of issues with exec by executing arbitrary code:

module = 'request'
func = 'urlopen'
exec("from urllib.%s import %s" % (module, func))

func = 'urlopen; print("hello python")'
exec("from urllib.%s import %s" % (module, func))

yes, your example is harder to forge, but problem stays — giving python arbitrary code to execute is overkill (with potential security gap), when you have tool built exactly for your purpose — programatically importing modules.

Slam
  • 8,112
  • 1
  • 36
  • 44