Re: [Python-Dev] docs.python.org pointing to Python 3 by default?

2012-05-22 Thread Stefan Scherfke
Am 2012-05-21 um 19:58 schrieb Éric Araujo:

> Le 21/05/2012 07:42, Georg Brandl a écrit :
>> What about:
>> 
>> * Canonical:
>> 
>> docs.python.org/2/
>> docs.python.org/3/
>> 
>> for latest versions of 2.x and 3.x
>> 
>> docs.python.org/2.7/ etc.
>> 
>> for latest minor versions
>> 
>> docs.python.org/dev/
>> 
>> for latest dev version.
> +1.
> 
> I’d be +1 to adding /stable but both 2.7 and 3.2 are stable at this time.
> 
>> * Redirected:
>> 
>> docs.python.org/  -->  either /2/ or /3/ or a "disambiguation page"
> Either sounds good, I’m in favor of redirecting to /2 for a few years
> still to preserve existing links and avoid the need to click on each page.
> 
>> docs.python.org/py3k/ -> /3/
> +1, the py3k name is not obvious for everyone.
> 
>> There is also /release/X.Y.Z for individual released versions, which
>> I don't want to change.
> The URIs should not change, but it seems a bit bad to me that for
> example the 2.7.1 docs don’t link to the latest 2.7 page and mention 2.6
> as stable version
> 
>> I also like Martin's idea of offering more links between individual
>> pages, not only the front-pages.
> +1
> 
> On a related note, we may want to find a way to make the version more
> prominent in the pages; I’ve seen beginners install Python 3 and use the
> Python 2 docs and fail at the first print 'Hello, world!' example.
> That’s why I support always having the version numbers in the URIs.
> 
> Cheers

I think this URL scheme looks most clean:

docs.python.org/   --> Points to recommended version(2 for now, 3 later)
docs.python.org/2/  --> Points to latest stable 2.x
docs.python.org/2.7/ 
docs.python.org/2.6/
...
docs.python.org/3/  --> Points to latest stable 3.x
docs.python.org/3.2/
...
docs.python.org/dev/  --> Points to dev version (e.g., 3.3)

Using something like docs.python.org/stable/ in books might not make sense if 
the book is about Python 3 and /stable/ points to Python 4 a few years later.

Imho, adding additional sub-domains also wouldn’t improve anything, but would 
add more clutter and confusion (what if somebody types "docs3.python.org/2/ ?)

A prominent CCS-box showing the current version and offering Links to other 
main versions would make it perfect (e.g. 2, 3 and dev for all versions, 3.x 
sub-releases only, if you are under docs.python.org/3/... and for 2.x 
accordingly).

Cheers,
Stefan
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-checkins] cpython (2.7): #14804: Remove [] around optional arguments with default values

2012-05-22 Thread Nick Coghlan
On Tue, May 22, 2012 at 6:34 PM, hynek.schlawack
 wrote:
> http://hg.python.org/cpython/rev/a3c52115
> changeset:   77102:a3c52115
> branch:      2.7
> parent:      77099:c13066f752a8
> user:        Hynek Schlawack 
> date:        Tue May 22 10:27:40 2012 +0200
> summary:
>  #14804: Remove [] around optional arguments with default values
>
> Mostly just mechanical removal of []. In some rare cases I've pulled the
> default value up into the argument list.

Be a little careful with this - "[]" is the right notation when the
function doesn't support keyword arguments. At least one of the
updated signatures is incorrect:

> diff --git a/Doc/library/itertools.rst b/Doc/library/itertools.rst
> --- a/Doc/library/itertools.rst
> +++ b/Doc/library/itertools.rst
> @@ -627,7 +627,7 @@
>                   break
>
>
> -.. function:: tee(iterable[, n=2])
> +.. function:: tee(iterable, n=2)

>>> itertools.tee([], n=2)
Traceback (most recent call last):
  File "", line 1, in 
TypeError: tee() takes no keyword arguments

Since calling "tee(itr, n=2)" doesn't add really any clarity over
"tee(itr, 2)", it's unlikely this function will ever gain keyword
argument support (since supporting keyword arguments *is* slower than
supporting only positional arguments for functions written in C.

The change is probably valid for the pure Python modules, and the
builtins looked right, but be wary of any extension modules in the
list.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-checkins] cpython (2.7): #14804: Remove [] around optional arguments with default values

2012-05-22 Thread Hynek Schlawack
Hi Nick,

>> Mostly just mechanical removal of []. In some rare cases I've pulled the
>> default value up into the argument list.
> Be a little careful with this - "[]" is the right notation when the
> function doesn't support keyword arguments. At least one of the
> updated signatures is incorrect:

Ah dang, thanks for pointing this out! I went at least five times
through all changes but there had to be one thing I missed. :(

Same in dl.open() & ossaudiodev.oss_audio_device.setparameters(). I will
go through them all once more and fix it at the latest tomorrow.

Regards,
Hynek
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Eric V. Smith
On 05/21/2012 07:25 PM, Nick Coghlan wrote:
> As a simple example to back up PJE's explanation, consider:
> 1.  encodings becomes a namespace package
> 2. It sometimes gets imported during interpreter startup to initialise
> the standard io streams
> 3. An application modifies sys.path after startup and wants to
> contribute additional encodings
> 
> Searching the entire parent path for new portions on every import would
> be needlessly slow.
> 
> Not recognising new portions would be needlessly confusing for users. In
> our simple case above, the application would fail if the io
> initialisation accessed the encodings package, but work if it did not
> (e.g. when all streams are utf-8).
> 
> PEP 420 splits the difference via an automatically invalidated cache:
> when you iterate over a namespace package __path__ object, it rescans
> the parent path for new portions *if and only if* the contents of the
> parent path have changed since the previous scan.

That seems like a pretty convincing example to me.

Personally I'm +1 on putting dynamic computation into the PEP, at least
for top-level namespace packages, and probably for all namespace packages.

The code is not very large or complicated, and with the proposed removal
of the restriction that sys.path cannot be replaced, I think it behaves
well.

But Guido can decide against it without hurting my feelings.

Eric.

P.S.: Here's the current code in the pep-420 branch. This code still has
the restriction that sys.path (or parent_path in general) can't be
replaced. I'll fix that if we decide to keep the feature.

class _NamespacePath:
def __init__(self, name, path, parent_path, path_finder):
self._name = name
self._path = path
self._parent_path = parent_path
self._last_parent_path = tuple(parent_path)
self._path_finder = path_finder

def _recalculate(self):
# If _parent_path has changed, recalculate _path
parent_path = tuple(self._parent_path) # Make a copy
if parent_path != self._last_parent_path:
loader, new_path = self._path_finder(self._name, parent_path)
# Note that no changes are made if a loader is returned, but we
#  do remember the new parent path
if loader is None:
self._path = new_path
self._last_parent_path = parent_path   # Save the copy
return self._path

def __iter__(self):
return iter(self._recalculate())

def __len__(self):
return len(self._recalculate())

def __repr__(self):
return "_NamespacePath" + repr((self._path, self._parent_path))

def __contains__(self, item):
return item in self._recalculate()



___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Nick Coghlan
On Wed, May 23, 2012 at 12:51 AM, Eric V. Smith  wrote:
> That seems like a pretty convincing example to me.
>
> Personally I'm +1 on putting dynamic computation into the PEP, at least
> for top-level namespace packages, and probably for all namespace packages.

Same here, but Guido's right that the rationale (and example) should
be clearer in the PEP itself if the feature is to be retained.

> P.S.: Here's the current code in the pep-420 branch. This code still has
> the restriction that sys.path (or parent_path in general) can't be
> replaced. I'll fix that if we decide to keep the feature.

I wonder if it would be worth exposing an importlib.LazyRef API to
make it generally easy to avoid this kind of early binding problem?

   class LazyRef:
  # similar API to weakref.weakref
  def __init__(self, modname, attr=None):
  self.modname = modname
  self.attr = attr
  def __call__(self):
  mod = sys.modules[self.modname]
  attr = self.attr
  if attr is None:
  return mod
  return getattr(mod, attr)

Then _NamespacePath could just be defined as taking a callable that
returns the parent path:


 class _NamespacePath:
    def __init__(self, name, path, parent_path, path_finder):
        self._name = name
        self._path = path
        self._parent_path = parent_path
        self._last_parent_path = tuple(parent_path)
        self._path_finder = path_finder

    def _recalculate(self):
        # If _parent_path has changed, recalculate _path
        parent_path = tuple(self._parent_path())     # Retrieve and make a copy
        if parent_path != self._last_parent_path:
            loader, new_path = self._path_finder(self._name, parent_path)
            # Note that no changes are made if a loader is returned, but we
            #  do remember the new parent path
            if loader is None:
                self._path = new_path
            self._last_parent_path = parent_path   # Save the copy
        return self._path

Even if the LazyRef idea isn't used, I still like the idea of passing
a callable in to _NamespacePath for the parent path rather than
hardcoding the "module name + attribute name" approach.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Nick Coghlan
On Wed, May 23, 2012 at 1:39 AM, Nick Coghlan  wrote:
>     def _recalculate(self):
>         # If _parent_path has changed, recalculate _path
>         parent_path = tuple(self._parent_path())     # Retrieve and make a 
> copy
>         if parent_path != self._last_parent_path:
>             loader, new_path = self._path_finder(self._name, parent_path)
>             # Note that no changes are made if a loader is returned, but we
>             #  do remember the new parent path
>             if loader is None:
>                 self._path = new_path
>             self._last_parent_path = parent_path   # Save the copy
>         return self._path

Oops, I also meant to say that it's probably worth at least issuing
ImportWarning if a new portion with an __init__.py gets added - it's
going to block all future dynamic updates of that namespace package.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Eric V. Smith
On 05/22/2012 11:39 AM, Nick Coghlan wrote:
> On Wed, May 23, 2012 at 12:51 AM, Eric V. Smith  wrote:
>> That seems like a pretty convincing example to me.
>>
>> Personally I'm +1 on putting dynamic computation into the PEP, at least
>> for top-level namespace packages, and probably for all namespace packages.
> 
> Same here, but Guido's right that the rationale (and example) should
> be clearer in the PEP itself if the feature is to be retained.

Completely agreed. I'll work on it.

> Oops, I also meant to say that it's probably worth at least issuing
> ImportWarning if a new portion with an __init__.py gets added - it's
> going to block all future dynamic updates of that namespace package.

Right. That's on my list of things to clean up. It actually won't block
updates during this run of Python, though: once a namespace package,
always a namespace package. But if, on another run, that entry is on
sys.path, then yes, it will block all namespace package portions.

Eric.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread PJ Eby
On Mon, May 21, 2012 at 8:32 PM, Eric V. Smith  wrote:

> Any reason to make this the string "sys" or "foo", and not the module
> itself? Can the module be replaced in sys.modules? Mostly I'm just curious.
>

Probably not, but it occurred to me that storing references to modules
introduces a reference cycle that wasn't there when we were pointing to
parent path objects instead. It basically would make child packages point
to their parents, as well as the other way around.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Guido van Rossum
Okay, I've been convinced that keeping the dynamic path feature is a
good idea. I am really looking forward to seeing the rationale added
to the PEP -- that's pretty much the last thing on my list that made
me hesitate. I'll leave the details of exactly how the parent path is
referenced up to the implementation team (several good points were
made), as long as the restriction that sys.path must be modified in
place is lifted.

-- 
--Guido van Rossum (python.org/~guido)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-checkins] cpython: Issue #14814: addition of the ipaddress module (stage 1 - code and tests)

2012-05-22 Thread Sandro Tosi
Thanks Terry for the review! I've attached a patch to issue14814
addressing your points; but..

On Sun, May 20, 2012 at 7:18 PM, Terry Reedy  wrote:
>> +def _get_prefix_length(number1, number2, bits):
>> +    """Get the number of leading bits that are same for two numbers.
>> +
>> +    Args:
>> +        number1: an integer.
>> +        number2: another integer.
>> +        bits: the maximum number of bits to compare.
>> +
>> +    Returns:
>> +        The number of leading bits that are the same for two numbers.
>> +
>> +    """
>> +    for i in range(bits):
>> +        if number1>>  i == number2>>  i:
>
>
> This non-PEP8 spacing is awful to read. The double space after the tighter
> binding operator is actively deceptive. Please use
>
>        if number1 >> i == number2 >> i:

I don't see this (and all the other) spacing issue you mentioned. Is
it possible that your mail client had played some "funny" tricks?

>> +    Args:
>> +        first: the first IPv4Address or IPv6Address in the range.
>> +        last: the last IPv4Address or IPv6Address in the range.
>> +
>> +    Returns:
>> +        An iterator of the summarized IPv(4|6) network objects.
>
> Very clear as to types.

I don't think I get exactly what you mean here.

Cheers,
-- 
Sandro Tosi (aka morph, morpheus, matrixhasu)
My website: http://matrixhasu.altervista.org/
Me at Debian: http://wiki.debian.org/SandroTosi
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread PJ Eby
On Tue, May 22, 2012 at 12:31 PM, Eric V. Smith  wrote:

> On 05/22/2012 11:39 AM, Nick Coghlan wrote:
> > Oops, I also meant to say that it's probably worth at least issuing
> > ImportWarning if a new portion with an __init__.py gets added - it's
> > going to block all future dynamic updates of that namespace package.
>
> Right. That's on my list of things to clean up. It actually won't block
> updates during this run of Python, though: once a namespace package,
> always a namespace package. But if, on another run, that entry is on
> sys.path, then yes, it will block all namespace package portions.
>

This discussion has gotten me thinking: should we expose a
pkgutil.declare_namespace() API to allow such an __init__.py to turn itself
back into a namespace?  (Per our previous discussion on transitioning
existing namespace packages.)  It wouldn't need to do all the other stuff
that the setuptools version does, it would just be a way to transition away
from setuptools.

What it would do is:
1. Recursively invoke itself for parent packages
2. Create the module object if it doesn't already exist
3. Set the module __path__ to a _NamespacePath instance.

def declare_namespace(package_name):
 parent, dot, tail = package_name.rpartition('.')
 attr = '__path__'
 if dot:
declare_namespace(parent)
 else:
parent, attr = 'sys', 'path'
 with importlockcontext:
  module = sys.modules.get(package_name)
  if module is None:
  module = XXX new module here
  module.__path__ = _NamespacePath(...stuff involving 'parent' and
'attr')

It may be that this should complain under certain circumstances, or use the
'__path__ = something' idiom, but the above approach would be (basically)
API compatible with the standard usage of declare_namespace.

Obviously, this'll only be useful for people who are porting code going
forward, but even if a different API is chosen, there still ought to be a
way for people to do it.  Namespace packages are one of a handful of
features that are still basically setuptools-only at this point (i.e. not
yet provided by packaging/distutils2), but if it's the only setuptools-only
feature a project is using, they'd be able to drop their dependency as of
3.3.

(Next up, I guess we'll need an entry-points PEP, but that'll be another
discussion. ;-) )
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-checkins] cpython: Issue #14814: addition of the ipaddress module (stage 1 - code and tests)

2012-05-22 Thread Terry Reedy

On 5/22/2012 3:59 PM, Sandro Tosi wrote:

Thanks Terry for the review! I've attached a patch to issue14814
addressing your points; but..

On Sun, May 20, 2012 at 7:18 PM, Terry Reedy  wrote:

+def _get_prefix_length(number1, number2, bits):
+"""Get the number of leading bits that are same for two numbers.
+
+Args:
+number1: an integer.
+number2: another integer.
+bits: the maximum number of bits to compare.
+
+Returns:
+The number of leading bits that are the same for two numbers.
+
+"""
+for i in range(bits):
+if number1>>i == number2>>i:



This non-PEP8 spacing is awful to read. The double space after the tighter
binding operator is actively deceptive. Please use

if number1>>  i == number2>>  i:


I don't see this (and all the other) spacing issue you mentioned. Is
it possible that your mail client had played some "funny" tricks?


Well, *something* between there and here seems to have. I retrieved the 
patch in FF browser and that line looks fine. It also looks fine when I 
cut and pasted it into a test message from a web mail account to my udel 
account, viewed with same mail client. Sorry for the noise. Glad that 
you do not need to 'fix' anything of this sort.



+Args:
+first: the first IPv4Address or IPv6Address in the range.
+last: the last IPv4Address or IPv6Address in the range.
+
+Returns:
+An iterator of the summarized IPv(4|6) network objects.


Very clear as to types.


I don't think I get exactly what you mean here.


This docstring clearly says what the input type is instead of the more 
vague 'address'. Also, the output is pretty clearly an iterable of 
IPv#Address objects. I meant to contrast this as a good example compared 
to some of the previous docstrings.


--
Terry Jan Reedy

___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Barry Warsaw
Minor nit.

On May 22, 2012, at 04:43 PM, PJ Eby wrote:

>def declare_namespace(package_name):
> parent, dot, tail = package_name.rpartition('.')
> attr = '__path__'
> if dot:
>declare_namespace(parent)
> else:
>parent, attr = 'sys', 'path'
> with importlockcontext:
>  module = sys.modules.get(package_name)

Best to use a marker object here instead of checking for None, since the
latter is a valid value for an existing entry in sys.modules.

>  if module is None:
>  module = XXX new module here
>  module.__path__ = _NamespacePath(...stuff involving 'parent' and
>'attr')

Cheers,
-Barry
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Eric V. Smith
On 5/22/2012 2:37 PM, Guido van Rossum wrote:
> Okay, I've been convinced that keeping the dynamic path feature is a
> good idea. I am really looking forward to seeing the rationale added
> to the PEP -- that's pretty much the last thing on my list that made
> me hesitate. I'll leave the details of exactly how the parent path is
> referenced up to the implementation team (several good points were
> made), as long as the restriction that sys.path must be modified in
> place is lifted.

I've updated the PEP. Let me know how it looks.

I have not updated the implementation yet. I'm not exactly sure how I'm
going to convert from a path list of unknown origin to ('sys', 'path')
or ('foo', '__path__'). I'll look at it later tonight to see if it's
possible. I'm hoping it doesn't require major surgery to
importlib._bootstrap.

I still owe PEP updates for finder/loader examples and nested namespace
package examples. But I think that's all that's needed.

Eric.
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] [Python-checkins] peps: Added dynamic path computation rationale, specification, and discussion.

2012-05-22 Thread Nick Coghlan
On Wed, May 23, 2012 at 10:35 AM, eric.smith  wrote:
> +  4. An attempt is made to import an ``encodings`` portion that is
> +     found on a path added in step 3.

I'd phrase this as something like "import an encoding from an
``encodings`` portion". You don't really import namespace package
portions directly - you import the modules and packages they contain.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread PJ Eby
On Tue, May 22, 2012 at 8:40 PM, Eric V. Smith  wrote:

> On 5/22/2012 2:37 PM, Guido van Rossum wrote:
> > Okay, I've been convinced that keeping the dynamic path feature is a
> > good idea. I am really looking forward to seeing the rationale added
> > to the PEP -- that's pretty much the last thing on my list that made
> > me hesitate. I'll leave the details of exactly how the parent path is
> > referenced up to the implementation team (several good points were
> > made), as long as the restriction that sys.path must be modified in
> > place is lifted.
>
> I've updated the PEP. Let me know how it looks.
>

My name is misspelled in it, but otherwise it looks fine.  ;-)

I have not updated the implementation yet. I'm not exactly sure how I'm
> going to convert from a path list of unknown origin to ('sys', 'path')
> or ('foo', '__path__'). I'll look at it later tonight to see if it's
> possible. I'm hoping it doesn't require major surgery to
> importlib._bootstrap.
>

It shouldn't - all you should need is to use
getattr(sys.modules[self.modname], self.attr) instead of referencing a
parent path object directly.

(The more interesting thing is what to do if the parent module goes away,
due to somebody deleting the module out of sys.modules.  The simplest thing
to do would probably be to just keep using the cached value in that case.)

Ah crap, I just thought of something - what happens if you reload() a
namespace package?  Probably nothing, but should we specify what sort of
nothing?  ;-)
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Nick Coghlan
On Wed, May 23, 2012 at 10:40 AM, Eric V. Smith  wrote:
> On 5/22/2012 2:37 PM, Guido van Rossum wrote:
>> Okay, I've been convinced that keeping the dynamic path feature is a
>> good idea. I am really looking forward to seeing the rationale added
>> to the PEP -- that's pretty much the last thing on my list that made
>> me hesitate. I'll leave the details of exactly how the parent path is
>> referenced up to the implementation team (several good points were
>> made), as long as the restriction that sys.path must be modified in
>> place is lifted.
>
> I've updated the PEP. Let me know how it looks.
>
> I have not updated the implementation yet. I'm not exactly sure how I'm
> going to convert from a path list of unknown origin to ('sys', 'path')
> or ('foo', '__path__'). I'll look at it later tonight to see if it's
> possible. I'm hoping it doesn't require major surgery to
> importlib._bootstrap.

If you wanted to do this without changing the sys.meta_path hook API,
you'd have to pass an object to find_module() that did the dynamic
lookup of the value in obj.__iter__. Something like:

class _LazyPath:
def __init__(self, modname, attribute):
self.modname = modname
self.attribute = attribute
def __iter__(self):
return iter(getattr(sys.module[self.modname], self.attribute))

A potentially cleaner alternative to consider is tweaking the
find_loader API spec so that it gets used at the meta path level as
well as at the path hooks level and is handed a *callable* that
dynamically retrieves the path rather than a direct reference to the
path itself.

The full signature of find_loader would then become:

def find_loader(fullname, get_path=None):
# fullname as for find_module
# When get_path is None, it means the finder is being called
as a path hook and
# should use the specific path entry passed to __init__
# In this case, namespace package portions are returned as
(None, portions)
# Otherwise, the finder is being called as a meta_path hook
and get_path() will return the relevant path
# Any namespace packages are then returned as (loader, portions)

There are two major consequences of this latter approach:
- the PEP 302 find_module API would now be a purely legacy interface
for both the meta_path and path_hooks, used only if find_loader is not
defined
- it becomes trivial to tell whether a particular name references a
package or not *without* needing to load it first: find_loader()
returns a non-empty iterable for the list of portions

That second consequence is rather appealing: it means you'd be able to
implement an almost complete walk of a package hierarchy *without*
having to import anything (although you would miss old-style namespace
packages and any other packages that alter their own __path__ in
__init__, so you may still want to load packages to make sure you
found everything. You could definitively answer the "is this a package
or not?" question without running any code, though).

The first consequence is also appealing, since the find_module() name
is more than a little misleading. The "find_module" name strongly
suggests that the method is expected to return a module object, and
that's just wrong -  you actually find a loader, then you use that to
load the module.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread PJ Eby
On Tue, May 22, 2012 at 9:58 PM, Nick Coghlan  wrote:

> If you wanted to do this without changing the sys.meta_path hook API,
> you'd have to pass an object to find_module() that did the dynamic
> lookup of the value in obj.__iter__. Something like:
>
>class _LazyPath:
>def __init__(self, modname, attribute):
>self.modname = modname
>self.attribute = attribute
>def __iter__(self):
>return iter(getattr(sys.module[self.modname], self.attribute))
>
> A potentially cleaner alternative to consider is tweaking the
> find_loader API spec so that it gets used at the meta path level as
> well as at the path hooks level and is handed a *callable* that
> dynamically retrieves the path rather than a direct reference to the
> path itself.
>
> The full signature of find_loader would then become:
>
>def find_loader(fullname, get_path=None):
># fullname as for find_module
># When get_path is None, it means the finder is being called
> as a path hook and
># should use the specific path entry passed to __init__
># In this case, namespace package portions are returned as
> (None, portions)
># Otherwise, the finder is being called as a meta_path hook
> and get_path() will return the relevant path
># Any namespace packages are then returned as (loader, portions)
>
> There are two major consequences of this latter approach:
> - the PEP 302 find_module API would now be a purely legacy interface
> for both the meta_path and path_hooks, used only if find_loader is not
> defined
> - it becomes trivial to tell whether a particular name references a
> package or not *without* needing to load it first: find_loader()
> returns a non-empty iterable for the list of portions
>
> That second consequence is rather appealing: it means you'd be able to
> implement an almost complete walk of a package hierarchy *without*
> having to import anything (although you would miss old-style namespace
> packages and any other packages that alter their own __path__ in
> __init__, so you may still want to load packages to make sure you
> found everything. You could definitively answer the "is this a package
> or not?" question without running any code, though).
>
> The first consequence is also appealing, since the find_module() name
> is more than a little misleading. The "find_module" name strongly
> suggests that the method is expected to return a module object, and
> that's just wrong -  you actually find a loader, then you use that to
> load the module.
>

While I see no problem with cleaning up the interface, I'm kind of lost as
to the point of making a get_path callable, vs. just using the iterable
interface you sketched.  Python has iterables, so why add a call to get the
iterable, when iter() or a straight "for" loop will do effectively the same
thing?
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com


Re: [Python-Dev] PEP 420 - dynamic path computation is missing rationale

2012-05-22 Thread Nick Coghlan
On Wed, May 23, 2012 at 1:58 PM, PJ Eby  wrote:
> While I see no problem with cleaning up the interface, I'm kind of lost as
> to the point of making a get_path callable, vs. just using the iterable
> interface you sketched.  Python has iterables, so why add a call to get the
> iterable, when iter() or a straight "for" loop will do effectively the same
> thing?

Yeah, I'm not sure what I was thinking either, since just documenting
the interface and providing LazyPath as a public API somewhere in
importlib should suffice. Meta path hooks are already going to need to
tolerate being handed arbitrary iterables, since that's exactly what
namespace package path objects are going to be.

While I still like the idea of killing off find_module() completely
rather than leaving it in at the meta_path level, there's no reason
that needs to be done as part of PEP 420 itself. Instead, it can be
done later if anyone comes up with a concrete use case for access the
path details without loading packages and modules.

Cheers,
Nick.

-- 
Nick Coghlan   |   [email protected]   |   Brisbane, Australia
___
Python-Dev mailing list
[email protected]
http://mail.python.org/mailman/listinfo/python-dev
Unsubscribe: 
http://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com