Am 29.05.2010 21:06, schrieb P.J. Eby:
> At 08:45 PM 5/29/2010 +0200, Martin v. Löwis wrote:
>>> In it he says that PEP 382 is being deferred until it can address PEP
>>> 302 loaders. I can't find any follow-up to this. I don't see any
>>> discussion in PEP 382 about PEP 302 loaders, so I assume this issue was
>>> never resolved. Does it need to be before PEP 382 is implemented? Are we
>>> wasting our time by designing and (eventually) coding before this issue
>>> is resolved?
>> Yes, and yes.
> Is there anything we can do to help regarding that?
You could comment on the proposal I made back then, or propose a
At 09:24 AM 5/31/2010 +0200, Martin v. Löwis wrote:
>Is this really how it works today? Shouldn't it abort here
>if there is an ImportError?
Oops. You're right - I was confusing find_module with the path_hooks
> > else:
> > # errors here should propagate
> > module = loader.load_module(fullname)
> > if not hasattr(module, '__path__'):
> > # found, but not a package
> > return module
> > pc = get_pth_contents(importer)
>Assuming we always get here with a loader, I'd rather call this
>on the loader.
We don't, unless the finder natively supports PEP 382.
I had the strong impression that there was a policy that x.y.z bugfix
releases should only fix bugs and not add new features and revise
current ones. The rationale, as I understood it, is that x.y.z releases
should be increasingly better implementations of a stable x.y feature
set. Adding features is 'bad' because code using a new feature will not
work in previous releases of the same x.y version. Changing features is
even worse because it may also break working code going forward.
Because of this policy, an x.y.z Windows installer (I do not know about
others) deletes any earlier release of the same version. Also, there is
no What's New in Python x.y.z (relative to x.y.(z-1) since such should
be empty. Consequently, violations of the policy are pretty much silent
and well hidden.
Yesterday, I spent two hours puzzling over the failure of my previously
'green' test sequence that tested a custom test function. I finally
realized that the change was not due to anything I did (or undid), but a
change in 3.1.2 in the interaction of StringIO.truncate,
StringIO.getvalue, and print(x, StringIO()). (I should note the it is
the usual stability and quality of Python that made me slow to blame
Python rather than myself.)
I was rather shocked to be told that the code-breaking and
policy-violating change was intentional because being 'more consistent
with other file-handling APIs out there' was somehow more important than
consistency within version releases. It also seems to me that discussion
of code-breaking API changes like this should involve more than one user
and one developer. See
I have fixed my tests so they works in 3.1.2 and should work in other
3.1 releases, but that would be a nuisance to test. Of course, I should
not have to worry about API changes within a version series.
I think issue 8840 illustrates another reason for the bugfix-only
policy. New x.y features and docs are (nearly always) added before the
first beta. They can then be tested, discussed, and improved. This
'cooking' does not occur for bugfix releases. For reasons I give in my
response on the tracker, I think the new behavior is buggy and the doc
So, I think
1) the supposed bugfix-only policy should really be the policy;
2) the violation in 3.1.2 should be reverted in 3.1.3, and the API
change reviewed in the normal 3.2 alpha/beta process.
I am curious as to what others think on both points.
Terry Jan Reedy
At 03:44 PM 5/29/2010 -0700, Brett Cannon wrote:
>On Sat, May 29, 2010 at 12:29, "Martin v. LÃ¶wis" <martin(a)v.loewis.de> wrote:
> > Am 29.05.2010 21:06, schrieb P.J. Eby:
> >> At 08:45 PM 5/29/2010 +0200, Martin v. LÃ¶wis wrote:
> >>>> In it he says that PEP 382 is being deferred until it can address PEP
> >>>> 302 loaders. I can't find any follow-up to this. I don't see any
> >>>> discussion in PEP 382 about PEP 302 loaders, so I assume this issue was
> >>>> never resolved. Does it need to be before PEP 382 is implemented? Are we
> >>>> wasting our time by designing and (eventually) coding before this issue
> >>>> is resolved?
> >>> Yes, and yes.
> >> Is there anything we can do to help regarding that?
> > You could comment on the proposal I made back then, or propose a different
> > solution.
>[sorry for the fundamental PEP questions, but I think PEP 382 came
>about while I was on my python-dev sabbatical last year]
>I have some questions about the PEP which might help clarify how to
>handle the API changes.
>For finders, their search algorithm is changed in a couple of ways.
>One is that modules are given priority over packages (is that
>intentional, Martin, or just an oversight?). Two, the package search
>requires checking for a .pth file on top of an __init__.py. This will
>change finders that could before simply do an existence check on an
>__init__ "file" (or whatever the storage back-end happened to be) and
>make it into a list-and-search which one would hope wasn't costly, but
>in same cases might be if the paths to files is not stored in a
>hierarchical fashion (e.g. zip files list entire files paths in their
>TOC or a sqlite3 DB which uses a path for keys will have to list
>**all** keys, sort them to just the relevant directory, and then look
>for .pth or some such approach). Are we worried about possible
>performance implications of this search?
No. First, an importer would not be required to implement it in a
precisely analagous way; you could have database entries or a special
consolidated index in a zipfile, if you wanted to do it like
that. (In practice, Python's zipimporter has a memory cache of the
TOC, and a simple database index on paths would make a search for
.pth's in a subdirectory trivial for the database case.)
> I say no, but I just want to
>make sure people we are not and people are aware about the design
>shift required in finders. This entire worry would be alleviated if
>only .pth files named after the package were supported, much like
>*.pkg files in pkgutil.
Which would completely break one of the major use cases of the PEP,
which is precisely to ensure that you can install two pieces of code
to the same namespace without either one overwriting the other's files.
>And then the search for the __init__.py begins on the newly modified
>__path__, which I assume ends with the first __init__ found on
>__path__, but if no file is found it's okay and essentially an empty
>module with just module-specific attributes is used? In other words,
>can a .pth file replace an __init__ file in delineating a package?
>Or is it purely additive? I assume the latter for compatibility reasons,
Nope. The idea is specifically to allow separately installed
projects to create a package without overwriting any files (causing
conflicts for system installers).
>but the PEP says "a directory is considered a package if it **either**
>contains a file named __init__.py, **or** a file whose name ends with
>".pth"" (emphasis mine). Otherwise I assume that the search will be
>done simply with ``os.path.isdir(os.path.join(sys_path_entry,
>top_level_package_name)`` and all existing paths will be added to
>__path__. Will they come before or after the directory where the *.pth
>was found? And will any subsequent *.pth files found in other
>directories also be executed?
>As for how "*" works, is this limited to top-level packages, or will
>sub-packages participate as well?
Sub-packages as well.
> I assume the former, but it is not
>directly stated in the PEP. If the latter, is a dotted package name
>changed to ``os.sep.join(sy_path_entry, package_name.replace('".",
>For sys.path_hooks, I am assuming import will simply skip over passing
>that as it is a marker that __path__ represents a namsepace package
>and not in any way functional. Although with sys.namespace_packages,
>is leaving the "*" in __path__ truly necessary?
I'm going to leave these to Martin to answer.
>For the search of paths to use to extend, are we limiting ourselves to
>actual file system entries on sys.path (as pkgutil does),
pkgutil doesn't have such a limitation, except in the case
extend_path, and that limitation is one that PEP 382 intends to remove.
>or do we
>want to support other storage back-ends? To do the latter I would
>suggest having a successful path discovery be when a finder can be
>created for the hypothetical directory from sys.path_hooks.
The downside to that is that NullImporter is the default importer, so
you'd still have to special case it. It would make more sense to add
to the PEP 302 protocols directly.
>I'll shut up now and stop causing trouble. =)
May I suggest you take a look at the implementation draft in my other
email? I realize in retrospect it doesn't handle __init__ searching
in precisely the order proposed by the PEP, but I'm not sure it would
be that difficult to add. (It also needs to split the operation into
find/load pieces, but that's also a straightforward mod: just defer
the module loading until the end, and return a wrapper around the
loader that finishes the process.)
At 05:59 PM 5/30/2010 -0700, Brett Cannon wrote:
>Is it wise to modify __path__ post-import? Today people can make sure
>that __path__ is set to what they want before potentially reading it
>in their __init__ module by making the pkgutil.extend_path() call
>first. This would actually defer to after the import and thus not
>allow any __init__ code to rely on what __path__ eventually becomes.
Well, that's what the other lines in the .pth files are for. Keep in
mind that only *one* project can contain the namespace package's
__init__ module, so it's only sane for that __init__ to import things
that are bundled with the __init__ module.
AFAIK, most uses of namespace packages today are via setuptools' API,
which doesn't support having a non-empty __init__.py at all (apart
from the namespace declaration), so this limitation is unlikely to
cause problems in practice.
When the code I gave is refactored into a proper importer/loader
pair, it can actually be structured such that the full __path__ is
set *before* the low-level loader is called; however, if the loader
itself chooses to overwrite __path__ at that point, there's little
that can be done about it.
In the Python 3.x case, the loader protocol could be revised to
require only *adding* a non-duplicate entry to __path__ if it's
present, and the stdlib loaders updated accordingly. For my
backport, OTOH, I'd have to do some sort of workaround to wrap the
regular importers, so I'd just as soon leave it undefined by PEP 382
what an __init__ module sees in __path__ during its execution. (And
for a backport whose sole purpose is to cut down on setuptools' funky
.pth manipulations, that might suffice anyway.)
issue991196 was closed being described as intentional. I've added
a comment in that issue which argues that this is a serious bug (also
aserted by a previous commenter - Armin Rigo), because it creates a
unique, undocumented, oddly behaving scope that doesn't apply closures
correctly. At the very least I think this should be acknowledged as a
plain old bug (rather than a feature), and then a discussion about
whether it will be fixed or not. Appreciate your thoughts - cheers,
Last night Barry Warsaw, Jason Coombs, and I met to work on implementing
PEP 382. As part of my research, I came across this email from Martin:
In it he says that PEP 382 is being deferred until it can address PEP
302 loaders. I can't find any follow-up to this. I don't see any
discussion in PEP 382 about PEP 302 loaders, so I assume this issue was
never resolved. Does it need to be before PEP 382 is implemented? Are we
wasting our time by designing and (eventually) coding before this issue
Mark Dickinson wrote:
> Seems to me the whole idea of being able to specify
> separate global and local scopes for top-level code is
> screwy in the first place. Are there any use cases for
> it? Maybe the second scope argument to exec() should
> be deprecated?
It is running as class namespace that makes the argument that there's
no use case. I agree - I can't think of any decent use cases for
exec() as class namespace - defining functions and classes only works
for a subset of function and class definitions
However, if exec() ran as function namespace instead, then the locals
dictionary will contain all the definitions from the exec()'d code
block, and only those definitions. Very useful. This is a major use
case for exec() - defining code from strings (e.g. enabling you to
store python code in the database), and using it at runtime. It seems
to me this must have been the point of locals in the first place.
If you just use globals, then your definitions exist amongst a whole
bunch of other python stuff, and unless you know in advance what was
defined in your code block, its very difficult to extract them.