[Python-Dev] PEP 420 - dynamic path computation is missing rationale (original) (raw)

Eric V. Smith eric at trueblade.com
Wed May 23 23:29:41 CEST 2012


On 05/23/2012 03:56 PM, Brett Cannon wrote:

On Wed, May 23, 2012 at 3:35 PM, PJ Eby <pje at telecommunity.com_ _<mailto:pje at telecommunity.com>> wrote: On Wed, May 23, 2012 at 3:02 PM, Brett Cannon <brett at python.org_ _<mailto:brett at python.org>> wrote: If I understand the proposal correctly, this would be a change in NamespaceLoader in how it sets path and in no way affect any other code since import() just grabs the object on path and passes as an argument to the meta path finders which just iterate over the object, so I have no objections to it. That's not quite the proposal (but almost). The change would also mean that import() instead passes a ModulePath (aka Nick's LazyIterable) instance to the meta path finders, which just iterate over it. But other than that, yes. And why does import() need to construct that? I thought NamespaceLoader was going to be making these "magical" path objects that detected changes and thus update themselves as necessary and just stick them on the object. Why specifically does import() need to play a role?

Assume that we're talking about importing either a top-level namespace package named 'parent' and a nested namespace package parent.child.

The problem is that NamespaceLoader is just passed the parent path (typically sys.path, but if a sub-package then parent.path). The concern is that if the parent path object is replaced: sys.path = sys.path + ['new-dir'] or parent.path = ['new-dir'] then the NamespaceLoader instance can no longer detect changes to parent_path.

So the proposed solution is for NamespaceLoader to be told the name of the parent module ('sys' or 'parent') and the attribute name to use to find the path ('path' or 'path').

Here's another suggestion: instead of modifying the finder/loader code to pass these names through, assume that we can always find (module_name, attribute_name) with this code:

def find_parent_path_names(module): parent, dot, me = module.name.rpartition('.') if dot == '': return 'sys', 'path' return parent, 'path'

import glob findparentpathnames(glob) ('sys', 'path') import unittest.test.testcase findparentpathnames(unittest.test.testcase) ('unittest.test', 'path')

I guess it's a little more fragile than passing in these names to NamespaceLoader, but it requires less code to change.

I think I'll whip this up in the pep-420 branch.

Eric.



More information about the Python-Dev mailing list