[Python-Dev] Choosing a best practice solution for Python/extension modules

glyph at divmod.com glyph at divmod.com
Sat Feb 21 20:43:31 CET 2009


On 07:07 pm, brett at python.org wrote:
>On Sat, Feb 21, 2009 at 09:17, Jean-Paul Calderone 
><exarkun at divmod.com>wrote:

>>>But there is another issue with this: the pure Python code will never 
>>>call
>>>the extension code because the globals will be bound to _pypickle and 
>>>not
>>>_pickle. So if you have something like::

>>>  # _pypickle
>>>  def A(): return _B()
>>>  def _B(): return -13

>>>  # _pickle
>>>  def _B(): return 42

>>>  # pickle
>>>  from _pypickle import *
>>>  try: from _pickle import *
>>>  except ImportError: pass

>>This is really the same as any other high-level/low-level
>>library split.  It doesn't matter that in this case, one
>>low-level implementation is provided as an extension module.
>>Importing the low-level APIs from another module and then
>>using them to implement high-level APIs is a pretty common,
>>simple, well-understood technique which is quite applicable
>>here.

>But that doesn't provide a clear way, short of screwing with 
>sys.modules, to
>get at just the pure Python implementation for testing when the 
>extensions
>are also present. The key point in trying to figure this out is to
>facilitate testing since the standard library already uses the import *
>trick in a couple of places.

You don't have to screw with sys.modules.  The way I would deal with 
testing this particular interaction would be a setUp that replaces 
pickle._A with _pypickle._A, and a tearDown that restores the original 
one.

Twisted's TestCase has specific support for this.  You would spell it 
like this:

    import _pypickle
    # ...
    testCase.patch(pickle, '_A', _pypickle._A)

You can read more about this method here:

http://python.net/crew/mwh/apidocs/twisted.trial.unittest.TestCase.html#patch


More information about the Python-Dev mailing list