title: How do I override a Python import?
body: <p>I'm working on <a href="http://code.google.com/p/pypreprocessor/" rel="noreferrer">pypreprocessor</a> which is a preprocessor that takes c-style directives and I've been able to make it work like a traditional preprocessor (it's self-consuming and executes postprocessed code on-the-fly) except that it breaks library imports.</p>
  
  <p>The problem is: The preprocessor runs through the file, processes it, outputs to a temporary file, and exec() the temporary file. Libraries that are imported need to be handled a little different, because they aren't executed, but rather they are loaded and made accessible to the caller module.</p>
  
  <p>What I need to be able to do is: Interrupt the import (since the preprocessor is being run in the middle of the import), load the postprocessed code as a tempModule, and replace the original import with the tempModule to trick the calling script with the import into believing that the tempModule is the original module.</p>
  
  <p>I have searched everywhere and so far and have no solution.</p>
  
  <p>This Stack Overflow question is the closest I've seen so far to providing an answer:
  <a href="https://stackoverflow.com/questions/1096216/override-namespace-in-python">Override namespace in Python</a></p>
  
  <p>Here's what I have.</p>
  
  <pre><code># Remove the bytecode file created by the first import
  os.remove(moduleName + '.pyc')
  
  # Remove the first import
  del sys.modules[moduleName]
  
  # Import the postprocessed module
  tmpModule = __import__(tmpModuleName)
  
  # Set first module's reference to point to the preprocessed module
  sys.modules[moduleName] = tmpModule
  </code></pre>
  
  <p>moduleName is the name of the original module, and tmpModuleName is the name of the postprocessed code file.</p>
  
  <p>The strange part is this solution still runs completely normal as if the first module completed loaded normally; unless you remove the last line, then you get a module not found error.</p>
  
  <p>Hopefully someone on Stack&nbsp;Overflow know a lot more about imports than I do, because this one has me stumped.</p>
  
  <p><strong>Note: I will only award a solution, or, if this is not possible in Python; the best, most detailed explanation of why this is not impossible.</strong></p>
  
  <p><strong>Update: For anybody who is interested, here is the working code.</strong></p>
  
  <pre><code>if imp.lock_held() is True:
      del sys.modules[moduleName]
      sys.modules[tmpModuleName] = __import__(tmpModuleName)
      sys.modules[moduleName] = __import__(tmpModuleName)
  </code></pre>
  
  <p>The 'imp.lock_held' part detects whether the module is being loaded as a library. The following lines do the rest.</p>