<br><br><div class="gmail_quote">On Sat, Feb 21, 2009 at 09:17, Jean-Paul Calderone <span dir="ltr"><<a href="mailto:exarkun@divmod.com">exarkun@divmod.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
<div><div></div><div class="Wj3C7c">On Fri, 20 Feb 2009 13:45:26 -0800, Brett Cannon <<a href="mailto:brett@python.org" target="_blank">brett@python.org</a>> wrote:<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Fri, Feb 20, 2009 at 12:53, Aahz <<a href="mailto:aahz@pythoncraft.com" target="_blank">aahz@pythoncraft.com</a>> wrote:<br>
<br>
<blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">
On Fri, Feb 20, 2009, Brett Cannon wrote:<br>
> On Fri, Feb 20, 2009 at 12:37, Brett Cannon <<a href="mailto:brett@python.org" target="_blank">brett@python.org</a>> wrote:<br>
>> On Fri, Feb 20, 2009 at 12:31, Daniel Stutzbach <<br>
>> <a href="mailto:daniel@stutzbachenterprises.com" target="_blank">daniel@stutzbachenterprises.com</a>> wrote:<br>
>>><br>
>>> A slight change would make it work for modules where only key functions<br>
>>> have been rewritten. For example, pickle.py could read:<br>
>>><br>
>>> from _pypickle import *<br>
>>> try: from _pickle import *<br>
>>> except ImportError: pass<br>
>><br>
>> True, although that still suffers from the problem of overwriting things<br>
>> like __name__, __file__, etc.<br>
><br>
> Actually, I take that back; the IMPORT_STAR opcode doesn't pull in<br>
anything<br>
> starting with an underscore. So while this alleviates the worry above, it<br>
> does mean that anything that gets rewritten needs to have a name that<br>
does<br>
> not lead with an underscore for this to work. Is that really an<br>
acceptable<br>
> compromise for a simple solution like this?<br>
<br>
Doesn't __all__ control this?<br>
</blockquote>
<br>
<br>
If you define it, yes.<br>
<br>
But there is another issue with this: the pure Python code will never call<br>
the extension code because the globals will be bound to _pypickle and not<br>
_pickle. So if you have something like::<br>
<br>
# _pypickle<br>
def A(): return _B()<br>
def _B(): return -13<br>
<br>
# _pickle<br>
def _B(): return 42<br>
<br>
# pickle<br>
from _pypickle import *<br>
try: from _pickle import *<br>
except ImportError: pass<br>
<br>
If you import pickle and call pickle.A() you will get -13 which is not what<br>
you are after.<br>
</blockquote>
<br></div></div>
If pickle and _pypickle are both Python modules, and _pypickle.A is intended<br>
to be used all the time, regardless of whether _pickle is available, then<br>
there's not really any reason to implement A in _pypickle. Just implement it<br>
in pickle. Then import whatever optionally fast thing it depends on from<br>
_pickle, if possible, and fall-back to the less fast thing in _pypickle<br>
otherwise.<br>
<br>
This is really the same as any other high-level/low-level library split. It<br>
doesn't matter that in this case, one low-level implementation is provided as<br>
an extension module. Importing the low-level APIs from another module and<br>
then using them to implement high-level APIs is a pretty common, simple,<br>
well-understood technique which is quite applicable here.<font color="#888888"></font></blockquote><div><br>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.<br>
<br>-Brett <br></div></div><br>