title: What's Python good practice for importing and offering optional features?
body: <p>I'm writing a piece of software over on github. It's basically a tray icon with some extra features. I want to provide a working piece of code without actually having to make the user install what are essentially dependencies for optional features and I don't actually want to import things I'm not going to use so I thought code like this would be "good solution":</p>
  
  <pre><code>---- IN LOADING FUNCTION ----
  features = []
  
  for path in sys.path:
         if os.path.exists(os.path.join(path, 'pynotify')):
                features.append('pynotify')
         if os.path.exists(os.path.join(path, 'gnomekeyring.so')):
                features.append('gnome-keyring')
  
  #user dialog to ask for stuff
  #notifications available, do you want them enabled?
  dlg = ConfigDialog(features)
  
  if not dlg.get_notifications():
      features.remove('pynotify')
  
  
  service_start(features ...)
  
  ---- SOMEWHERE ELSE ------
  
  def service_start(features, other_config):
  
          if 'pynotify' in features:
                 import pynotify
                 #use pynotify...
  </code></pre>
  
  <p>There are some issues however. If a user formats his machine and installs the newest version of his OS and redeploys this application, features suddenly disappear without warning. The solution is to present this on the configuration window:</p>
  
  <pre><code>if 'pynotify' in features:
      #gtk checkbox
  else:
      #gtk label reading "Get pynotify and enjoy notification pop ups!"
  </code></pre>
  
  <p>But if this is say, a mac, how do I know I'm not sending the user on a wild goose chase looking for a dependency they can never fill?</p>
  
  <p>The second problem is the:</p>
  
  <pre><code>if os.path.exists(os.path.join(path, 'gnomekeyring.so')):
  </code></pre>
  
  <p>issue. Can I be sure that the file is always called gnomekeyring.so across all the linux distros?</p>
  
  <p>How do other people test these features? The problem with the basic</p>
  
  <pre><code>try:
      import pynotify
  except:
      pynotify = disabled
  </code></pre>
  
  <p>is that the code is global, these might be littered around and even if the user doesn't want pynotify....it's loaded anyway.</p>
  
  <p>So what do people think is the best way to solve this problem?</p>