Re: [Python-ideas] Consider (one day) adding an inheritance order class precedence mechanism

2017-11-16 Thread Steven D'Aprano
On Thu, Nov 16, 2017 at 07:10:15PM +1300, Greg Ewing wrote:
> Steven D'Aprano wrote:
> >These are not equivalent:
> >
> >B < S, E
> >B < E, S
> 
> Not in general, but in many cases they will be, e.g. if
> E and S have no method names in common. I think the OP is
> implying that his case is one of those.

Explicit is better than implicit :-) If Neil meant his suggestion to 
only apply in the case where S and E have no methods in common, he 
should have said so.

Given the possibility of __getattr__ or more exotic things like 
metaclass trickery, we might not even be able to tell what methods are 
possible. We'd need either some philosophy like "if you use this 
feature, you're responsible for ensuring it works" (an excellent way to 
guarantee hard-to-diagnose bugs in people's code *wink* ) or a more 
complex set of requirements:

- none of the classes involved have a non-standard metaclass;
- none of them override __getattribute__ or __getattr__
- none of them have any methods in common

then, and only then, can Python attempt to reorder the MRO to suit. 
Did I miss any necessary conditions?

But that seems like its adding a lot of complexity for little benefit. 

Its not even clear whether this is practical -- why would the author of 
class E specify __precedes__ to suit a class that they don't even know 
exists? What if two classes both want E to specify the order in opposite 
directions?

If I am the author of both E and B, then why don't I just reorder E's 
superclasses directly, instead of using __precedes__?

There's a lot of benefit to having a relatively simple, understandable 
algorithm for determining the MRO, as opposed to some sort of adaptive 
rule that will try to reorder classes according to potentially clashing 
constraints. If that means that some classes cannot go together in 
multiple inheritence because their MRO would be inconsistent, I think 
that's a price worth paying for not having to debug inheritence bugs 
caused by weirdly reordered MROs.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A proliferation of (un-)Pythonically programmatic pragmas

2017-11-16 Thread Steven D'Aprano
On Mon, Nov 13, 2017 at 07:17:26PM -0500, Terry Reedy wrote:

> Docstring directives might be considered for points to copy or not copy.
> An example is  # doctest: +ELLIPSIS, +NORMALIZE_WHITESPACE
[...]
> For binary options, '+' and '-' prefixes are much more compact than 
> '=True' and '=False' suffixes.  This will be more important with 
> multiple directives in one comment.

I'd just like to strongly +1 Terry's comments here.


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Looking for input to help with the pip situation

2017-11-16 Thread Nick Coghlan
On 17 November 2017 at 05:15, Chris Barker  wrote:

> On Wed, Nov 15, 2017 at 11:07 AM, Steve Dower 
> wrote:
>
>> If you write such a PEP, please also research and write up the issues
>> with modifying PATH on Windows (they're largely scattered throughout
>> bugs.p.o and earlier discussions on python-dev).
>>
>
> Is anyone proposing doing anything new with that? (other than changing the
> default)
>
> My preferred solution for this is to rename "py.exe" to "python.exe"
>
>
> I was going to propose that in this thread, but then thought: "there has
> GOT to be a reason why that reall obvious solution wan't done in the first
> place", and didn't have time to go back and research it.
>

As far as I recall, the arguments against it are:

- wanting the regular executable and the launcher to be able to coexist in
the same build target directory
- not wanting the regular python executable to prevent access to the
launcher at a shell prompt
- not wanting the launcher at a shell prompt to prevent access to the
regular executable at a shell prompt

However, https://www.python.org/dev/peps/pep-0397/ doesn't spell those out,
it just states what the launcher's name will be, and emphasises that the
main purpose is to provide a sensible target for file associations after
the "always use the most recently installed version" assumption broke down:
https://www.python.org/dev/peps/pep-0397/#rationale

Addressing them now:

* as long as the extra hard links are only generated at install time, there
also won't be any problems with build directory name conflicts.
* the launcher will always be available a `py`, regardless of the current
PATH
* PATH in a venv will still put the regular python executable ahead of the
launcher

Cheers,
Nick.

-- 
Nick Coghlan   |   ncogh...@gmail.com   |   Brisbane, Australia
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Consider (one day) adding an inheritance order class precedence mechanism

2017-11-16 Thread Chris Barker - NOAA Federal
It doesn't -- that's the point.

Currently it's assumed that the order base classes appear
in a class statement is the order that they must appear
in the MRO.


It’s not assumed — it’s how order is specified by the coder...

But that's not always true.


Isn’t it true by definition?

I'm suggesting that
the MRO algorithm should not assume that and should make
its own assessment of the required ordering.


Isn’t that impossible? It could determine that order doesn’t matter (no
name clashes), but when that’s the case, there’s nothing to do.

What am I missing?

-CHB


-- 
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A proliferation of (un-)Pythonically programmatic pragmas

2017-11-16 Thread Steve Barnes


On 16/11/2017 19:03, Chris Barker wrote:
> On Tue, Nov 14, 2017 at 6:14 PM, Steven D'Aprano  > wrote:
> 
> > and then, even if you wanted to put it on the previous line, you would't
> > have the line-length issue:
> >
> > # flake8: disable=unused-import mypy: alias=pathlib2.Path coverage:
> > ignore=when>py2.7
> 
> And the irony is that this shows exactly why it is still a problem. Code
> gets emailed, and lines get wrapped, breaking the too-long line.
> 
> 
> that wrapped a 85 char line (probably to 72) -- lots of folks have set 
> their line length limit to 90+ these days, so I"m not sure we'll evr be 
> safe...
> 
> but whatever -- multiple line pragmas are fine, too -- I'm hoping 
> putting this much crap in your code will be rare :-)
> 
> -CHB
> 
> -- 
> 
> Christopher Barker, Ph.D.
> Oceanographer
> 
Obviously the best way to avoid multiple warning suppressions to to fix 
what is being warned about, unfortunately it is not always possible.

-- 
Steve (Gadget) Barnes
Any opinions in this message are my personal opinions and do not reflect 
those of my employer.

---
This email has been checked for viruses by AVG.
http://www.avg.com

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Consider (one day) adding an inheritance order class precedence mechanism

2017-11-16 Thread Greg Ewing

Ethan Furman wrote:

If they don't have any clashing attributes, why does order matter?


It doesn't -- that's the point.

Currently it's assumed that the order base classes appear
in a class statement is the order that they must appear
in the MRO. But that's not always true. I'm suggesting that
the MRO algorithm should not assume that and should make
its own assessment of the required ordering.

--
Greg
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Steven D'Aprano
On Thu, Nov 16, 2017 at 02:56:29PM -0500, Terry Reedy wrote:

> >3) using a while loop in code dealing with iterables,
> 
> I agree that this is not necessary, and give a replacement below.

The OP isn't just saying that its unnecessary in this case, but that its 
unPythonic to ever use a while loop in code dealing with iterables. I 
disagree with that stronger statement.


> >def roundrobin(*iters):
> >     "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
> >     # Perhaps "flat_zip_nofill" is a better name, or something similar
> >     sentinel = object()
> >     for tup in it.zip_longest(*iters, fillvalue=sentinel):
> >         yield from (x for x in tup if x is not sentinel)
> 
> This adds and then deletes grouping and fill values that are not wanted. 
>  To me, this is an 'algorithm smell'.  One of the principles of 
> algorithm design is to avoid unnecessary calculations.  For an edge case 
> such as roundrobin(100*'a', ''), the above mostly does unnecessary work.

Its a recipe, not a tuned and optimized piece of production code.

And if you're going to criticise code on the basis of efficiency, then I 
would hope you've actually profiled the code first. Because it isn't 
clear to me at all that what you call "unnecessary work" is more 
expensive than re-writing the recipe using a more complex algorithm with 
calls to cycle and islice.

But I'm not here to nit-pick your recipe over the earlier ones.


[...]
> Since I have a competing 'improvement', I would hold off on a PR until 
> Raymond Hettinger, the itertools author, comments.

Raise a doc issue on the tracker, and take the discussion there. I think 
that this is too minor an issue to need long argument on the list. 
Besides, it's not really on-topic as such -- it isn't about a change to 
the language. Its about an implementation change to a recipe in the 
docs.



-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Terry Reedy

On 11/16/2017 2:42 PM, brent bejot wrote:
I think the idea behind the original recipe is that when one of the 
inner lists has been iterated through, it is removed and never looked at 
again.  Imagine the following scenario:


L is a list which contains one million empty lists and also a list 
containing one million numbers


Then the original recipe will iterate over two million(ish) items: each 
inner list must get visited and each item from the long inner list must 
get visited.  However, your use of zip_longest must visit one trillion 
items, which will likely not finish in a reasonable amount of time.


I'm not saying that this is likely to be the case, but this is probably 
why the original recipe is what it is.  It would be great to see a 
recipe that is more pythonic but that maintains the efficiencies of the 
first recipy, but I could not come up with one.


The two assignments and while loop for 'pending' can be turned into a 
for loop, as in my response (with correction).


--
Terry Jan Reedy


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Terry Reedy

On 11/16/2017 2:56 PM, Terry Reedy wrote:

Correct off-by-one error.  I should have tested with an edge case such as
print(list(roundrobin('ABC', '')))


The following combines 3 statements into one for statement.

def roundrobin(*iterables):
     "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
     nexts = cycle(iter(it).__next__ for it in iterables)
     for reduced_len in reversed(range(1, len(iterables))):


Make that 0 rather than 1 for start value.


     try:
     for next in nexts:
     yield next()
     except StopIteration:
     nexts = cycle(islice(nexts, reduced_len))


A slightly clearer, slightly less efficient alternative would be

def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
nexts = cycle(iter(it).__next__ for it in iterables)
for current_len in reversed(range(1, len(iterables)+1)):
try:
for next in nexts:
yield next()
except StopIteration:
nexts = cycle(islice(nexts, current_len - 1))


--
Terry Jan Reedy


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Steven D'Aprano
On Thu, Nov 16, 2017 at 07:56:21AM -0600, bunslow wrote about the 
roundrobin recipe in the itertools docs:

> However, it is remarkably unpythonic, in my opinion
[...]
> Things that strike me as unpythonic: 1) requiring the total number of input
> iterables 2) making gratuitous use of `next`, 3) using a while loop in code
> dealing with iterables, 4) combining loops, exceptions, and composed
> itertools functions in non-obvious ways that make control flow difficult to
> determine

I don't find *any* of those things unPythonic in the least, nor the 
recipe difficult to follow.


> Now, I get it, looking at the "roughly equivalent to" code for zip_longest
> in the docs, there doesn't seem to be much way around it for generally
> similar goals, and as I said above, unpythonic is fine when necessary
> (practicality beats purity), but in this case, for being a "recipe" in the
> itertools docs, it should *make use* of the zip_longest 

The roundrobin recipe was introduced to the docs some time during Python 
2.5. zip_longest (or izip_longest as it was originally called) wasn't 
introduced until 2.6.


[...]
> Instead, the following recipe (which I also submitted to the StackOverflow
> question, and which is generally similar to several other later answers,
> all remarking that they believe it's more pythonic) is much cleaner and
> more suited to demonstrating the power of itertools to new developers than
> the mess of a "recipe" pasted above.

A "mess" of a quote-unquote "recipe". That's an insulting way of 
describing it. I'd like to see how you would have solved this problem 
back in Python 2.5.

Your post is a very long-winded way of saying:

"I have an improved, more modern implementation for the itertools 
roundrobin recipe, should I raise a documentation issue on the tracker 
to replace it?"

to which I would say, "Sure, why not?".


> I realize at the end of the day this is a pretty trivial and ultimately
> meaningless nit to pick, but I've never contributed before and have a
> variety of similar minor pain points in the docs/stdlib, and I'm trying to
> gauge 1) how well this sort of minor QoL improvement is wanted, and 2) even
> if it is wanted, am I going about it the right way.

1) is fine.

2) is not. You don't need to put down existing code to make your point, 
nor do you have to sing your code's praises. Let the code speak for 
itself. And while its one thing to write detailed and pedantic posts (I 
have a tendency to do likewise) know when its necessary and when it 
isn't. Sometimes we need to discuss a lot of background material to 
explain something, but this wasn't one of those times.


Thank you,


-- 
Steve
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Ignorable whitespaces in the re.VERBOSE mode

2017-11-16 Thread MRAB

On 2017-11-16 21:44, Serhiy Storchaka wrote:

16.11.17 19:38, Guido van Rossum пише:
Who would benefit from changing this? Let's not change things just 
because we can, or because Perl 6 does it.


I don't know. I know the disadvantages of making this change, and I ask
what is the benefit. If there is a benefit, and it is important for
Python, I could implement this feature in re and regex.

You could see what some more languages, e.g. C#, do. If there isn't a 
consensus of some kind, it's best to leave it.

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Ignorable whitespaces in the re.VERBOSE mode

2017-11-16 Thread Serhiy Storchaka

16.11.17 19:38, Guido van Rossum пише:
Who would benefit from changing this? Let's not change things just 
because we can, or because Perl 6 does it.


I don't know. I know the disadvantages of making this change, and I ask 
what is the benefit. If there is a benefit, and it is important for 
Python, I could implement this feature in re and regex.


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Neil Girdhar
I like yours better.  Plenty of recipes sit on top of other recipes, e.g., 
pairwise sits on top of tee.

On Thursday, November 16, 2017 at 8:57:29 AM UTC-5, bunslow wrote:
>
> For taking values alternately from a series of iterables, there's two 
> primary functions:
>
> builtin.zip
> itertools.zip_longest
>
> zip of course stops when the shortest iterable ends. zip_longest is 
> generally a useful substitute for when you don't want the zip behavior, but 
> it fills extra values in the blanks rather than just ignoring a finished 
> iterator and moving on with the rest.
>
> This latter most use case is at least somewhat common, according to 
> this[1] StackOverflow question (and other duplicates), in addition to the 
> existence of the `roundrobin` recipe[2] in the itertools docs. The recipe 
> satisfies this use case, and its code is repeated in the StackOverflow 
> answer.
>
> However, it is remarkably unpythonic, in my opinion, which is one thing 
> when such is necessary to achieve a goal, but for this functionality, such 
> is most definitely *not* necessary.  I'll paste the code here for quick 
> reference:
>
>
> def roundrobin(*iterables):
> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
> pending = len(iterables)
> nexts = cycle(iter(it).__next__ for it in iterables)
> while pending:
> try:
> for next in nexts:
> yield next()
> except StopIteration:
> pending -= 1
> nexts = cycle(islice(nexts, pending))
>
>
> Things that strike me as unpythonic: 1) requiring the total number of 
> input iterables 2) making gratuitous use of `next`, 3) using a while loop 
> in code dealing with iterables, 4) combining loops, exceptions, and 
> composed itertools functions in non-obvious ways that make control flow 
> difficult to determine
>
> Now, I get it, looking at the "roughly equivalent to" code for zip_longest 
> in the docs, there doesn't seem to be much way around it for generally 
> similar goals, and as I said above, unpythonic is fine when necessary 
> (practicality beats purity), but in this case, for being a "recipe" in the 
> itertools docs, it should *make use* of the zip_longest which already does 
> all the unpythonic stuff for you (though honestly I'm not convinced either 
> that the zip_longest code in the docs is the most possible pythonic-ness). 
> Instead, the following recipe (which I also submitted to the StackOverflow 
> question, and which is generally similar to several other later answers, 
> all remarking that they believe it's more pythonic) is much cleaner and 
> more suited to demonstrating the power of itertools to new developers than 
> the mess of a "recipe" pasted above.
>
>
> def roundrobin(*iters):
> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
> # Perhaps "flat_zip_nofill" is a better name, or something similar
> sentinel = object()
> for tup in it.zip_longest(*iters, fillvalue=sentinel):
> yield from (x for x in tup if x is not sentinel)
>
>
> In particular, this is just an extremely thin wrapper around zip_longest, 
> whose primary purpose is to eliminate the otherwise-mandatory "fillvalues" 
> that zip_longest requires to produce uniform-length tuples. It's also an 
> excellent example of how to make best pythonic use of iterables in general, 
> and itertools in particular, and as such a much better implementation to be 
> demonstrated in documentation.
>
> I would thus advocate that the former recipe is replaced with the latter 
> recipe, being much more pythonic, understandable, and useful for helping 
> new developers acquire the style of python. (Using the common linguistics 
> analogy: a dictionary and grammar for a spoken language may be enough to 
> communicate, but we rely on a large body of literature -- fiction, 
> research, poetry, etc -- as children to get that special flavor and most 
> expressive taste to the language. The stdlib is no Shakespeare, but it and 
> its docs still form an important part of the formative literature of the 
> Python language.)
>
> I realize at the end of the day this is a pretty trivial and ultimately 
> meaningless nit to pick, but I've never contributed before and have a 
> variety of similar minor pain points in the docs/stdlib, and I'm trying to 
> gauge 1) how well this sort of minor QoL improvement is wanted, and 2) even 
> if it is wanted, am I going about it the right way. If the answers to both 
> of these questions are positive regarding this particular case, then I'll 
> look into making a BPO issue and pull request on GitHub, which IIUC is the 
> standard path for contributions.
>
> Thank you for your consideration.
>
> 
>
> [1]: 
> https://stackoverflow.com/questions/3678869/pythonic-way-to-combine-two-lists-in-an-alternating-fashion/
>
> [2]: https://docs.python.org/3/library/itertools.html#itertools-recipes
>
___
Python-ideas mailing list
Python-ideas@python.org

Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Ethan Furman

On 11/16/2017 05:56 AM, bunslow wrote:


I realize at the end of the day this is a pretty trivial and ultimately 
meaningless nit to pick,


Not at all -- documentation is extremely important.


but I've never
contributed before and have a variety of similar minor pain points in the 
docs/stdlib, and I'm trying to gauge 1) how
well this sort of minor QoL improvement is wanted, and 2) even if it is wanted, 
am I going about it the right way. If
the answers to both of these questions are positive regarding this particular 
case, then I'll look into making a BPO
issue and pull request on GitHub, which IIUC is the standard path for 
contributions.


I found your example much easier to understand.  Just include a note the the "roughly similar" python code is not 
performant in extreme situations; after all, it's there to aid understanding, not to be used.


--
~Ethan~

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread Terry Reedy

On 11/16/2017 8:56 AM, bunslow wrote:
For taking values alternately from a series of iterables, there's two 
primary functions:


builtin.zip
itertools.zip_longest


These bunch together the nth items of each iterable, while 
itertools.cycle does not.


...

def roundrobin(*iterables):
     "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
     pending = len(iterables)
     nexts = cycle(iter(it).__next__ for it in iterables)
     while pending:
         try:
             for next in nexts:
                 yield next()
         except StopIteration:
             pending -= 1
             nexts = cycle(islice(nexts, pending))



Things that strike me as unpythonic:
1) requiring the total number of input iterable, > 2) making gratuitous use of 
`next`,


I disagree that 1 and 2 are problems.


3) using a while loop in code dealing with iterables,


I agree that this is not necessary, and give a replacement below.


4) combining loops, exceptions, and composed itertools functions in
non-obvious ways that make control flow difficult to determine


I agree that the correctness of the last statement is slightly opaque. 
But this nicely demonstrates a non-trivial use of cycle.


Now, I get it, looking at the "roughly equivalent to" code for 
zip_longest in the docs, there doesn't seem to be much way around it for 
generally similar goals, and as I said above, unpythonic is fine when 
necessary (practicality beats purity), but in this case, for being a 
"recipe" in the itertools docs, it should *make use* of the zip_longest 
which already does all the unpythonic stuff for you (though honestly I'm 
not convinced either that the zip_longest code in the docs is the most 
possible pythonic-ness). Instead, the following recipe (which I also 
submitted to the StackOverflow question, and which is generally similar 
to several other later answers, all remarking that they believe it's 
more pythonic) is much cleaner and more suited to demonstrating the 
power of itertools to new developers than the mess of a "recipe" pasted 
above.


def roundrobin(*iters):
     "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
     # Perhaps "flat_zip_nofill" is a better name, or something similar
     sentinel = object()
     for tup in it.zip_longest(*iters, fillvalue=sentinel):
         yield from (x for x in tup if x is not sentinel)


This adds and then deletes grouping and fill values that are not wanted. 
 To me, this is an 'algorithm smell'.  One of the principles of 
algorithm design is to avoid unnecessary calculations.  For an edge case 
such as roundrobin(100*'a', ''), the above mostly does unnecessary work.


The following combines 3 statements into one for statement.

def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
nexts = cycle(iter(it).__next__ for it in iterables)
for reduced_len in reversed(range(1, len(iterables))):
try:
for next in nexts:
yield next()
except StopIteration:
nexts = cycle(islice(nexts, reduced_len))

In particular, this is just an extremely thin wrapper around 
zip_longest, whose primary purpose is to eliminate the 
otherwise-mandatory "fillvalues" that zip_longest requires to produce 
uniform-length tuples.


But we do not want tuples or fill values.

It's also an excellent example of how to make 
best pythonic use of iterables in general, and itertools in particular, 
and as such a much better implementation to be demonstrated in 
documentation.


I disagree.  [I have mostly stopped using 'pythonic' because there is 
too much disagreement on particulars, and its use seems to inhibit as 
much as facilitate insight.]


[snip more]

I realize at the end of the day this is a pretty trivial and ultimately 
meaningless nit to pick, but I've never contributed before and have a 
variety of similar minor pain points in the docs/stdlib, and I'm trying 
to gauge 1) how well this sort of minor QoL improvement is wanted,


We constantly improve the docs.


2) even if it is wanted, am I going about it the right way.


Typos and trivial grammar issues can be filed as a PR with no issue 
required.  Clarifications usually require an issue and perhaps 
discussion.  Since this is more about philosophy of algorithm design, 
python-ideas was a good place to start.


If the 
answers to both of these questions are positive regarding this 
particular case, then I'll look into making a BPO issue and pull request 
on GitHub, which IIUC is the standard path for contributions.


Since I have a competing 'improvement', I would hold off on a PR until 
Raymond Hettinger, the itertools author, comments.


--
Terry Jan Reedy


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread brent bejot
I think the idea behind the original recipe is that when one of the inner
lists has been iterated through, it is removed and never looked at again.
Imagine the following scenario:

L is a list which contains one million empty lists and also a list
containing one million numbers

Then the original recipe will iterate over two million(ish) items: each
inner list must get visited and each item from the long inner list must get
visited.  However, your use of zip_longest must visit one trillion items,
which will likely not finish in a reasonable amount of time.

I'm not saying that this is likely to be the case, but this is probably why
the original recipe is what it is.  It would be great to see a recipe that
is more pythonic but that maintains the efficiencies of the first recipy,
but I could not come up with one.

-Brent

On Thu, Nov 16, 2017 at 10:08 AM, David Mertz  wrote:

> I agree this is a much better recipe presented.
>
> Have you benchmarked the two on more realistically long iterators. E.g. a
> hundred iterators of millions of items where many terminate much earlier
> than others. I doubt the repeated 'is not' comparison makes much
> difference, but it would be good to see.
>
> On Nov 16, 2017 5:57 AM, "bunslow"  wrote:
>
>> For taking values alternately from a series of iterables, there's two
>> primary functions:
>>
>> builtin.zip
>> itertools.zip_longest
>>
>> zip of course stops when the shortest iterable ends. zip_longest is
>> generally a useful substitute for when you don't want the zip behavior, but
>> it fills extra values in the blanks rather than just ignoring a finished
>> iterator and moving on with the rest.
>>
>> This latter most use case is at least somewhat common, according to
>> this[1] StackOverflow question (and other duplicates), in addition to the
>> existence of the `roundrobin` recipe[2] in the itertools docs. The recipe
>> satisfies this use case, and its code is repeated in the StackOverflow
>> answer.
>>
>> However, it is remarkably unpythonic, in my opinion, which is one thing
>> when such is necessary to achieve a goal, but for this functionality, such
>> is most definitely *not* necessary.  I'll paste the code here for quick
>> reference:
>>
>>
>> def roundrobin(*iterables):
>> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
>> pending = len(iterables)
>> nexts = cycle(iter(it).__next__ for it in iterables)
>> while pending:
>> try:
>> for next in nexts:
>> yield next()
>> except StopIteration:
>> pending -= 1
>> nexts = cycle(islice(nexts, pending))
>>
>>
>> Things that strike me as unpythonic: 1) requiring the total number of
>> input iterables 2) making gratuitous use of `next`, 3) using a while loop
>> in code dealing with iterables, 4) combining loops, exceptions, and
>> composed itertools functions in non-obvious ways that make control flow
>> difficult to determine
>>
>> Now, I get it, looking at the "roughly equivalent to" code for
>> zip_longest in the docs, there doesn't seem to be much way around it for
>> generally similar goals, and as I said above, unpythonic is fine when
>> necessary (practicality beats purity), but in this case, for being a
>> "recipe" in the itertools docs, it should *make use* of the zip_longest
>> which already does all the unpythonic stuff for you (though honestly I'm
>> not convinced either that the zip_longest code in the docs is the most
>> possible pythonic-ness). Instead, the following recipe (which I also
>> submitted to the StackOverflow question, and which is generally similar to
>> several other later answers, all remarking that they believe it's more
>> pythonic) is much cleaner and more suited to demonstrating the power of
>> itertools to new developers than the mess of a "recipe" pasted above.
>>
>>
>> def roundrobin(*iters):
>> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
>> # Perhaps "flat_zip_nofill" is a better name, or something similar
>> sentinel = object()
>> for tup in it.zip_longest(*iters, fillvalue=sentinel):
>> yield from (x for x in tup if x is not sentinel)
>>
>>
>> In particular, this is just an extremely thin wrapper around zip_longest,
>> whose primary purpose is to eliminate the otherwise-mandatory "fillvalues"
>> that zip_longest requires to produce uniform-length tuples. It's also an
>> excellent example of how to make best pythonic use of iterables in general,
>> and itertools in particular, and as such a much better implementation to be
>> demonstrated in documentation.
>>
>> I would thus advocate that the former recipe is replaced with the latter
>> recipe, being much more pythonic, understandable, and useful for helping
>> new developers acquire the style of python. (Using the common linguistics
>> analogy: a dictionary and grammar for a spoken language may be enough to
>> communicate, but we rely on a large body of literature -- fiction,
>> research, poetry, etc -- as children to get that

Re: [Python-ideas] Looking for input to help with the pip situation

2017-11-16 Thread Chris Barker
On Wed, Nov 15, 2017 at 11:07 AM, Steve Dower 
wrote:

> If you write such a PEP, please also research and write up the issues with
> modifying PATH on Windows (they're largely scattered throughout bugs.p.o
> and earlier discussions on python-dev).
>

Is anyone proposing doing anything new with that? (other than changing the
default)

My preferred solution for this is to rename "py.exe" to "python.exe"


I was going to propose that in this thread, but then thought: "there has
GOT to be a reason why that reall obvious solution wan't done in the first
place", and didn't have time to go back and research it.

But if it's feasible from a technical and backward-compatible perspective,
great!

-CHB

-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] A proliferation of (un-)Pythonically programmatic pragmas

2017-11-16 Thread Chris Barker
On Tue, Nov 14, 2017 at 6:14 PM, Steven D'Aprano 
wrote:

> > and then, even if you wanted to put it on the previous line, you would't
> > have the line-length issue:
> >
> > # flake8: disable=unused-import mypy: alias=pathlib2.Path coverage:
> > ignore=when>py2.7
>
> And the irony is that this shows exactly why it is still a problem. Code
> gets emailed, and lines get wrapped, breaking the too-long line.
>

that wrapped a 85 char line (probably to 72) -- lots of folks have set
their line length limit to 90+ these days, so I"m not sure we'll evr be
safe...

but whatever -- multiple line pragmas are fine, too -- I'm hoping putting
this much crap in your code will be rare :-)

-CHB

-- 

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R(206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115   (206) 526-6317   main reception

chris.bar...@noaa.gov
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Ignorable whitespaces in the re.VERBOSE mode

2017-11-16 Thread Guido van Rossum
Who would benefit from changing this? Let's not change things just because
we can, or because Perl 6 does it.

On Thu, Nov 16, 2017 at 9:21 AM, MRAB  wrote:

> On 2017-11-16 10:23, Serhiy Storchaka wrote:
>
>> Currently the re module ignores only 6 ASCII whitespaces in the
>> re.VERBOSE mode:
>>
>>U+0009 CHARACTER TABULATION
>>U+000A LINE FEED
>>U+000B LINE TABULATION
>>U+000C FORM FEED
>>U+000D CARRIAGE RETURN
>>U+0020 SPACE
>>
>> Perl ignores characters that Unicode calls "Pattern White Space" in the
>> /x mode. It ignores additional 5 non-ASCII characters.
>>
>>U+0085 NEXT LINE
>>U+200E LEFT-TO-RIGHT MARK
>>U+200F RIGHT-TO-LEFT MARK
>>U+2028 LINE SEPARATOR
>>U+2029 PARAGRAPH SEPARATOR
>>
>> The regex module just ignores characters for which str.isspace() returns
>> True. It ignores additional 20 non-ASCII whitespace characters,
>> including characters U+001C..001F whose classification as whitespaces is
>> questionable, but doesn't ignore LEFT-TO-RIGHT MARK and RIGHT-TO-LEFT
>> MARK.
>>
>>U+001C [FILE SEPARATOR]
>>U+001D [GROUP SEPARATOR]
>>U+001E [RECORD SEPARATOR]
>>U+001F [UNIT SEPARATOR]
>>U+00A0 NO-BREAK SPACE
>>U+1680 OGHAM SPACE MARK
>>U+2000 EN QUAD
>>U+2001 EM QUAD
>>U+2002 EN SPACE
>>U+2003 EM SPACE
>>U+2004 THREE-PER-EM SPACE
>>U+2005 FOUR-PER-EM SPACE
>>U+2006 SIX-PER-EM SPACE
>>U+2007 FIGURE SPACE
>>U+2008 PUNCTUATION SPACE
>>U+2009 THIN SPACE
>>U+200A HAIR SPACE
>>U+202F NARROW NO-BREAK SPACE
>>U+205F MEDIUM MATHEMATICAL SPACE
>>U+3000 IDEOGRAPHIC SPACE
>>
>> str.isspace appears to be Unicode "Whitespace" plus those 4
> "questionable" codepoints.
>
>
> Is it worth to extend the set of ignored whitespaces to "Pattern
>> Whitespaces"? Would it add any benefit? Or add confusion? Should this
>> depend on the re.ASCII mode? Should the byte b'\x85' be ignorable in
>> verbose bytes patterns?
>>
>> And there is a similar question about the Python parser. If Python uses
>> Unicode definition for identifier, shouldn't it accept non-ASCII
>> "Pattern Whitespaces" as whitespaces? There will be technical problems
>> with supporting this, but are there any benefits?
>>
>>
>> https://perldoc.perl.org/perlre.html
>> https://www.unicode.org/reports/tr31/tr31-4.html#Pattern_Syntax
>> https://unicode.org/L2/L2005/05012r-pattern.html
>>
>> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
>



-- 
--Guido van Rossum (python.org/~guido)
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Ignorable whitespaces in the re.VERBOSE mode

2017-11-16 Thread MRAB

On 2017-11-16 10:23, Serhiy Storchaka wrote:

Currently the re module ignores only 6 ASCII whitespaces in the
re.VERBOSE mode:

   U+0009 CHARACTER TABULATION
   U+000A LINE FEED
   U+000B LINE TABULATION
   U+000C FORM FEED
   U+000D CARRIAGE RETURN
   U+0020 SPACE

Perl ignores characters that Unicode calls "Pattern White Space" in the
/x mode. It ignores additional 5 non-ASCII characters.

   U+0085 NEXT LINE
   U+200E LEFT-TO-RIGHT MARK
   U+200F RIGHT-TO-LEFT MARK
   U+2028 LINE SEPARATOR
   U+2029 PARAGRAPH SEPARATOR

The regex module just ignores characters for which str.isspace() returns
True. It ignores additional 20 non-ASCII whitespace characters,
including characters U+001C..001F whose classification as whitespaces is
questionable, but doesn't ignore LEFT-TO-RIGHT MARK and RIGHT-TO-LEFT MARK.

   U+001C [FILE SEPARATOR]
   U+001D [GROUP SEPARATOR]
   U+001E [RECORD SEPARATOR]
   U+001F [UNIT SEPARATOR]
   U+00A0 NO-BREAK SPACE
   U+1680 OGHAM SPACE MARK
   U+2000 EN QUAD
   U+2001 EM QUAD
   U+2002 EN SPACE
   U+2003 EM SPACE
   U+2004 THREE-PER-EM SPACE
   U+2005 FOUR-PER-EM SPACE
   U+2006 SIX-PER-EM SPACE
   U+2007 FIGURE SPACE
   U+2008 PUNCTUATION SPACE
   U+2009 THIN SPACE
   U+200A HAIR SPACE
   U+202F NARROW NO-BREAK SPACE
   U+205F MEDIUM MATHEMATICAL SPACE
   U+3000 IDEOGRAPHIC SPACE

str.isspace appears to be Unicode "Whitespace" plus those 4 
"questionable" codepoints.



Is it worth to extend the set of ignored whitespaces to "Pattern
Whitespaces"? Would it add any benefit? Or add confusion? Should this
depend on the re.ASCII mode? Should the byte b'\x85' be ignorable in
verbose bytes patterns?

And there is a similar question about the Python parser. If Python uses
Unicode definition for identifier, shouldn't it accept non-ASCII
"Pattern Whitespaces" as whitespaces? There will be technical problems
with supporting this, but are there any benefits?


https://perldoc.perl.org/perlre.html
https://www.unicode.org/reports/tr31/tr31-4.html#Pattern_Syntax
https://unicode.org/L2/L2005/05012r-pattern.html


___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread David Mertz
I agree this is a much better recipe presented.

Have you benchmarked the two on more realistically long iterators. E.g. a
hundred iterators of millions of items where many terminate much earlier
than others. I doubt the repeated 'is not' comparison makes much
difference, but it would be good to see.

On Nov 16, 2017 5:57 AM, "bunslow"  wrote:

> For taking values alternately from a series of iterables, there's two
> primary functions:
>
> builtin.zip
> itertools.zip_longest
>
> zip of course stops when the shortest iterable ends. zip_longest is
> generally a useful substitute for when you don't want the zip behavior, but
> it fills extra values in the blanks rather than just ignoring a finished
> iterator and moving on with the rest.
>
> This latter most use case is at least somewhat common, according to
> this[1] StackOverflow question (and other duplicates), in addition to the
> existence of the `roundrobin` recipe[2] in the itertools docs. The recipe
> satisfies this use case, and its code is repeated in the StackOverflow
> answer.
>
> However, it is remarkably unpythonic, in my opinion, which is one thing
> when such is necessary to achieve a goal, but for this functionality, such
> is most definitely *not* necessary.  I'll paste the code here for quick
> reference:
>
>
> def roundrobin(*iterables):
> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
> pending = len(iterables)
> nexts = cycle(iter(it).__next__ for it in iterables)
> while pending:
> try:
> for next in nexts:
> yield next()
> except StopIteration:
> pending -= 1
> nexts = cycle(islice(nexts, pending))
>
>
> Things that strike me as unpythonic: 1) requiring the total number of
> input iterables 2) making gratuitous use of `next`, 3) using a while loop
> in code dealing with iterables, 4) combining loops, exceptions, and
> composed itertools functions in non-obvious ways that make control flow
> difficult to determine
>
> Now, I get it, looking at the "roughly equivalent to" code for zip_longest
> in the docs, there doesn't seem to be much way around it for generally
> similar goals, and as I said above, unpythonic is fine when necessary
> (practicality beats purity), but in this case, for being a "recipe" in the
> itertools docs, it should *make use* of the zip_longest which already does
> all the unpythonic stuff for you (though honestly I'm not convinced either
> that the zip_longest code in the docs is the most possible pythonic-ness).
> Instead, the following recipe (which I also submitted to the StackOverflow
> question, and which is generally similar to several other later answers,
> all remarking that they believe it's more pythonic) is much cleaner and
> more suited to demonstrating the power of itertools to new developers than
> the mess of a "recipe" pasted above.
>
>
> def roundrobin(*iters):
> "roundrobin('ABC', 'D', 'EF') --> A D E B F C"
> # Perhaps "flat_zip_nofill" is a better name, or something similar
> sentinel = object()
> for tup in it.zip_longest(*iters, fillvalue=sentinel):
> yield from (x for x in tup if x is not sentinel)
>
>
> In particular, this is just an extremely thin wrapper around zip_longest,
> whose primary purpose is to eliminate the otherwise-mandatory "fillvalues"
> that zip_longest requires to produce uniform-length tuples. It's also an
> excellent example of how to make best pythonic use of iterables in general,
> and itertools in particular, and as such a much better implementation to be
> demonstrated in documentation.
>
> I would thus advocate that the former recipe is replaced with the latter
> recipe, being much more pythonic, understandable, and useful for helping
> new developers acquire the style of python. (Using the common linguistics
> analogy: a dictionary and grammar for a spoken language may be enough to
> communicate, but we rely on a large body of literature -- fiction,
> research, poetry, etc -- as children to get that special flavor and most
> expressive taste to the language. The stdlib is no Shakespeare, but it and
> its docs still form an important part of the formative literature of the
> Python language.)
>
> I realize at the end of the day this is a pretty trivial and ultimately
> meaningless nit to pick, but I've never contributed before and have a
> variety of similar minor pain points in the docs/stdlib, and I'm trying to
> gauge 1) how well this sort of minor QoL improvement is wanted, and 2) even
> if it is wanted, am I going about it the right way. If the answers to both
> of these questions are positive regarding this particular case, then I'll
> look into making a BPO issue and pull request on GitHub, which IIUC is the
> standard path for contributions.
>
> Thank you for your consideration.
>
> 
>
> [1]: https://stackoverflow.com/questions/3678869/pythonic-
> way-to-combine-two-lists-in-an-alternating-fashion/
>
> [2]: https://docs.python.org/3/library/itertoo

Re: [Python-ideas] Consider (one day) adding an inheritance order class precedence mechanism

2017-11-16 Thread Ethan Furman

On 11/15/2017 10:10 PM, Greg Ewing wrote:

Steven D'Aprano wrote:

These are not equivalent:

B < S, E
B < E, S


Not in general, but in many cases they will be, e.g. if
E and S have no method names in common. I think the OP is
implying that his case is one of those.

Maybe what's really wanted is a way to say "B inherits from
S and E, but it doesn't care what order they go in". Then
the MRO generating algorithm could in principle swap them
if it would result in a consistent MRO.

Or maybe the MRO generator could decide for itself if the
order of two base classes can be swapped by inspecting
their attributes to see if any of them clash?


If they don't have any clashing attributes, why does order matter?

--
~Ethan~

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Rewriting the "roundrobin" recipe in the itertools documentation

2017-11-16 Thread bunslow
For taking values alternately from a series of iterables, there's two
primary functions:

builtin.zip
itertools.zip_longest

zip of course stops when the shortest iterable ends. zip_longest is
generally a useful substitute for when you don't want the zip behavior, but
it fills extra values in the blanks rather than just ignoring a finished
iterator and moving on with the rest.

This latter most use case is at least somewhat common, according to this[1]
StackOverflow question (and other duplicates), in addition to the existence
of the `roundrobin` recipe[2] in the itertools docs. The recipe satisfies
this use case, and its code is repeated in the StackOverflow answer.

However, it is remarkably unpythonic, in my opinion, which is one thing
when such is necessary to achieve a goal, but for this functionality, such
is most definitely *not* necessary.  I'll paste the code here for quick
reference:


def roundrobin(*iterables):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
pending = len(iterables)
nexts = cycle(iter(it).__next__ for it in iterables)
while pending:
try:
for next in nexts:
yield next()
except StopIteration:
pending -= 1
nexts = cycle(islice(nexts, pending))


Things that strike me as unpythonic: 1) requiring the total number of input
iterables 2) making gratuitous use of `next`, 3) using a while loop in code
dealing with iterables, 4) combining loops, exceptions, and composed
itertools functions in non-obvious ways that make control flow difficult to
determine

Now, I get it, looking at the "roughly equivalent to" code for zip_longest
in the docs, there doesn't seem to be much way around it for generally
similar goals, and as I said above, unpythonic is fine when necessary
(practicality beats purity), but in this case, for being a "recipe" in the
itertools docs, it should *make use* of the zip_longest which already does
all the unpythonic stuff for you (though honestly I'm not convinced either
that the zip_longest code in the docs is the most possible pythonic-ness).
Instead, the following recipe (which I also submitted to the StackOverflow
question, and which is generally similar to several other later answers,
all remarking that they believe it's more pythonic) is much cleaner and
more suited to demonstrating the power of itertools to new developers than
the mess of a "recipe" pasted above.


def roundrobin(*iters):
"roundrobin('ABC', 'D', 'EF') --> A D E B F C"
# Perhaps "flat_zip_nofill" is a better name, or something similar
sentinel = object()
for tup in it.zip_longest(*iters, fillvalue=sentinel):
yield from (x for x in tup if x is not sentinel)


In particular, this is just an extremely thin wrapper around zip_longest,
whose primary purpose is to eliminate the otherwise-mandatory "fillvalues"
that zip_longest requires to produce uniform-length tuples. It's also an
excellent example of how to make best pythonic use of iterables in general,
and itertools in particular, and as such a much better implementation to be
demonstrated in documentation.

I would thus advocate that the former recipe is replaced with the latter
recipe, being much more pythonic, understandable, and useful for helping
new developers acquire the style of python. (Using the common linguistics
analogy: a dictionary and grammar for a spoken language may be enough to
communicate, but we rely on a large body of literature -- fiction,
research, poetry, etc -- as children to get that special flavor and most
expressive taste to the language. The stdlib is no Shakespeare, but it and
its docs still form an important part of the formative literature of the
Python language.)

I realize at the end of the day this is a pretty trivial and ultimately
meaningless nit to pick, but I've never contributed before and have a
variety of similar minor pain points in the docs/stdlib, and I'm trying to
gauge 1) how well this sort of minor QoL improvement is wanted, and 2) even
if it is wanted, am I going about it the right way. If the answers to both
of these questions are positive regarding this particular case, then I'll
look into making a BPO issue and pull request on GitHub, which IIUC is the
standard path for contributions.

Thank you for your consideration.



[1]: https://stackoverflow.com/questions/3678869/
pythonic-way-to-combine-two-lists-in-an-alternating-fashion/

[2]: https://docs.python.org/3/library/itertools.html#itertools-recipes
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Consider (one day) adding an inheritance order class precedence mechanism

2017-11-16 Thread Koos Zevenhoven
On Thu, Nov 16, 2017 at 5:28 AM, Neil Girdhar  wrote:

> On Wednesday, November 15, 2017 at 5:32:00 PM UTC-5, Koos Zevenhoven wrote:
>>
>> On Wed, Nov 15, 2017 at 11:49 PM, Neil Girdhar 
>> wrote:
>>
>>> Sometimes I get MRO failures when defining classes.  For example, if
>>>
>>> R < E, C
>>> B < S, E
>>> S < C
>>> Z < B, R
>>>
>>> Then Z cannot be instantiated because C precedes E in B and E precedes C
>>> in R.  The problem is that when the inheritance graph was
>>> topologically-sorted in B, the order was S, C, E.  It could just as easily
>>> have been S, E, C.  So, one solution is to add C explicitly to B's base
>>> class list, but this is annoying because B might not care about C (it's an
>>> implementation detail of S).  It also means that if the hierarchy changes,
>>> a lot of these added extra base classes need to be fixed.
>>>
>>> I propose adding a magic member to classes:
>>>
>>> __precedes__ that is a list of classes.  So, the fix for the above
>>> problem would be to define E as follows:
>>>
>>> class E:
>>> from whatever import C
>>> __precedes__ = [C]
>>>
>>> Then, when topologically-sorting (so-called linearizing) the ancestor
>>> classes, Python can try to ensure that E precedes C when defining B.
>>>
>>>
>> So it sounds like you are talking about the way that the siblings in the
>> inheritance tree (the bases of each class) get "flattened" into the mro in
>> a depth-first manner, and the relative order of siblings is not preserved.
>>
>
> It is preserved, but there are insufficient constraints, which causes
> problems with future class definitions.
>
>
>> What would you think about not topologically sorting the inheritance tree
>> as such, but sorting a graph that has additional edges according to the
>> base lists of each class involved? In this case those edges would be E->C,
>> S->E, B->R. Is this what your talking about, or do I misinterpret the
>> problem?
>>
>
> That's already part of the topological sorting algorithm.  You have to do
> that.  I'm suggesting additional constraints.
>
>

​​I'm talking about the initial graph to be sorted. Not some intermediate
graph that may be used for describing steps in an algorithm.

Anyway, the contraint given by the edge E->C is not y​et part of the
algorithm, because if it was already there, you wouldn't need
"__precedes__" to add that edge.

But another thing that affects this is whether we consider multiple
occurrences of a class in the inheritance tree as the same node in the
inheritance graph or not. If yes, then the inheritance tree and the
inheritance graph are two different things.

––Koos

-- 
+ Koos Zevenhoven + http://twitter.com/k7hoven +
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Looking for input to help with the pip situation

2017-11-16 Thread Wes Turner
Would something like this be helpful?
(`python -m pip` seems to work fine after `conda install pip` after a
miniconda install)

https://gist.github.com/westurner/80e81cd4bf9b79acb5989622f2621655

```python
#!/usr/bin/env python
"""
Something like this as e.g site.discover
(for use as ``python -m site.discover``)
could be helpful for explaining and diagnosing multiple pythons and pips
"""

import os
import re
from distutils.spawn import find_executable
from subprocess import check_output, STDOUT
import collections


def discover(path=None, printsite=False, uniques=True):
"""
Find all ``python*`` and ``pip*`` executables and their version strings
within ``os.environ['PATH']``

Kwargs:
path (str): os.pathsep-delimited path str
(defaults to ``os.environ['PATH']``)
printsite (bool): call `` -m site``
with each found python binary
uniques (bool): print uniques according to ``os.realpath`` at the
end

Returns:
None
"""
if path is None:
path = os.environ['PATH']
rgx = re.compile(r'(python|pip)\-?(\d?\.?\d?)$')
uniques = collections.OrderedDict()
for directory in path.split(os.pathsep):
paths = sorted(
((match.group(0), match.group(2)) for match in
(rgx.match(name) for name in os.listdir(directory))
 if match),
key=lambda x: x[::-1],
reverse=True)
print(u'# %s' % directory)
for (name, ver) in paths:
pathjoined = os.path.join(directory, name)
binpath = find_executable(pathjoined, directory)
realpath = os.path.realpath(binpath)
if binpath is None:
continue
if os.path.exists(pathjoined):
if os.path.islink(pathjoined):
print((
u"%r is a symlink to %r, which doesn't exist"
% (pathjoined, binpath)))
# TODO: %r exists but isnt executable
verstring = check_output((binpath, '-V'),
 stderr=STDOUT).rstrip()
uniques.setdefault(realpath, collections.OrderedDict()) \
.setdefault(binpath, verstring)
print(u'%-11r %-5r %r' % (name, ver, verstring))
if printsite and name.startswith('python'):
sitestring = check_output((binpath, '-m', 'site'))
lines = (u'> %s' % l for l in sitestring.splitlines())
for line in lines:
print(line)
# TODO: check_output((binpath, '-m', 'pip'))

# TODO: AND/OR (?) only print uniques at the end
if uniques:
print('### UNIQUES')
for path in uniques:
print('## %s' % path)
paths = uniques.get(path)
for otherpath in sorted(paths):
print(otherpath)
print('')


if __name__ == '__main__':
discover()

```


On Wednesday, November 15, 2017, Steve Dower  wrote:

> On 15Nov2017 0617, Nick Coghlan wrote:
>
>> On 15 November 2017 at 22:46, Michel Desmoulin > > wrote:
>> Should I do a PEP with a summary of all the stuff we discussed ?
>> I think a Windows-specific PEP covering adding PATH updates back to the
>> default installer behaviour, and adding pythonX and pythonX.Y commands
>> would be useful (and Guido would presumably delegate resolving that to
>> Steve Dower as the Windows installer maintainer).
>>
>
> If you write such a PEP, please also research and write up the issues with
> modifying PATH on Windows (they're largely scattered throughout bugs.p.o
> and earlier discussions on python-dev).
>
> Once you realise the tradeoff involved in modifying these global settings,
> you'll either come around to my point of view or be volunteering to take
> *all* the support questions when they come in :)
>
> The one thing I'd ask is that any such PEP *not* advocate for promoting
>> ther variants as the preferred way of invoking Python on Windows - rather,
>> they should be positioned as a way of making online instructions written
>> for Linux more likely to "just work" for folks on Windows (similar to the
>> utf-8 encoding changes in https://www.python.org/dev/peps/pep-0529/)
>>
>> Instead, the focus should be on ensuring the "python -m pip install" and
>> "pip install" both work after clicking through the installer without
>> changing any settings, and devising a troubleshooting guide to help folks
>> that are familiar with computers and Python, but perhaps not with Windows,
>> guide folks to a properly working environment.
>>
>
> My preferred solution for this is to rename "py.exe" to "python.exe" (or
> rather, make a copy of it with the new name), and extend (or more likely,
> rewrite) the launcher such that:
>
> * if argv[0] == "py.exe", use PEP 514 company/tag resolution to find and
> launch Python based on first command line 

Re: [Python-ideas] Ignorable whitespaces in the re.VERBOSE mode

2017-11-16 Thread Paul Moore
My instinct is not to worry about it unless someone has actually hit
the issue in practice and raised a bug.
Paul

On 16 November 2017 at 10:23, Serhiy Storchaka  wrote:
> Currently the re module ignores only 6 ASCII whitespaces in the re.VERBOSE
> mode:
>
>  U+0009 CHARACTER TABULATION
>  U+000A LINE FEED
>  U+000B LINE TABULATION
>  U+000C FORM FEED
>  U+000D CARRIAGE RETURN
>  U+0020 SPACE
>
> Perl ignores characters that Unicode calls "Pattern White Space" in the /x
> mode. It ignores additional 5 non-ASCII characters.
>
>  U+0085 NEXT LINE
>  U+200E LEFT-TO-RIGHT MARK
>  U+200F RIGHT-TO-LEFT MARK
>  U+2028 LINE SEPARATOR
>  U+2029 PARAGRAPH SEPARATOR
>
> The regex module just ignores characters for which str.isspace() returns
> True. It ignores additional 20 non-ASCII whitespace characters, including
> characters U+001C..001F whose classification as whitespaces is questionable,
> but doesn't ignore LEFT-TO-RIGHT MARK and RIGHT-TO-LEFT MARK.
>
>  U+001C [FILE SEPARATOR]
>  U+001D [GROUP SEPARATOR]
>  U+001E [RECORD SEPARATOR]
>  U+001F [UNIT SEPARATOR]
>  U+00A0 NO-BREAK SPACE
>  U+1680 OGHAM SPACE MARK
>  U+2000 EN QUAD
>  U+2001 EM QUAD
>  U+2002 EN SPACE
>  U+2003 EM SPACE
>  U+2004 THREE-PER-EM SPACE
>  U+2005 FOUR-PER-EM SPACE
>  U+2006 SIX-PER-EM SPACE
>  U+2007 FIGURE SPACE
>  U+2008 PUNCTUATION SPACE
>  U+2009 THIN SPACE
>  U+200A HAIR SPACE
>  U+202F NARROW NO-BREAK SPACE
>  U+205F MEDIUM MATHEMATICAL SPACE
>  U+3000 IDEOGRAPHIC SPACE
>
> Is it worth to extend the set of ignored whitespaces to "Pattern
> Whitespaces"? Would it add any benefit? Or add confusion? Should this depend
> on the re.ASCII mode? Should the byte b'\x85' be ignorable in verbose bytes
> patterns?
>
> And there is a similar question about the Python parser. If Python uses
> Unicode definition for identifier, shouldn't it accept non-ASCII "Pattern
> Whitespaces" as whitespaces? There will be technical problems with
> supporting this, but are there any benefits?
>
>
> https://perldoc.perl.org/perlre.html
> https://www.unicode.org/reports/tr31/tr31-4.html#Pattern_Syntax
> https://unicode.org/L2/L2005/05012r-pattern.html
>
> ___
> Python-ideas mailing list
> Python-ideas@python.org
> https://mail.python.org/mailman/listinfo/python-ideas
> Code of Conduct: http://python.org/psf/codeofconduct/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


[Python-ideas] Ignorable whitespaces in the re.VERBOSE mode

2017-11-16 Thread Serhiy Storchaka
Currently the re module ignores only 6 ASCII whitespaces in the 
re.VERBOSE mode:


 U+0009 CHARACTER TABULATION
 U+000A LINE FEED
 U+000B LINE TABULATION
 U+000C FORM FEED
 U+000D CARRIAGE RETURN
 U+0020 SPACE

Perl ignores characters that Unicode calls "Pattern White Space" in the 
/x mode. It ignores additional 5 non-ASCII characters.


 U+0085 NEXT LINE
 U+200E LEFT-TO-RIGHT MARK
 U+200F RIGHT-TO-LEFT MARK
 U+2028 LINE SEPARATOR
 U+2029 PARAGRAPH SEPARATOR

The regex module just ignores characters for which str.isspace() returns 
True. It ignores additional 20 non-ASCII whitespace characters, 
including characters U+001C..001F whose classification as whitespaces is 
questionable, but doesn't ignore LEFT-TO-RIGHT MARK and RIGHT-TO-LEFT MARK.


 U+001C [FILE SEPARATOR]
 U+001D [GROUP SEPARATOR]
 U+001E [RECORD SEPARATOR]
 U+001F [UNIT SEPARATOR]
 U+00A0 NO-BREAK SPACE
 U+1680 OGHAM SPACE MARK
 U+2000 EN QUAD
 U+2001 EM QUAD
 U+2002 EN SPACE
 U+2003 EM SPACE
 U+2004 THREE-PER-EM SPACE
 U+2005 FOUR-PER-EM SPACE
 U+2006 SIX-PER-EM SPACE
 U+2007 FIGURE SPACE
 U+2008 PUNCTUATION SPACE
 U+2009 THIN SPACE
 U+200A HAIR SPACE
 U+202F NARROW NO-BREAK SPACE
 U+205F MEDIUM MATHEMATICAL SPACE
 U+3000 IDEOGRAPHIC SPACE

Is it worth to extend the set of ignored whitespaces to "Pattern 
Whitespaces"? Would it add any benefit? Or add confusion? Should this 
depend on the re.ASCII mode? Should the byte b'\x85' be ignorable in 
verbose bytes patterns?


And there is a similar question about the Python parser. If Python uses 
Unicode definition for identifier, shouldn't it accept non-ASCII 
"Pattern Whitespaces" as whitespaces? There will be technical problems 
with supporting this, but are there any benefits?



https://perldoc.perl.org/perlre.html
https://www.unicode.org/reports/tr31/tr31-4.html#Pattern_Syntax
https://unicode.org/L2/L2005/05012r-pattern.html

___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Looking for input to help with the pip situation

2017-11-16 Thread Paul Moore
On 16 November 2017 at 06:49, Nick Coghlan  wrote:
> On 16 November 2017 at 05:29, Zachary Ware 
> wrote:
>>
>> On Wed, Nov 15, 2017 at 1:07 PM, Steve Dower 
>> wrote:
>> > My preferred solution for this is to rename "py.exe" to "python.exe" (or
>> > rather, make a copy of it with the new name), and extend (or more
>> > likely,
>> > rewrite) the launcher such that:
>> >
>> > * if argv[0] == "py.exe", use PEP 514 company/tag resolution to find and
>> > launch Python based on first command line argument
>> > * if argv[0] == "python.exe", find the matching
>> > PythonCore/ install (where tag may be a partial match - e.g.
>> > "python3.exe" finds the latest PythonCore/3.x)
>> > * else, if argv[0] == ".exe, find the matching
>> > PythonCore/ install and launch "-m "
>> >
>> > With the launcher behaving like this, we can make as many hard links as
>> > we
>> > want in its install directory (it only gets installed once, so only
>> > needs
>> > one PATH entry, and this is C:\Windows for admin installs):
>> > * python.exe
>> > * python2.exe
>> > * python3.exe
>> > * python3.6.exe
>> > * pip.exe
>> > * pip2.exe
>> > * pip3.exe
>>
>> I haven't been following this thread closely, but this sounds lovely.
>> I'm not terribly keen on cluttering up C:\Windows with this, but
>> that's a minor issue.
>
>
> I'd missed Steve's post before writing my last one. This sounds like a
> really nice technical solution to me, too, especially as it will handle
> Python 2 as well (even for Python 2 only systems, the launcher is available
> as an independently installable executable).
>
> Regardless of the underlying implementation details though, a PEP would be a
> helpful way of writing it up so we can make sure packaging.python.org and
> other resources properly account for it.

OK, I'll add that to the list of things to look at.

Paul
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/