Re: [Python-ideas] + operator on generators

2017-07-01 Thread Paul Moore
On 1 July 2017 at 07:13, Steven D'Aprano  wrote:
> But the more I think about it the more I agree with Nick. Let's start
> by moving itertools.chain into built-ins, with zip and map, and only
> consider giving it an operator after we've had a few years of experience
> with chain as a built-in. We might even find that an operator doesn't
> add any real value.

I'm struck here by the contrast between this and the "let's slim down
the stdlib" debates we've had in the past.

How difficult is it really to add "from itertools import chain" at the
start of a file? It's not even as if itertools is a 3rd party
dependency.

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/


Re: [Python-ideas] CPython should get...

2017-07-01 Thread Paul Moore
On 1 July 2017 at 18:35, Nick Timkovich  wrote:
> Devil's advocate: why prepare a patch and submit it if it is going to be
> dismissed out of hand. Trying to gauge support for the idea is a reasonable
> first-step.

That's perfectly OK, but it's important to phrase the email in a way
that makes that clear - "I'm considering putting together a PR for
Python to implement X. Does that sound like a good idea, or does
anyone have suggestions for potential issues I might consider? Also,
is there any prior work in this area that I should look into?"

"Python should have X" implies (a) that you are criticising the python
developers for missing that feature out, (b) that you consider your
position self-evident, and (c) that you expect someone to implement
it.

People have different ways of expressing themselves, so we should all
be prepared to allow some leeway in how people put their ideas across.
But the writer has some responsibility for the tone, too.

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-03 Thread Paul Moore
On 3 July 2017 at 09:59, Ken Kundert  wrote:
> I think in trying to illustrate the existing behavior I made things more
> confusing than they needed to be.  Let me try again.
>
> Consider this code.
>
> >>> import Food
> >>> try:
> ... import meals
> ... except NameError as e:
> ... name = str(e).split("'")[1]   # <-- fragile code
> ... from difflib import get_close_matches
> ... candidates = ', '.join(get_close_matches(name, Food.foods, 1, 
> 0.6))
> ... print(f'{name}: not found. Did you mean {candidates}?')
>
> In this case *meals* instantiates a collection of foods. It is a Python file,
> but it is also a data file (in this case the user knows Python, so Python is
> a convenient data format). In that file thousands of foods may be 
> instantiated.
> If the user misspells a food, I would like to present the available
> alternatives. To do so, I need the misspelled name.  The only way I can get it
> is by parsing the error message.

As Steven pointed out, this is a pretty good example of a code smell.
My feeling is that you may have just proved that Python isn't quite as
good a fit for your data file format as you thought - or that your
design has flaws. Suppose your user had a breakfast menu, and did
something like:

if now < lunchtim: # Should have been "lunchtime"

Your error handling will be fairly confusing in that case.

> That is the problem.  To write the error handler, I need the misspelled name.
> The only way to get it is to extract it from the error message. The need to
> unpack information that was just packed suggests that the packing was done too
> early.  That is my point.

I don't have any problem with *having* the misspelled name as an
attribute to the error, I just don't think it's going to be as useful
as you hope, and it may indeed (as above) encourage people to use it
without thinking about whether there might be problems with using
error handling that way.

> Fundamentally, pulling the name out of an error message is a really bad coding
> practice because it is fragile.  The code will likely break if the formatting 
> or
> the wording of the message changes.  But given the way the exception was
> implemented, I am forced to choose between two unpleasant choices: pulling the
> name from the error message or not giving the enhanced message at all.

Or using a different approach. ("Among our different approaches...!"
:-)) Agreed that's also an unpleasant choice at this point.

> What I am hoping to do with this proposal is to get the Python developer
> community to see that:
> 1. The code that handles the exception benefits from having access to the
>components of the error message.  In the least it can present the message 
> to
>the user is the best possible way. Perhaps that means enforcing a 
> particular
>style, or presenting it in the user's native language, or perhaps it means
>providing additional related information as in the example above.

I see it as a minor bug magnet, but not really a problem in principle.

> 2. The current approach to exceptions follows the opposite philosophy,
>suggesting that the best place to construct the error message is at the
>source of the error. It inadvertently puts obstacles in place that make it
>difficult to customize the message in the handler.

It's more about implicitly enforcing the policy of "catch errors over
as small a section of code as practical". In your example, you're
trapping NameError from anywhere in a "many thousands" of line file.
That's about as far from the typical use of one or two lines in a try
block as you can get.

> 3. Changing the approach in the BaseException class to provide the best of 
> both
>approaches provides considerable value and is both trivial and backward
>compatible.

A small amount of value in a case we don't particularly want to encourage.
Whether it's trivial comes down to implementation - I'll leave that to
whoever writes the PR to demonstrate. (Although if it *is* trivial, is
it something you could write a PR for?)

Also, given that this would be Python 3.7 only, would people needing
this functionality (only you have expressed a need so far) be OK with
either insisting their users go straight to Python 3.7, or including
backward compatible code for older versions?

Overall, I'm -0 on this request (assuming it is trivial to implement -
I certainly don't feel it's worth significant implementation effort).

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-03 Thread Paul Moore
On 3 July 2017 at 20:46, Jeff Walker  wrote:
>  I think you are fixating too much on Ken's example. I think I understand 
> what he
> is saying and I agree with him. It is a problem I struggle with routinely. It 
> occurs in
>  the following situations:

Possibly. I hadn't reread the original email. Having done so, I'm
confused as to how the proposal and the example are related. The
proposal makes no difference unless the places where (for example)
NameError are raised are changed. But the proposal doesn't suggest
changing how the interpreter raises NameError. So how will the
proposal make a difference? I'd understood from the example that Ken's
need was to be able to find the name that triggered the NameError. His
proposal doesn't do that (unless we are talking about user-raised
NameError exceptions, as opposed to ones the interpreter raises - in
which case why not just use a user-defined exception?

So I'm -1 on his proposal, as I don't see anything in it that couldn't
be done in user code for user-defined exceptions, and there's nothing
in the proposal suggesting a change in how interpreter-raised
exceptions are created.

> 1. You are handling an exception that you are not raising. This could be 
> because
> Python itself is raising the exception, as in Ken's example, or it could 
> be raised
> by some package you did not write.
> 2. You need to process or transform the message in some way.

Then yes, you need to know the API presented by the exception.
Projects (and the core interpreter) are not particularly good at
documenting (or designing) the API for their exceptions, but that
doesn't alter the fact that exceptions are user-defined classes and as
such do have an API. I'd be OK with arguments that the API of built in
exceptions as raised by the interpreter could be improved. Indeed, I
thought that was Ken's proposal. But his proposal seems to be that if
we add a ___str__ method to BaseException, that will somehow
automatically improve the API of all other exceptions.

To quote Ken:

> However, if more than one argument is passed, you get the string 
> representation
> of the tuple containing all the arguments:
>
> >>> try:
> ... raise Exception('Hey there!', 'Something went wrong.')
> ... except Exception as e:
> ... print(str(e))
> ('Hey there!', 'Something went wrong.')
>
> That behavior does not seem very useful, and I believe it leads to people
> passing only one argument to their exceptions.

Alternatively, I could argue that code which uses print(str(e)) as its
exception handling isn't very well written, and the fact that people
do this is what leads to people passing only one argument to their
exceptions when creating them.

Look, I see that there might be something that could be improved here.
But I don't see an explanation of how, if we implement just the
proposed change to BaseException, the user code that Ken's quoting as
having a problem could be improved. There seems to be an assumption of
"and because of that change, people raising exceptions would change
what they do". Frankly, no they wouldn't. There's no demonstrated
benefit for them, and they'd have to maintain a mess of backward
compatibility code. So why would they bother?

Anyway, you were right that I'd replied to just the example, not the
original proposal. I apologise for that, I should have read the thread
more carefully. But if I had done so, it wouldn't have made much
difference - I still don't see a justification for the proposed
change.

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-03 Thread Paul Moore
On 3 July 2017 at 21:56, Jeff Walker  wrote:
> Paul,
>  Indeed, nothing gets better until people change the way they do their
> exceptions. Ken's suggested enhancement to BaseException does not
> directly solve the problem, but it removes the roadblocks that discourage
> people from passing the components to the message.

As noted, I disagree that people are not passing components because
str(e) displays them the way it does. But we're both just guessing at
people's motivations, so there's little point in speculating.

> Seems to me that to address this problem, four things are needed:
> 1. Change BaseException. This allows people to pass the components
> to the message without ruining str(e).

I dispute this is the essential place to start. If nothing else, the
proposed approach encourages people to use a position-based "args"
attribute for exceptions, rather than properly named attributes.

> 2. A PEP that educates the Python community on this better way of
> writing exceptions.

Educating the community can be done right now, and doesn't need a PEP.
Someone could write a blog post, or an article, that explains how to
code exception classes, how to create the exceptions, and how client
code can/should use the API. This can be done now, all you need to do
is to start with "at the moment, BaseException doesn't implement these
features, so you should create an application-specific base exception
class to minimise duplication of code". If project authors take up the
proposed approach, then that makes a good argument for moving the
supporting code into the built in BaseException class.

> 3. Changes to the base language and standard library to employ the
> new approach. These would changes would be quite small and could
> be done opportunistically.

And I've never said that there's a problem with these. Although I do
dispute that using an args list is the best approach here - I'd much
rather see NameError instances have a "name" attribute that had the
name that couldn't be found as its value. Opportunistic changes to
built in exceptions can implement the most appropriate API for the
given exception - why constrain such changes to a "lowest common
denominator" API that is ideal for no-one?

class NameError(BaseException):
def __init__(self, name):
self.name = name
def __str__(self):
return f"name '{self.name}' is not defined"

Of course, that's not backward compatible as it stands, but it could
probably be made so, just as easily as implementing the proposed
solution.

> 4. Time. Over time things will just get better as more people see the
> benefits of this new approach to exceptions and adopt it. And if they
> don't, we are no worse off than we are now.

The same could be said of any improved practice. And I agree, let's
encourage people to learn to write better code, and promote good
practices. There's definitely no reason not to do this.

> And frankly, I don't see any downside. The changes he is proposing are
> tiny and simple and backward compatible.

Well, the main downside I see is that I don't agree that the proposed
changes are the best possible approach. Implementing them in the built
in exceptions therefore makes it harder for people to choose better
approaches (or at least encourages them not to look for better
approaches). There's no way I'd consider that e.args[0] as a better
way to get the name that triggered a NameError than e.name.

This seems to me to be something that should be experimented with and
proven outside of the stdlib, before we rush to change the language. I
don't see anything that makes that impossible.

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-04 Thread Paul Moore
On 4 July 2017 at 06:08, Nick Coghlan  wrote:
> On 4 July 2017 at 09:46, Greg Ewing  wrote:
>> Paul Moore wrote:
>>>
>>> As noted, I disagree that people are not passing components because
>>> str(e) displays them the way it does. But we're both just guessing at
>>> people's motivations, so there's little point in speculating.
>>
>>
>> I've no doubt that the current situation encourages people
>> to be lazy -- I know, because I'm guilty of it myself!
>>
>> Writing a few extra lines to store attributes away and format
>> them in __str__ might not seem like much, but in most cases
>> those lines are of no direct benefit to the person writing
>> the code, so there's little motivation to do it right.
>
> So isn't this a variant of the argument that defining well-behaved
> classes currently involves writing too much boilerplate code, and the
> fact that non-structured exceptions are significantly easier to define
> than structured ones is just an example of that more general problem?
>
> I personally don't think there's anything all *that* special about
> exceptions in this case - they're just a common example of something
> that would be better handled as a "data record" type, but is commonly
> handled as an opaque string because they're so much easier to define
> that way.

Yes, that's what I was (badly) trying to say.

I agree that we could hide a lot of the boilerplate in BaseException
(which is what Ken was suggesting) but I don't believe we yet know the
best way to write that boilerplate, so I'm reluctant to put anything
in the stdlib until we do know better. For now, experimenting with 3rd
party "rich exception" base classes seems a sufficient option. It's
possible that more advanced methods than simply using a base class may
make writing good exception classes even easier, but I'm not sure I've
seen any evidence of that yet.

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-06 Thread Paul Moore
On 6 July 2017 at 02:53, Jeff Walker  wrote:
> Could you please expand on these statements:
>
>>  the idea doesn't actually solve the problem it is intended to
>
> Specifically Ken started by saying that it should not be necessary to parse 
> the
> messages to get the components of the message. He then gave an example
> where he was able to access the components of the message without parsing
> the message. So how is it that he is not solving the problem he intended to 
> solve?

Just to add my perspective here, his proposed solution (to modify
BaseException) doesn't include any changes to the derived exceptions
that would need to store the components. To use the (already
over-used) NameError example, Ken's proposal doesn't include any
change to how NameError exceptions are raised to store the name
separately on the exception.

So *as the proposal stands* it doesn't allow users to extract
components of any exceptions, simply because the proposal doesn't
suggest changing exceptions to *store* those components.

>>  His solution can't work
>
> Again, he gave an example where he was able to access the components of the
> message without parsing the message. Yet you claim his solution cannot work.
> Is his example wrong?

Yes. Because he tries to extract the name component of a NameError,
and yet that component isn't stored anywhere - under his proposal or
under current CPython.

>>  He hasn't demonstrated that there is a real problem
>
> You yourself admitted that parsing a message to extract the components is
> undesirable. Ken and others, including myself, gave examples where this was
> necessary. Each example was given as either being a real problem or
> representative of a real problem. Are we all wrong?

He's given examples of use cases. To that extent, Steven is being a
touch absolute here. However, there has been some debate over whether
those examples are valid. We've had multiple responses pointing out
that the code examples aren't restricting what's in the try block
sufficiently tightly, for example (the NameError case in particular
was importing a file which, according to Ken himself, had potentially
*thousands* of places where NameError could be raised). It's possible
that introspecting exceptions is the right way to design a solution to
this particular problem, but it does go against the normal design
principles that have been discussed on this list and elsewhere many
times. So, to demonstrate that there's a problem, it's necessary to
address the question of whether the code could in fact have been
written in a different manner that avoided the claimed problem.

That's obviously not a black and white situation - making it easier to
write code in a certain style is a valid reason for suggesting an
enhancement - but the debate has edged towards a stance of "this is
needed" (as in, the lack of it is an issue) rather than "this would be
an improvement". That's not what Ken said, though, and we all bear a
certain responsibility for becoming a little too entrenched in our
positions.

As far as whether Steven's (or anyone's) comments are too negative, I
think the pushback is reasonable. In particular, as far as I know Ken
is not a first-time contributor here, so he's almost certainly aware
of the sorts of concerns that come up in discussions like this, and
with that context I doubt he's offended by the reception his idea got
(indeed, his responses on this thread have been perfectly sensible and
positive). I do think we need to be more sensitive with newcomers, and
Chris Angelico's idea of a "falsehoods programmers believe about
python-ideas" collection may well be a good resource to gently remind
newcomers of some of the parameters of discussion around here.

You also say
> but it can be fun and educational to discuss the ideas

Indeed, very much so. I've certainly learned a lot about language and
API design from discussions here over the years. But again, that's the
point - the biggest things I've learned are about how *hard* good
design is, and how important it is to think beyond your own personal
requirements. Most of the "negative" comments I've seen on this list
have been along those lines - reminding people that there's a much
wider impact for their proposals, and that benefits need to be a lot
more compelling than you originally thought. That's daunting, and
often discouraging (plenty of times, I've been frustrated by the fact
that proposals that seem good to be are blocked by the risk that
someone might have built their whole business around a corner case
that I'd never thought of, or cared about). But it's the reality and
it's an immensely valuable lesson to learn (IMO).

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-06 Thread Paul Moore
On 6 July 2017 at 18:59, Mark E. Haase  wrote:
> On Thu, Jul 6, 2017 at 5:58 AM, Paul Moore  wrote:
>>
>> To use the (already
>>
>> over-used) NameError example, Ken's proposal doesn't include any
>> change to how NameError exceptions are raised to store the name
>> separately on the exception.
>
>
> Maybe I'm misunderstanding you, but the proposal has a clear example of
> raising NameError and getting the name attribute from the exception
> instance:

But no-one manually raises NameError, so Ken's example wouldn't work
with "real" NameErrors. If Ken was intending to present a use case
that did involve manually-raised NameError exceptions, then he needs
to show the context to demonstrate why manually raising NameError
rather than a custom exception (which can obviously work like he
wants) is necessary.

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/


Re: [Python-ideas] Arguments to exceptions

2017-07-07 Thread Paul Moore
On 7 July 2017 at 04:54, Jeff Walker  wrote:
> Here is an example:
>
> class NameError(BaseException):
>  pass
>
> try:
> raise NameError('welker', db='users', template='{0}: unknown {db}.')
> except NameError as e:
> unknown_name = e.args[0]
> missing_from = e.kwargs('db')
> print(str(e))
>
> Given this example, please explain why it is you say that the arguments are 
> not
> be stored and are not accessible.

Because the proposal doesn't state that NameError is to be changed,
and the example code isn't real, as it's manually raising a system
exception.

Anyway, I'm tired of this endless debate about what Ken may or may not
have meant. I'm going to bow out now and restrict myself to only
reading and responding to actual proposals.

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/


Re: [Python-ideas] PEP: Hide implementation details in the C API

2017-07-11 Thread Paul Moore
On 11 July 2017 at 11:19, Victor Stinner  wrote:
> XXX should we abandon the stable ABI? Never really used by anyone.

Please don't. On Windows, embedding Python is a pain because a new
version of Python requires a recompile (which isn't ideal for apps
that just want to optionally allow Python scripting, for example).
Also, the recent availability of the embedded distribution on Windows
has opened up some opportunities and I've been using the stable ABI
there.

It's not the end of the world if we lose it, but I'd rather see it
retained (or better still, enhanced).

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/


Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]

2017-07-20 Thread Paul Moore
On 20 July 2017 at 07:58, Nathaniel Smith  wrote:
> From the above it sounds like this ntuple literal idea would be giving
> us a third independent way to solve this niche use case (ntuple,
> namedtuple, structseq). This seems like two too many? Especially given
> that namedtuple is already arguably *too* convenient, in the sense
> that it's become an attractive nuisance that gets used in places where
> it isn't really appropriate.

Agreed. This discussion was prompted by the fact that namedtuple class
creation was slow, resulting in startup time issues. It seems to have
morphed into a generalised discussion of how we design a new "named
values" type. While I know that if we're rewriting the implementation,
that's a good time to review the semantics, but it feels like we've
gone too far in that direction.

As has been noted, the new proposal

- no longer supports multiple named types with the same set of field names
- doesn't allow creation from a simple sequence of values

I would actually struggle to see how this can be considered a
replacement for namedtuple - it feels like a completely independent
beast. Certainly code intended to work on multiple Python versions
would seem to have no motivation to change.

> Also, what's the advantage of (x=1, y=2) over ntuple(x=1, y=2)? I.e.,
> why does this need to be syntax instead of a library?

Agreed. Now that keyword argument dictionaries retain their order,
there's no need for new syntax here. In fact, that's one of the key
motivating reasons for the feature.

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/


Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]

2017-07-20 Thread Paul Moore
On 20 July 2017 at 10:15, Clément Pit-Claudel  wrote:
> On 2017-07-20 11:02, Paul Moore wrote:
>>> Also, what's the advantage of (x=1, y=2) over ntuple(x=1, y=2)? I.e.,
>>> why does this need to be syntax instead of a library?
>>
>> Agreed. Now that keyword argument dictionaries retain their order,
>> there's no need for new syntax here. In fact, that's one of the key
>> motivating reasons for the feature.
>
> Isn't there a speed aspect?  That is, doesn't the library approach require 
> creating (and likely discarding) a dictionary every time a new ntuple is 
> created?  The syntax approach wouldn't need to do that.

I don't think anyone has suggested that the instance creation time
penalty for namedtuple is the issue (it's the initial creation of the
class that affects interpreter startup time), so it's not clear that
we need to optimise that (at this stage). However, it's also true that
namedtuple instances are created from sequences, not dictionaries
(because the class holds the position/name mapping, so instance
creation doesn't need it). So it could be argued that the
backward-incompatible means of creating instances is *also* a problem
because it's slower...

Paul

PS Taking ntuple as "here's a neat idea for a new class", rather than
as a possible namedtuple replacement, changes the context of all of
the above significantly. Just treating ntuple purely as a new class
being proposed, I quite like it, but I'm not sure it's justified given
all of the similar approaches available, so let's see how a 3rd party
implementation fares. And it's too early to justify new syntax, but if
the overhead of a creation function turns out to be too high in
practice, we can revisit that question. But that's *not* what this
thread is about, as I understand 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] namedtuple literals [Was: RE a new namedtuple]

2017-07-24 Thread Paul Moore
On 24 July 2017 at 17:37, Michel Desmoulin  wrote:
> You are in the wrong thread. This thread is specifically about
> namedtupels literal.

In which case, did you not see Guido's post "Honestly I would like to
declare the bare (x=1, y=0) proposal dead."? The namedtuple literal
proposal that started this thread is no longer an option, so can we
move on? Preferably by dropping the whole idea - no-one has to my mind
offered any sort of "replacement namedtuple" proposal that can't be
implemented as a 3rd party library on PyPI *except* the (x=1, y=0)
syntax proposal, and I see no justification for adding a *fourth*
implementation of this type of object in the stdlib (which means any
proposal would have to include deprecation of at least one of
namedtuple, structseq or types.SimpleNamespace).

The only remaining discussion on the table that I'm aware of is how we
implement a more efficient version of the stdlib namedtuple class (and
there's not much of that to be discussed here - implementation details
can be thrashed out on the tracker issue).

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/


Re: [Python-ideas] namedtuple literals [Was: RE a new namedtuple]

2017-07-30 Thread Paul Moore
On 30 July 2017 at 16:24, Nick Coghlan  wrote:
> Rather than being about any changes on that front, these threads are
> mostly about making it possible to write that first line as:
>
> MyNT = type(implicitly_typed_named_tuple_factory(foo=None, bar=None))

Is that really true, though? There's a lot of discussion about whether
ntuple(x=1, y=2) and ntuple(y=2, x=1) are equal (which implies they
are the same type). If there's any way they can be the same type, then
your definition of MyNT above is inherently ambiguous, depending on
whether we've previously referred to
implicitly_typed_named_tuple_factory(bar=None, foo=None).

For me, the showstopper with regard to this whole discussion about
ntuple(x=1, y=2) is this key point - every proposed behaviour has
turned out to be surprising to someone (and not just in a "hmm, that's
odd" sense, but rather in the sense that it'd almost certainly result
in bugs as a result of misunderstood behaviour).

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/


Re: [Python-ideas] "any" and "all" support multiple arguments

2017-08-01 Thread Paul Moore
On 1 August 2017 at 14:01, Louie Lu  wrote:
> I'm not sure if this is discuss before, but can "any" and "all"
> support like min_max "arg1, arg2, *args" style?

I don't see any particular reason why not, but is there a specific use
case for this or is it just a matter of consistency? Unlike max and
min, we already have operators in this case (and/or). I'd imagine that
if I had a use for any(a, b, c) I'd write it as a or b or c, and for
all(a, b, c) I'd write a and b and c.

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/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Paul Moore
On 4 August 2017 at 08:39, Paul Laos  wrote:
> Hi folks
> I was thinking about how sometimes, a function sometimes acts on classes,
> and behaves very much like a method. Adding new methods to classes existing
> classes is currently somewhat difficult, and having pseudo methods would make 
> that
> easier.

Adding new methods to classes is deliberately (somewhat) difficult, as
it makes it harder to locate the definition of a method. If you need
to see the code for a method, you'd expect to look in the class
definition. Making it common for people to put method definitions
outside the class definition harms supportability by breaking that
assumption.

> Code example: (The syntax can most likely be improved upon)
> def has_vowels(self: str):
> for vowel in ["a", "e,", "i", "o", "u"]:
> if vowel in self: return True
>
> This allows one to wring `string.has_vowels()` instead of
> `has_vowels(string)`,
> which would make it easier to read,

That's very much a subjective view. Personally, I don't see
"string.has_vowels()" as being any easier to read - except in the
sense that it tells me that I can find the definition of has_vowels in
the class definition of str (and I can find its documentation in the
documentation of the str type). And your proposal removes this
advantage!

> and would make it easier to add
> functionality to existing classes, without having to extend them. This would
> be useful for builtins or imported libraries, so one can fill in "missing"
> methods.

This is a common technique in other languages like Ruby, but is
considered specialised and somewhat of an advanced technique
(monkeypatching) in Python. As you say yourself, the syntax will make
it *easier* to do this - it's already possible, so the change doesn't
add any new capabilities. Adding new syntax to the language typically
needs a much stronger justification (either in terms of enabling
fundamentally new techniques, or providing a significantly more
natural spelling of something that's widely used and acknowledged as a
common programming idiom).

Sorry, but I'm -1 on this change. It doesn't let people do anything
they can't do now, on the contrary it makes it simpler to use a
technique which has readability and supportability problems, which as
a result will mean that people will be inclined to use the approach
without properly considering the consequences.

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/


Re: [Python-ideas] Pseudo methods

2017-08-04 Thread Paul Moore
On 4 August 2017 at 14:20, Joao S. O. Bueno  wrote:
> Had not this been discussed here earlier this year?
>
> (And despite there being perceived dangers to readability in the long term,
> was accepted?)
>
> Here it is on an archive:
> https://mail.python.org/pipermail/python-ideas/2017-February/044551.html

>From a very brief review of the end of that thread, it looks like it
was agreed that a PEP might be worthwhile - it was expected to be
rejected, though, and the PEP would simply document the discussion and
the fact that the idea was rejected. This agrees with my recollection
of the discussion, as well. But as far as I'm aware, no-one ever wrote
that PEP. (Not surprising, I guess, as it's hard to get enthusiastic
about proposing an idea you know in advance will be rejected).

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/


Re: [Python-ideas] Generator syntax hooks?

2017-08-10 Thread Paul Moore
On 10 August 2017 at 14:42, Steven D'Aprano  wrote:
> I don't think it is confusing. Regardless of the implementation, the
> meaning of:
>
> [expression for x in sequence while condition]
>
> should (I believe) be obvious to anyone who already groks comprehension
> syntax. The mapping to a for-loop is admittedly a tad more complex:
>
> result = []
> for x in sequence:
> if not condition: break
> result.append(expression)
>
> but I'm yet to meet anyone who routinely and regularly reads
> comprehensions by converting them to for loops like that. And if they
> did, all they need do is mentally map "while condition" to "if not
> condition: break" and it should all Just Work™.

The hard part is the interaction between if and while.

Consider (expr for var in seq if cond1 while cond2):

This means:

for var in seq:
if cond1:
if not cond2: break
yield expr

Note that unlike all other comprehension clauses (for and if) while
doesn't introduce a new level of nesting. That's an inconsistency, and
while it's minor, it would need clarifying (my original draft of this
email was a mess, because I misinterpreted how if and while would
interact, precisely over this point). Also, there's a potential issue
here - consider

[expr for var in even_numbers() if is_odd(var) while var < 100]

This is an infinite loop, even though it has a finite termination
condition (var < 100), because we only test the termination condition
if var is odd, which it never will be.

Obviously, this is a contrived example. And certainly "don't do that,
then" is a valid response. But my instinct is that people are going to
get this wrong - *especially* in a maintenance environment. That
example could have started off being "for var in count(0)" and then
someone realised they could "optimise" it by omitting odd numbers,
introducing the bug in the process. (And I'm sure real life code could
come up with much subtler examples ;-))

Overall, I agree with Steven's point. It seems pretty obvious what the
intention is, and while it's probably possible to construct examples
that are somewhat unclear,

1. The mechanical rule gives an explicit meaning
2. People shouldn't be writing such complex comprehensions, so if the
rule doesn't give what they expect, they can always rewrite the code
with an explicit (and clearer) loop.

But while I think this says that the above interpretation of while is
the only sensible one, and in general other approaches are unlikely to
be as natural, I *don't* think that it unequivocally says that
allowing while is a good thing. It may still be better to omit it, and
force people to state their intent explicitly (albeit a bit more
verbosely).

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/


Re: [Python-ideas] Generator syntax hooks?

2017-08-10 Thread Paul Moore
On 10 August 2017 at 21:25, Chris Barker  wrote:
> On Thu, Aug 10, 2017 at 8:39 AM, Paul Moore  wrote:
>
>>
>>  Also, there's a potential issue
>> here - consider
>>
>> [expr for var in even_numbers() if is_odd(var) while var < 100]
>>
>> This is an infinite loop, even though it has a finite termination
>> condition (var < 100), because we only test the termination condition
>> if var is odd, which it never will be.
>
>
> why is the termination only tested if teh if clause is True? Could then not
> be processed in parallel? or the while first

See? That's my point - the "obvious" interpretation stops being
obvious pretty fast...

> so maybe better to do:
>
> [expr for var in even_numbers() while var < 100 if is_odd(var)]

That would work. But I bet people's intuition wouldn't immediately
lead to that fix (or indeed, necessarily incline them to put the
clauses in this order in the first place).

> Maybe it's just me, but I would certainly expect the while to have
> precedence.
>
> I guess I think of it like this:
>
> "if" is providing a filtering mechanism
>
> "while" is providing a termination mechanism
>
>  -- is there a use case anyone can think of when they would want the while
> to be applied to the list AFTER filtering?

Probably not, but when you can have multiple FORs, WHILEs and IFs, in
any order, explaining the behaviour precisely while still preserving
some sense of "filtering comes after termination" is going to be
pretty difficult. [expr for var1 in seq1 if cond1 for var2 in seq2 for
var3 in seq3 if cond2 if cond3] is legal - stupid, but legal. Now add
while clauses randomly in that, and define your expected semantics
clearly so a user (and the compiler!) can determine what the resulting
mess means.

The main benefit of the current "works like a for loop" interpretation
is that it's 100% explicit. Nothing will make a mess like the above
good code, but at least it's well-defined.

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/


Re: [Python-ideas] Generator syntax hooks?

2017-08-11 Thread Paul Moore
On 11 August 2017 at 05:49, Steven D'Aprano  wrote:
> On Thu, Aug 10, 2017 at 01:25:24PM -0700, Chris Barker wrote:
>> On Thu, Aug 10, 2017 at 8:39 AM, Paul Moore  wrote:
>>
>>
>> >  Also, there's a potential issue
>> > here - consider
>> >
>> > [expr for var in even_numbers() if is_odd(var) while var < 100]
>> >
>> > This is an infinite loop, even though it has a finite termination
>> > condition (var < 100), because we only test the termination condition
>> > if var is odd, which it never will be.
>
> I'm not sure why Paul thinks this is an issue. There are plenty of ways
> to accidentally write an infinite loop in a comprehension, or a for
> loop, already:

Mostly because I work in a support and maintenance environment, where
we routinely see code that *originally* made sense, but which was over
time modified in ways that break things - usually precisely because
coders who in theory understand how to write such things correctly,
end up not taking the time to fully understand the constructs they are
modifying. Of course that's wrong, but it's sadly all too common, and
for that reason I'm always wary of constructs that need thinking
through carefully to understand the implications.

Nick's original

{x for x in itertools.count(0) if 1000 <= x while x < 100}

was like that. It was *sort of* obvious that it meant "numbers between
1_000 and 1_000_000, but the interaction between "if" and "while"
wasn't clear to me. If I were asked to rush in a change to only pick
odd numbers,

{x for x in itertools.count(0) if 1000 <= x and is_odd(x) while x < 100}

seems right to me, but quick - what about edge cases? It's not that I
can't get it right, nor is it that I can't test that I *did* get it
right, just that this sort of "quick fix" is very common in the sort
of real-world coding I see regularly, and a huge advantage of Python
is that it's hard to get in a situation where the obvious guess is
wrong.

Don't get me wrong - I'm not arguing that the sky is falling. Just
that this construct isn't as easy to understand as it seems at first
(and that hard-to-understand cases appear *before* you hit the point
where it's obvious that the statement is too complex and should be
refactored.

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/


Re: [Python-ideas] Remote package/module imports through HTTP/S

2017-08-23 Thread Paul Moore
On 23 August 2017 at 18:49, Chris Angelico  wrote:
> Still -1 on this becoming a stdlib package, as there's nothing I've
> yet seen that can't be done as a third-party package. But it's less
> scary than I thought it was :)

IMO, this would make a great 3rd party package (I note that it's not
yet published on PyPI). It's possible that it would end up being
extremely popular, and recognised as sufficiently secure - at which
point it may be worth considering for core inclusion. But it's also
possible that it remains niche, and/or people aren't willing to take
the security risks that it implies, in which case it's still useful to
those who do like it.

One aspect that hasn't been mentioned yet - as a 3rd party module, the
user (or the organisation's security team) can control whether or not
the ability to import over the web is available by controlling whether
the module is allowed to be installed - whereas with a core module,
it's there, like it or not, and *all* Python code has to be audited on
the assumption that it might be used. I could easily imagine cases
where the httpimport module was allowed on development machines and CI
servers, but forbidden on production (and pre-production) systems.
That option simply isn't available if the feature is in the core.

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/


Re: [Python-ideas] tarfile.extractall progress

2017-09-01 Thread Paul Moore
On 1 September 2017 at 12:50, Tarek Ziadé  wrote:
> Hey,
>
> For large archives, I want to display a progress bar while the archive
> is being extracted with:
>
> https://docs.python.org/3/library/tarfile.html#tarfile.TarFile.extractall
>
> I could write my own version of extractall() to do this, or maybe we
> could introduce a callback option that gets called
> everytime .extract() is called in extractall()
>
> The callback can receive the tarinfo object and where it's being
> extracted. This is enough to plug a progress bar
> and avoid reinventing .extractall()
>
> I can add a ticket and maybe a patch if people think this is a good
> little enhancement

Sounds like a reasonable enhancement, but for your particular use
couldn't you just subclass TarFile and call your progress callback at
the end of the extract method after the base class extract?

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/


Re: [Python-ideas] if as

2017-09-07 Thread Paul Moore
On 7 September 2017 at 11:43, Denis Krienbühl  wrote:
> What I would love to see is the following syntax instead, which to me is much 
> cleaner:
>
>if computation() as result:
>do_something_with_result(result)

Hi - thanks for your suggestion! This has actually come up quite a lot
in the past. Here's a couple of links to threads you might want to
read (it's not surprising if you missed these, it's not that easy to
come up with a good search term for this topic).

https://mail.python.org/pipermail/python-ideas/2012-January/013461.html
https://mail.python.org/pipermail/python-ideas/2009-March/003423.html
  (This thread includes a note by Guido that he intentionally left out
this functionality)

In summary, it's a reasonably commonly suggested idea, but there's not
enough benefit to warrant adding it to the language.

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/


Re: [Python-ideas] PEP 554: Stdlib Module to Support Multiple Interpreters in Python Code

2017-09-07 Thread Paul Moore
On 7 September 2017 at 19:26, Eric Snow  wrote:
> As part of the multi-core work I'm proposing the addition of the
> "interpreters" module to the stdlib.  This will expose the existing
> subinterpreters C-API to Python code.  I've purposefully kept the API
> simple.  Please let me know what you think.

Looks good. I agree with the idea of keeping the interface simple in
the first instance - we can easily add extra functionality later, but
removing stuff (or worse still, finding that stuff we thought was OK
but had missed corner cases of was broken) is much harder.

>run(code):
>
>   Run the provided Python code in the interpreter, in the current
>   OS thread.  Supported code: source text.

The only quibble I have is that I'd prefer it if we had a
run(callable, *args, **kwargs) method. Either instead of, or as well
as, the run(string) one here.

Is there any reason why passing a callable and args is unsafe, and/or
difficult? Naively, I'd assume that

interp.call('f(a)')

would be precisely as safe as

interp.call(f, a)

Am I missing something? Name visibility or scoping issues come to mind
as possible complications I'm not seeing. At the least, if we don't
want a callable-and-args form yet, a note in the PEP explaining why
it's been omitted would be worthwhile.

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/


Re: [Python-ideas] PEP 554: Stdlib Module to Support Multiple Interpreters in Python Code

2017-09-07 Thread Paul Moore
On 7 September 2017 at 20:14, Eric Snow  wrote:
> On Thu, Sep 7, 2017 at 11:52 AM, Paul Moore  wrote:
>> Is there any reason why passing a callable and args is unsafe, and/or
>> difficult? Naively, I'd assume that
>>
>> interp.call('f(a)')
>>
>> would be precisely as safe as
>>
>> interp.call(f, a)
>
> The problem for now is with sharing objects between interpreters.  The
> simplest safe approach currently is to restrict execution to source
> strings.  Then there are no complications.  Interpreter.call() makes
> sense but I'd like to wait until we get feel for how subinterpreters
> get used and until we address some of the issues with object passing.

Ah, OK. so if I create a new interpreter, none of the classes,
functions, or objects defined in my calling code will exist within the
target interpreter? That makes sense, but I'd missed that nuance from
the description. Again, this is probably worth noting in the PEP.

And for the record, based on that one fact, I'm perfectly OK with the
initial API being string-only.

> FWIW, here are what I see as the next steps for subinterpreters in the stdlib:
>
> 1. add a basic queue class for passing objects between interpreters
> * only support strings at first (though Nick pointed out we could
> fall back to pickle or marshal for unsupported objects)
> 2. implement CSP on top of subinterpreters
> 3. expand the queue's supported types
> 4. add something like Interpreter.call()
>
> I didn't include such a queue in this proposal because I wanted to
> keep it as focused as possible.  I'll add a note to the PEP about
> this.

This all sounds very reasonable. Thanks for the clarification.
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/


Re: [Python-ideas] Hexadecimal floating literals

2017-09-21 Thread Paul Moore
On 21 September 2017 at 02:53, Steven D'Aprano  wrote:
> On Thu, Sep 21, 2017 at 11:13:44AM +1000, Nick Coghlan wrote:
>
>> I think so, as consider this question: how do you write a script that
>> accepts a user-supplied string (e.g. from a CSV file) and treats it as
>> hex floating point if it has the 0x prefix, and decimal floating point
>> otherwise?
>
> float.fromhex(s) if s.startswith('0x') else float(s)
>
> [...]
>> And if the float() builtin were to gain a "base" parameter, then it's
>> only a short step from there to allow at least the "0x" prefix on
>> literals, and potentially even "0b" and "0o" as well.
>>
>> So I'm personally +0 on the idea
>
> I agree with your arguments. I just wish I could think of a good reason
> to make it +1 instead of a luke-warm +0.

I'm also +0.

I think +0 is pretty much the correct response - it's OK with me, but
someone who actually needs or wants the feature will need to implement
it.

It's also worth remembering that there will be implementations other
than CPython that will need changes, too - Jython, PyPy, possibly
Cython, and many editors and IDEs. So setting the bar at "someone who
wants this will have to step up and provide a patch" seems reasonable
to me.

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/


Re: [Python-ideas] allow overriding files used for the input builtin

2017-09-29 Thread Paul Moore
On 29 September 2017 at 11:25, Steven D'Aprano  wrote:
> I like it very much.
>
> But as an alternative, perhaps all we really need is a context manager
> to set the std* files:
>
> with open('/dev/tty', 'r+') as f:
> with stdio(stdin=f, stdout=f):
> name = input('Name? ')
>
> print(name)
>
>
> That's nearly as nice, and is possibly useful in more situations. Or
> maybe we should have both?

Agreed - a general way of redirecting stdio would be more generally
useful - I've often replaced stdio, but as far as I can recall never
for input().

There's already contextlib.redirect_stdout() and
contextlib.redirect_stderr(). Adding contextlib.redirect_stdin() would
be logical, but I think a more flexible

contextlib.redirect_stdio(stdin=None, stdout=None, stderr=None)

would be better - where None (the default) means "leave this alone".

>> Would love to see if anyone else is interested in this. I think it's
>> pretty cool that the core logic really didn't need to be changed other
>> than plumbing in the new args.
>
> Definitely interested!

I'm interested in the general context manager. I don't use input()
enough to be particularly interested in a solution specific to that
function.

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/


Re: [Python-ideas] Ternary operators in list comprehensions

2017-10-05 Thread Paul Moore
>>> a = [1,2,3]
>>> [x if x & 1 else 'even' for x in a]
[1, 'even', 3]

You're mixing the if clause of the list comprehension up with a
ternary expresssion. There's no "else" in the list comprehension if
clause.

Paul

On 5 October 2017 at 16:40, Jason H  wrote:
 a = [1,2,3]
 [ x for x  in a if x & 1]
> [1, 3]
 [ x for x  in a if x & 1 else 'even']
>   File "", line 1
> [ x for x  in a if x & 1 else 'even']
> ^
> SyntaxError: invalid syntax
>
> I expected [1, 'even', 3]
>
> I would expect that the if expression would be able to provide alternative 
> values through else.
>
> The work around blows it out to:
> l = []
> for x in a:
>   if x&1:
> l.append(x)
>   else:
> l.append('even')
>
>
> Unless there is a better way?
> ___
> 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] PEP draft: context variables

2017-10-13 Thread Paul Moore
On 13 October 2017 at 19:32, Yury Selivanov  wrote:
>>> It seems simpler to have one specially named and specially called function
>>> be special, rather than make the semantics
>>> more complicated for all functions.
>>
>
> It's not possible to special case __aenter__ and __aexit__ reliably
> (supporting wrappers, decorators, and possible side effects).
>
>> +1.  I think that would make it much more usable by those of us who are not
>> experts.
>
> I still don't understand what Steve means by "more usable", to be honest.

I'd consider myself a "non-expert" in async. Essentially, I ignore it
- I don't write the sort of applications that would benefit
significantly from it, and I don't see any way to just do "a little
bit" of async, so I never use it.

But I *do* see value in the context variable proposals here - if only
in terms of them being a way to write my code to respond to external
settings in an async-friendly way. I don't follow the underlying
justification (which is based in "we need this to let things work with
async/coroutines) at all, but I'm completely OK with the basic idea
(if I want to have a setting that behaves "naturally", like I'd expect
decimal contexts to do, it needs a certain amount of language support,
so the proposal is to add that). I'd expect to be able to write
context variables that my code could respond to using a relatively
simple pattern, and have things "just work". Much like I can write a
context manager using @contextmanager and yield, and not need to
understand all the intricacies of __enter__ and __exit__. (BTW,
apologies if I'm mangling the terminology here - write it off as part
of me being "not an expert" :-))

What I'm getting from this discussion is that even if I *do* have a
simple way of writing context variables, they'll still behave in ways
that seem mildly weird to me (as a non-async user). Specifically, my
head hurts when I try to understand what that decimal context example
"should do". My instincts say that the current behaviour is wrong -
but I'm not sure I can explain why. So on that example, I'd ask the
following of any proposal:

1. Users trying to write a context variable[1] shouldn't have to jump
through hoops to get "natural" behaviour. That means that suggestions
that the complexity be pushed onto decimal.context aren't OK unless
it's also accepted that the current behaviour is wrong, and the only
reason decimal.context needs to replicated is for backward
compatibility (and new code can ignore the problem).
2. The proposal should clearly establish what it views as "natural"
behaviour, and why. I'm not happy with "it's how decimal.context has
always behaved" as an explanation. Sure, people asking to break
backward compatibility should have a good justification, but equally,
people arguing to *preserve* an unintuitive current behaviour in new
code should be prepared to explain why it's not a bug. To put it
another way, context variables aren't required to be bug-compatible
with thread local storage.

[1] I'm assuming here that "settings that affect how a library behave"
is a common requirement, and the PEP is intended as the "one obvious
way" to implement them.

Nick's other async refactoring example is different. If the two forms
he showed don't behave identically in all contexts, then I'd consider
that to be a major problem. Saying that "coroutines are special" just
reads to me as "coroutines/async are sufficiently weird that I can't
expect my normal patterns of reasoning to work with them". (Apologies
if I'm conflating coroutines and async incorrectly - as a non-expert,
they are essentially indistinguishable to me). I sincerely hope that
isn't the message I should be getting - async is already more
inaccessible than I'd like for the average user.

The fact that Nick's async example immediately devolved into a
discussion that I can't follow at all is fine - to an extent. I don't
mind the experts debating implementation details that I don't need to
know about. But if you make writing context variables harder, just to
fix Nick's example, or if you make *using* async code like (either of)
Nick's forms harder, then I do object, because that's affecting the
end user experience.

In that context, I take Steve's comment as meaning "fiddling about
with how __aenter__ and __aexit__ work is fine, as that's internals
that non-experts like me don't care about - but making context
variables behave oddly because of this is *not* fine".

Apologies if the above is unhelpful. I've been lurking but not
commenting here, precisely because I *am* a non-expert, and I trust
the experts to build something that works. But when non-experts were
explicitly mentioned, I thought my input might be useful.

The following quote from the Zen seems particularly relevant here:

If the implementation is hard to explain, it's a bad idea.

(although the one about needing to be Dutch to understand why
something is obvious might well trump it ;-))

Paul
__

Re: [Python-ideas] PEP draft: context variables

2017-10-14 Thread Paul Moore
On 14 October 2017 at 08:09, Nick Coghlan  wrote:
> To try and bring this back to synchronous examples that folks may find more
> intuitive, I figure it's worth framing the question this way: do we want
> people to reason about context variables like the active context is
> implicitly linked to the synchronous call stack, or do we want to encourage
> them to learn to reason about them more like they're a new kind of closure?

I'm really struggling to keep up here. I need to go and fully read the
PEP as Yury suggested, and focus on what's in there. But I'll try to
answer this comment. I will ask one question, though, based on Yury's
point "the PEP is where you should look for the actual semantics" -
can you state where in the PEP is affected by the answer to this
question? I want to make sure that when I read the PEP, I don't miss
the place that this whole discussion thread is about...

I don't think of contexts in terms of *either* the "synchronous call
stack" (which, by the way, is much too technical a term to make sense
to the "non-expert" people around here like me - I know what the term
means, but only in a way that's far to low-level to give me an
intuitive sense of what contexts are) or closures.

At the risk of using another analogy that's unfamiliar to a lot of
people, I think of them in terms of Lisp's dynamic variables. Code
that needs a context variable, gets the value that's current *at that
time*. I don't want to have to think lower level than that - if I have
to, then in my view there's a problem with a *different* abstraction
(specifically async ;-))

To give an example:

async def get_webpage(id):
url = f"https://{server}/{app}/items?id={id}";
# 1
encoding, content = await url_get(url)
#2
return content.decode(encoding)

I would expect that, if I set a context variable at #1, and read it at #2, then:

1. code run as part of url_get would see the value set at 1
2. code run as part of url_get could set the value, and I'd see
the new value at 2

It doesn't matter what form the lines in the function take (loops,
with statements, conditionals, ...) as long as they are run
immediately (class and function definitions should be ignored -
there's no lexical capture of context variables). That probably means
"synchronous call stack" in your terms, but please don't assume that
any implications of that term which aren't covered by the above
example are obvious to me.

To use the decimal context example:

> with decimal.localcontext() as ctx:
> ctx.prec = 30
> for i in gen():
>pass

There's only one setting of a context here, so it's obvious - values
returned from gen have precision 30.

> g = gen()
> with decimal.localcontext() as ctx:
> ctx.prec = 30
> for i in g:
>   pass

"for i in g" is getting values from the generator, at a time when the
precision is 30, so those values should have precision 30.

There's no confusion here to me. If that's not what decimal currently
does, I'd happily report that as a bug.

The refactoring case is similarly obvious to me:

>async def original_async_function():
> with some_context():
> do_some_setup()
> raw_data = await some_operation()
> data = do_some_postprocessing(raw_data)
>
> Refactored:
>
>async def async_helper_function():
> do_some_setup()
> raw_data = await some_operation()
> return do_some_postprocessing(raw_data)
>
>async def refactored_async_function():
> with some_context():
> data = await async_helper_function()
>

All we've done here is take some code out of the with block and write
it as a helper. There should be no change of semantics when doing so.
That's a fundamental principle to me, and honestly I don't see it as
credible for anyone to say otherwise. (Anyone who suggests that is
basically saying "if you use async, common sense goes out of the
window" as far as I'm concerned).

> The reason I ask that is because there are three "interesting" times in the
> life of a coroutine or generator:
>
> - definition time (when the def statement runs - this determines the lexical
> closure)
> - instance creation time (when the generator-iterator or coroutine is
> instantiated)
> - execution time (when the frame actually starts running - this determines
> the runtime call stack)

OK. They aren't *really* interesting to me (they are a low-level
detail, but they should work to support intuitive semantics, not to
define what my intuition should be) but I'd say that my expectation is
that the *execution time* value of the context variable is what I'd
expect to get and set.

> For synchronous functions, instance creation time and execution time are
> intrinsically linked, since the execution frame is allocated and executed
> directly as part of calling the function.
>
> For asynchronous operations, there's more of a question, since actual
> execution

Re: [Python-ideas] PEP draft: context variables

2017-10-14 Thread Paul Moore
On 14 October 2017 at 17:50, Nick Coghlan  wrote:
> On 14 October 2017 at 21:56, Paul Moore  wrote:
>
> TL;DR of below: PEP 550 currently gives you what you're after, so your
> perspective counts as a preference for "please don't eagerly capture the
> creation time context in generators or coroutines".

Thank you. That satisfies my concerns pretty well.

> The suggestion has been made that we should instead be capturing the active
> context when "url_get(url)" is called, and implicitly switching back to that
> at the point where await is called. It doesn't seem like a good idea to me,
> as it breaks the "top to bottom" mental model of code execution (since the
> "await cr" expression would briefly switch the context back to the one that
> was in effect on the "cr = url_get(url)" line without even a nested suite to
> indicate that we may be adjusting the order of code execution).

OK. Then I think that's a bad idea - and anyone proposing it probably
needs to explain much more clearly why it might be a good idea to jump
around in the timeline like that.

> If you capture the context eagerly, then there are fewer opportunities to
> get materially different values from "data = list(iterable)" and "data =
> iter(context_capturing_iterable)".
>
> While that's a valid intent for folks to want to be able to express, I
> personally think it would be more clearly requested via an expression like
> "data = iter_in_context(iterable)" rather than having it be implicit in the
> way generators work (especially since having eager context capture be
> generator-only behaviour would create an odd discrepancy between generators
> and other iterators like those in itertools).

OK. I understand the point here - but I'm not sure I see the practical
use case for iter_in_context. When would something like that be used?

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/


Re: [Python-ideas] PEP draft: context variables

2017-10-15 Thread Paul Moore
On 15 October 2017 at 05:39, Nick Coghlan  wrote:
> On 15 October 2017 at 05:47, Paul Moore  wrote:
>>
>> On 14 October 2017 at 17:50, Nick Coghlan  wrote:
>> > If you capture the context eagerly, then there are fewer opportunities
>> > to
>> > get materially different values from "data = list(iterable)" and "data =
>> > iter(context_capturing_iterable)".
>> >
>> > While that's a valid intent for folks to want to be able to express, I
>> > personally think it would be more clearly requested via an expression
>> > like
>> > "data = iter_in_context(iterable)" rather than having it be implicit in
>> > the
>> > way generators work (especially since having eager context capture be
>> > generator-only behaviour would create an odd discrepancy between
>> > generators
>> > and other iterators like those in itertools).
>>
>> OK. I understand the point here - but I'm not sure I see the practical
>> use case for iter_in_context. When would something like that be used?
>
>
> Suppose you have some existing code that looks like this:
>
> results = [calculate_result(a, b) for a, b in data]
>
> If calculate_result is context dependent in some way (e.g. a & b might be
> decimal values), then eager evaluation of "calculate_result(a, b)" will use
> the context that's in effect on this line for every result.
>
> Now, suppose you want to change the code to use lazy evaluation, so that you
> don't need to bother calculating any results you don't actually use:
>
> results = (calculate_result(a, b) for a, b in data)
>
> In a PEP 550 world, this refactoring now has a side-effect that goes beyond
> simply delaying the calculation: since "calculate_result(a, b)" is no longer
> executed immediately, it will default to using whatever execution context is
> in effect when it actually does get executed, *not* the one that's in effect
> on this line.
>
> A context capturing helper for iterators would let you decide whether or not
> that's what you actually wanted by instead writing:
>
> results = iter_in_context(calculate_result(a, b) for a, b in data)
>
> Here, "iter_in_context" would indicate explicitly to the reader that
> whenever another item is taken from this iterator, the execution context is
> going to be temporarily reset back to the way it was on this line. And since
> it would be a protocol based iterator-in-iterator-out function, you could
> wrap it around *any* iterator, not just generator-iterator objects.

OK, got it. That sounds to me like a candidate for a stdlib function
(either because it's seen as a common requirement, or because it's
tricky to get right - or both). The PEP doesn't include it, as far as
I can see, though.

But I do agree with MAL, it seems wrong to need a helper for this,
even though it's a logical consequence of the other semantics I
described as intuitive :-(

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/


Re: [Python-ideas] PEP draft: context variables

2017-10-15 Thread Paul Moore
On 15 October 2017 at 06:43, Nick Coghlan  wrote:
> On 15 October 2017 at 15:05, Guido van Rossum  wrote:
>>
>> I would like to reboot this discussion (again). It feels to me we're
>> getting farther and farther from solving any of the problems we might solve.
>>
>> I think we need to give up on doing anything about generators; the use
>> cases point in too many conflicting directions. So we should keep the
>> semantics there, and if you don't want your numeric or decimal context to
>> leak out of a generator, don't put `yield` inside `with`. (Yury and Stefan
>> have both remarked that this is not a problem in practice, given that there
>> are no bug reports or StackOverflow questions about this topic.)
>
>
> Let me have another go at building up the PEP 550 generator argument from
> first principles.
>
> The behaviour that PEP 550 says *shouldn't* change is the semantic
> equivalence of the following code:
>
> # Iterator form
> class ResultsIterator:
> def __init__(self, data):
> self._itr = iter(data)
> def __next__(self):
> return calculate_result(next(self._itr))
>
> results = _ResultsIterator(data)
>
> # Generator form
> def _results_gen(data):
> for item in data:
> yield calculate_result(item)
>
> results = _results_gen(data)
>
> This *had* been non-controversial until recently, and I still don't
> understand why folks suddenly decided we should bring it into question by
> proposing that generators should start implicitly capturing state at
> creation time just because it's technically possible for them to do so (yes
> we can implicitly change the way all generators work, but no, we can't
> implicitly change the way all *iterators* work).

This is non-controversial to me.

> The behaviour that PEP 550 thinks *should* change is for the following code
> to become roughly semantically equivalent, given the constraint that the
> context manager involved either doesn't manipulate any shared state at all
> (already supported), or else only manipulates context variables (the new
> part that PEP 550 adds):
>
> # Iterator form
> class ResultsIterator:
> def __init__(self, data):
> self._itr = iter(data)
> def __next__(self):
> with adjusted_context():
> return calculate_result(next(self._itr))
>
> results = _ResultsIterator(data)
>
> # Generator form
> def _results_gen(data):
> for item in data:
> with adjusted_context():
> yield calculate_result(item)
>
> results = _results_gen(data)
>
> Today, while these two forms look like they *should* be comparable, they're
> not especially close to being semantically equivalent, as there's no
> mechanism that allows for implicit context reversion at the yield point in
> the generator form.

I'll have to take your word for this, as I can't think of an actual
example that follows the pattern of your abstract description, for
which I can immediately see the difference.

In the absence of being able to understand why the difference matters
in current code, I have no view on whether PEP 550 needs to "fix" this
issue.

> While I think PEP 550 would still be usable without fixing this discrepancy,
> I'd be thoroughly disappointed if the only reason we decided not to do it
> was because we couldn't clearly articulate the difference in reasoning
> between:
>
> * "Generators currently have no way to reasonably express the equivalent of
> having a context-dependent return statement inside a with statement in a
> __next__ method implementation, so let's define one" (aka "context variable
> changes shouldn't leak out of generators, as that will make them *more* like
> explicit iterator __next__ methods"); and
> * "Generator functions should otherwise continue to be unsurprising
> syntactic sugar for objects that implement the regular iterator protocol"
> (aka "generators shouldn't implicitly capture their creation context, as
> that would make them *less* like explicit iterator __init__ methods").

I think that if we can't describe the problem that makes it obvious to
the average Python user, then that implies it's a corner case that's
irrelevant to said average Python user - and so I'd consider fixing it
to be low priority. Specifically, a lot lower priority than providing
a context variable facility - which while still not a *common* need,
at least resonates with the average user in the sense of "I can
imagine writing code that needed context like Decimal does".

(And apologies for presenting an imagined viewpoint as what "the
average user" might think...)

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/


Re: [Python-ideas] PEP draft: context variables

2017-10-15 Thread Paul Moore
On 13 October 2017 at 23:30, Yury Selivanov  wrote:
> At this point of time, there's just one place which describes one well
> defined semantics: PEP 550 latest version.  Paul, if you have
> time/interest, please take a look at it, and say what's confusing
> there.

Hi Yury,
The following is my impressions from a read-through of the initial
part of the PEP. tl; dr - you say "concurrent" too much and it makes
my head hurt :-)

1. The abstract feels like it's talking about async. The phrase
"consistent access to non-local state in the context of out-of-order
execution, such as in Python generators and coroutines" said async to
me, even though it mentioned generators. Probably because any time I
see generators mentioned alongside coroutines (a term I really don't
grasp yet in the context of Python) I immediately assume the reference
is to the weird extensions of generators when send() and yield
expressions are used. It quite genuinely took me two or three attempts
to get past the abstract and actually read the next section, because
the "this is async" idea came across so strongly.

2. The rationale says that "Prior to the advent of asynchronous
programming in Python" threads and TLS were used - and it implies this
was fine. But the section goes on to say "TLS does not work well for
programs which execute concurrently in a single thread". But it uses a
*generator* as the example. I'm sorry, but to me a generator is pure
and simple standard Python, and definitely not "executing concurrently
in a single thread" (see below). So again, the clash between what the
description said and the actual example left me confused (and confused
enough to equate all of this in my mind with "all that async stuff I
don't follow").

3. "This is because implicit Decimal context is stored as a
thread-local, so concurrent iteration of the fractions() generator
would corrupt the state." This makes no sense to me. The example isn't
concurrent. There's only one thread, and no async. So no concurrency.
It's interleaved iteration through two generators, which I understand
is *technically* considered concurrency in the async sense, but
doesn't *feel* like concurrency. At its core, this is the problem I'm
hitting throughout the whole document - the conceptual clash between
examples that don't feel concurrent, and discussions that talk almost
totally in terms of concurrency, means that understanding every
section is a significant mental effort.

4. By the end of the rationale, what I'd got from the document was:
"There's a bug in decimal.context, caused by the fact that it uses
TLS. It's basically a limitation of TLS. To fix it they need a new
mechanism, which this PEP provides." So unless I'm using (or would
expect to use) TLS in my own code, this doesn't affect me. Which
really isn't the point (if I now understand correctly) - the PEP is
actually providing a safe (and hopefully easy to use/understand!)
mechanism for handling a specific class of programming problem,
maintaining dynamic state that follows the execution order of the
code, rather than the lexical structure. (I didn't state that well -
but I hope I got the idea across) Basically, the problem that Lisp
dynamic variables are designed to solve (although I don't think that
describing the feature in terms of Lisp is a good idea either).

4a. I'd much prefer this part of the PEP to be structured as follows:

* There's a class of programming problems that need to allow code
to access "state" in a way that follows the runtime path the code
takes. Prior art in this area include Lisp's dynamic scope, ... (more
examples would be good - IIRC, Perl has this type of variable too).
* Normal local variables can't do this as they are lexically
scoped. Global variables can be used, but they don't work in the
presence of threads.
* TLS work for threads, but hit problems when code execution paths
aren't nested subroutine-style. Examples where this happens are
generators (which suspend execution and yield back to their parent),
and async (which simulates multiple threads by interleaving execution
of generators). [Note - I know this explanation is probably
inaccurate]
* This PEP proposes a general mechanism that will allow
programmers to simply write code that manages state like this, which
will work in all of the above cases.

That's it. Barely any mention of async, no need to focus on the
Decimal bug except as a motivating example of why TLS isn't
sufficient, and so no risk that people think "why not just fix
decimal.context" - so no need to go into detail as to why you can't
"just fix it". And it frames the PEP as providing a new piece of
functionality that *anyone* might find a use for, rather than as a fix
for a corner case of async/TLS interaction.

5. The "Goals" section says "provide a more reliable threading.local()
alternative" which is fine. But the bullet points do exactly the same
as before, using terms that I associate with async to describe the
benefits, and so the

Re: [Python-ideas] PEP draft: context variables

2017-10-15 Thread Paul Moore
On 15 October 2017 at 13:51, Amit Green  wrote:
> Once again, I think Paul Moore gets to the heart of the issue.
>
> Generators are simply confusing & async even more so.
>
> Per my earlier email, the fact that generators look like functions, but are
> not functions, is at the root of the confusion.

I don't agree. I don't find generators *at all* confusing. They are a
very natural way of expressing things, as has been proven by how
popular they are in the Python community.

I don't *personally* understand async, but I'm currently willing to
reserve judgement until I've been in a situation where it would be
useful, and therefore needed to learn it.

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/


Re: [Python-ideas] Membership of infinite iterators

2017-10-18 Thread Paul Moore
On 18 October 2017 at 10:56, Koos Zevenhoven  wrote:
> I'm unable to reproduce the "uninterruptible with Ctrl-C" problem with
> infinite iterators. At least itertools doesn't seem to have it:
>
 import itertools
 for i in itertools.count():
> ... pass
> ...
> ^CTraceback (most recent call last):
>   File "", line 1, in 
> KeyboardInterrupt

That's not the issue here, as the CPython interpreter implements this
with multiple opcodes, and checks between opcodes for Ctrl-C. The
demonstration is:

>>> import itertools
>>> 'x' in itertools.count()

... only way to break out is to kill the process.
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/


Re: [Python-ideas] Membership of infinite iterators

2017-10-18 Thread Paul Moore
On 18 October 2017 at 16:27, Koos Zevenhoven  wrote:
> So you're talking about code that would make a C-implemented Python iterable
> of strictly C-implemented Python objects and then pass this to something
> C-implemented like list(..) or sum(..), while expecting no Python code to be
> run or signals to be checked anywhere while doing it. I'm not really
> convinced that such code exists. But if such code does exist, it sounds like
> the code is heavily dependent on implementation details.

Well, the OP specifically noted that he had recently encountered
precisely that situation:

"""
I recently came across a bug where checking negative membership
(__contains__ returns False) of an infinite iterator will freeze the
program.
"""

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/


Re: [Python-ideas] Membership of infinite iterators

2017-10-18 Thread Paul Moore
OK, looks like I've lost track of what this thread is about then.
Sorry for the noise.
Paul

On 18 October 2017 at 16:40, Koos Zevenhoven  wrote:
> On Wed, Oct 18, 2017 at 6:36 PM, Paul Moore  wrote:
>>
>> On 18 October 2017 at 16:27, Koos Zevenhoven  wrote:
>> > So you're talking about code that would make a C-implemented Python
>> > iterable
>> > of strictly C-implemented Python objects and then pass this to something
>> > C-implemented like list(..) or sum(..), while expecting no Python code
>> > to be
>> > run or signals to be checked anywhere while doing it. I'm not really
>> > convinced that such code exists. But if such code does exist, it sounds
>> > like
>> > the code is heavily dependent on implementation details.
>>
>> Well, the OP specifically noted that he had recently encountered
>> precisely that situation:
>>
>> """
>> I recently came across a bug where checking negative membership
>> (__contains__ returns False) of an infinite iterator will freeze the
>> program.
>> """
>>
>
> No, __contains__ does not expect no python code to be run, because Python
> code *can* run, as Serhiy in fact already demonstrated for another purpose:
>
> On Wed, Oct 18, 2017 at 3:53 PM, Serhiy Storchaka 
> wrote:
>>
>> 18.10.17 13:22, Nick Coghlan пише:
>>>
>>> 2.. These particular cases can be addressed locally using existing
>>> protocols, so the chances of negative side effects are low
>>
>>
>> Only the particular case `count() in count()` can be addressed without
>> breaking the following examples:
>>
>> >>> class C:
>> ... def __init__(self, count):
>> ... self.count = count
>> ... def __eq__(self, other):
>> ... print(self.count, other)
>> ... if not self.count:
>> ... return True
>> ... self.count -= 1
>> ... return False
>> ...
>> >>> import itertools
>> >>> C(5) in itertools.count()
>> 5 0
>> 4 1
>> 3 2
>> 2 3
>> 1 4
>> 0 5
>> True
>
>
>
> Clearly, Python code *does* run from within itertools.count.__contains__(..)
>
>
> ––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] Dollar operator suggestion

2017-10-26 Thread Paul Moore
On 26 October 2017 at 13:53, Daniel Moisset  wrote:
> This is to clarify that this si NOT about function composition, just an 
> alternate
> application syntax

The idea is already dead, based on the quote from Guido, but this
makes it even more clear that it's inappropriate for Python. As you
said (in part that I trimmed) Haskell uses single-argument functions
plus currying to implement function calls. This is extremely common
for functional languages, as it matches the theoretical basis much
better. As you point out, the shell pipeline model is actually quite
similar (a single input, chain of processing model).

Procedural languages, and Python in particular, simply don't work like
that. Functions have arbitrary numbers of arguments, currying is not
built in, composition is not a fundamental operation in the same way.
Although it's possible to explain how a `$` style syntax would work,
it doesn't fit naturally into the language - certainly not naturally
enough to warrant being part of the language syntax.

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/


Re: [Python-ideas] Defining an easily installable "Recommended baseline package set"

2017-10-29 Thread Paul Moore
On 29 October 2017 at 07:54, Nick Coghlan  wrote:
> On 29 October 2017 at 15:16, Guido van Rossum  wrote:
>>
>> Why? What's wrong with pip install?
>
> At a technical level, this would just be a really thin wrapper around 'pip
> install' (even thinner than ensurepip in general, since these libraries
> *wouldn't* be bundled for offline installation, only listed by name).

I agree with Guido, this doesn't seem to add much as stated.

(From an earlier message of Nick's)
> At the same time, it would be beneficial to have a way to offer an even
> stronger recommendation to redistributors that we think full-featured
> general purpose Python scripting environments should offer the regex
> module as an opt-in alternative to the baseline re feature set, since that
> would also help with other currently difficult cases like the requests module.

This is key to me. The target area is *scripting*. Library and
application developers have their own ways of managing the dependency
handling problem, and they generally work fine. The people who don't
currently have a good solution are those who just use the system
install - i.e., people writing adhoc scripts, people writing code that
they want to share with other members of their organisation, via
"here's this file, just run it", and not as a full application. For
those people "not in a standard install" is a significantly higher
barrier to usage than elsewhere. "Here's a Python file, just install
Python and double click on the file" is a reasonable request. Running
pip may be beyond the capabilities of the recipient.

In my view, the key problems in this area are:

1. What users writing one-off scripts can expect to be available.
2. Corporate environments where "adding extra software" is a major hurdle.
3. Offline environments, where PyPI isn't available.

The solutions to these issues aren't so much around how we let people
know that they should do "pip install" (or "--install-recommended")
but rather around initial installs. To that end I'd suggest:

1. The python.org installers gain an "install recommended 3rd party
packages" option, that is true by default, which does "pip install
". This covers (1) and (2) above, as it makes
the recommended package set the norm, and ensures that they are
covered by an approval to "install Python".
2. For offline environments, we need to do a little more, but I'd
imagine having the installer look for wheels in the same directory as
the installer executable, and leave it to the user to put them there.
If wheels aren't available the installer should warn but continue.

For 3rd party distributions (Linux, Homebrew, Conda, ...) this gives a
clear message that Python users are entitled to expect these modules
to be available. Handling that expectation is down to those
distributions.

Things I haven't thought through:

1. System vs user site-packages. If we install (say) requests into the
system site-packages, the user could potentially need admin rights to
upgrade it. Or get into a situation where they have an older version
in site-packages and a newer one in user-site (which I don't believe
is a well-tested scenario),
2. Virtual environments. Should venv/virtualenv include the
recommended packages by default? Probably not, but that does make the
"in a virtual environment" experience different from the system Python
experience.
3. The suggestion above for offline environments isn't perfect, by any
means. Better solutions would be good here (but I don't think we want
to go down the bundling route like we did with pip...?).

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/


Re: [Python-ideas] Defining an easily installable "Recommended baseline package set"

2017-10-29 Thread Paul Moore
On 29 October 2017 at 09:51, Antoine Pitrou  wrote:
> On Sun, 29 Oct 2017 17:54:22 +1000
> Nick Coghlan  wrote:
>> This means that
>> if educators aren't teaching them, or redistributors aren't providing them,
>> then they're actively doing their users a disservice
>
> Which redistributors do not provide the requests library, for example?
> regex is probably not as popular (mostly because re is good enough for
> most purposes), but it still appears to be available from Ubuntu and
> Anaconda.

I know it's not what you meant, but "the python.org installers" is the
obvious answer here. On Windows, if you say to someone "install
Python", they get the python.org distribution. Explicitly directing
them to Anaconda is an option, but that gives them a distinctly
different experience than "standard Python plus some best of breed
packages like requests" does.

>> All the proposal does is to suggest taking those existing recommendations
>> from the documentation and converting them into a more readibly executable
>> form.
>
> I'm curious what such a list looks like :-)

I am also. I'd put requests on it immediately, but that's the only
thing I consider obvious. regex is what triggered this, but I'm not
sure it adds *that* much - it's a trade off between people who need
the extra features and people confused over why we have two regex
libraries available. After that, you're almost immediately into
domain-specific answers, and it becomes tricky fast.

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/


Re: [Python-ideas] Defining an easily installable "Recommended baseline package set"

2017-10-29 Thread Paul Moore
On 29 October 2017 at 10:40, Stephan Houben  wrote:
> Perhaps slightly off-topic, but I have sometimes wondered if
> pip could not be made somewhat friendlier for the absolute newbie
> and the classroom context.
>
> Some concrete proposals.
>
> 1. Add a function `pip` to the interactive interpreter
>   (similar to how `help` is available).
>
>   def pip(args):
>   import sys
>   import subprocess
>   subprocess.check_call([sys.executable, "-m", "pip"] + args.split())
>
>This allows people to install something using pip as long as they have a
>Python prompt open, and avoids instructors to have to deal with
> platform-specific
>instructions for various shells. Also avoids confusion when multiple
> Python interpreters
>are available (it operates in the context of the current interpreter.)

There are subtle issues around whether newly installed/upgraded
packages are visible in a running Python interpreter. It's possible
that this would result in *more* confusion than the current situation.
I can see the appeal of something like this, but it's not as simple as
it looks. If you want to discuss this further, I'd definitely suggest
making it a thread of its own. Personally, as a pip maintainer, I'm -0
on this (possibly even -1).

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/


Re: [Python-ideas] Defining an easily installable "Recommended baseline package set"

2017-10-29 Thread Paul Moore
On 29 October 2017 at 18:56, Guido van Rossum  wrote:
> The two use cases you describe (scripters and teachers) leave me luke-warm
> -- scripters live in the wild west and can just pip install whatever (that's
> what it means to be scripting)

In my experience, "scripting" *does* include people for whom "being in
a standard Python distribution" is a requirement.

Situations I have encountered:

1. Servers where developers need to write administrative or monitoring
scripts, but they don't control what's on that server. The Python
installation that comes by default is all that's available.
2. Developers working in environments with limited internet access.
For example, my employer has a Windows (NTLM) proxy that pip can't
work with. Getting internet access for pip involves installing a
separate application, and that's not always possible/desirable.
3. Developers writing scripts to be shared with non-developers. On
Unix, this means "must work with the system Python", and on Windows
"download and install Python from python.org" is typically all you can
expect (although in that case "install Anaconda" is a possible
alternative, although not one I've tried telling people to do myself).

Nick's proposal doesn't actually help for (1) or (2), as the problem
there is that "pip install" won't work. And bundling a script with its
(pure Python) dependencies, for example as a zipapp, is always a
solution - although it's nowhere near as easy as simply copying a
single-file script to the destination where it's to be run. So these
situations don't actually matter in terms of the value of the
proposals being discussed here. But I did want to dispute the idea
that "scripters can just pip install whatever" is inherent to the idea
of being a scripter - my experience is the opposite, that scripters
are the people *least* able to simply pip install things.

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/


Re: [Python-ideas] install pip packages from Python prompt

2017-10-29 Thread Paul Moore
On 29 October 2017 at 19:40, Stephan Houben  wrote:
> Hi Antoine,
>
> 2017-10-29 20:31 GMT+01:00 Antoine Rozo :
>>
>> Hi,
>>
>> What would be the difference with current pip module?
>> pip.main(['install', 'some_package'])
>
>
>
> My understanding is that direct use of the `pip` module is explicitly not
> recommended.

Not only not recommended, but explicitly not supported. And it won't
be available at all in pip 10.

Having said that, I'm -1 on this proposal. Installing new modules (or
upgrading existing ones) in a running Python process has all sorts of
subtle issues - the need to reload already-loaded modules, the fact
that failed imports may have resulted in different code paths being
taken ("except ImportError"), etc. Exiting the Python process to run
pi avoids all of these.

For someone who doesn't understand the difference between the Python
REPL and the command prompt, offering an interface that exposes them
to these sort of potential issues won't actually help them. Better to
teach them the basics of what a command line is, and what an
interactive Python prompt is, before exposing them to subtleties like
this.

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/


Re: [Python-ideas] Defining an easily installable "Recommended baseline package set"

2017-10-29 Thread Paul Moore
On 29 October 2017 at 20:44, Alex Walters  wrote:
> Writing scripts for non-developers, in an unmanaged environment (IT cant
> push a python install to the system) on windows means running pyinstaller
> et. al., on your script, if it has dependencies or not.  Its not worth it to
> walk someone through a python install to run a script, let alone installing
> optional dependencies.

Let's just say "not in the environments I work in", and leave it at that.

> Not to sound too crass, but there are only so many edge cases
> that a third party platform developer can be expected to care about (enough
> to bend over backwards to support).

I never suggested otherwise. I just wanted to point out that
"scripting in Python" covers a wider range of use cases than "can use
pip install". I'm not asking python-dev to support those use cases
(heck, I'm part of python-dev and *I* don't want to bend over
backwards to support them), but I do ask that people be careful not to
dismiss a group of users who are commonly under-represented in open
source mailing lists and communities.

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/


Re: [Python-ideas] install pip packages from Python prompt

2017-10-30 Thread Paul Moore
On 30 October 2017 at 15:53, Antoine Pitrou  wrote:
> On Tue, 31 Oct 2017 01:44:10 +1000
> Nick Coghlan  wrote:
>>
>> A few specific notes here:
>>
>> 1. As you say, this sort of already works in notebooks, since instructors
>> can say to run "!pip install requests" and then restart the language kernel.
>> 2. We could probably replicate that style in IDLE, since that runs user
>> code in a subprocess, similar to the way Jupyter language kernels are
>> separate from the frontend client
>> 3. We can't replicate it as readily in the regular REPL, since that runs
>> Python code directly in the current process, but even there I believe we
>> could potentially trigger a full process restart via execve (or the C++
>> style _execve on Windows)
>>
>> (We'd want a real process restart, rather than emulating it by calling
>> Py_Initialize & Py_Finalize multiple times, as not every module properly
>> supports multiple initialise/finalise cycles within a single process, and
>> module-specific quirks are exactly what we'd be trying to avoid by forcing
>> an interpreter restart)
>
> The main difference, though, is that a notebook will reload and
> replay all your session, while restarting the regular REPL will simply
> lose all current work.  I think that makes the idea much less
> appealing.

Also, on Windows, I believe that any emulation of execve either leaves
the original process in memory, or has problems getting console
inheritance right. It's been a long time since I worked at that level,
and things may be better now, but getting a robust "restart this
process" interface in Windows would need some care (that's one of the
reasons the py launcher runs Python as a subprocess rather than doing
any sort of exec equivalent).

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/


Re: [Python-ideas] install pip packages from Python prompt

2017-10-30 Thread Paul Moore
On 30 October 2017 at 16:22, Nick Coghlan  wrote:
>> Also, on Windows, I believe that any emulation of execve either leaves
>> the original process in memory, or has problems getting console
>> inheritance right. It's been a long time since I worked at that level,
>> and things may be better now, but getting a robust "restart this
>> process" interface in Windows would need some care (that's one of the
>> reasons the py launcher runs Python as a subprocess rather than doing
>> any sort of exec equivalent).
>
> As long as the standard streams are passed along correctly, whatever the py
> launcher does would presumably be adequate for a REPL restart as well,
> assuming we decided to go down that path.

The py launcher starts a subprocess for python.exe and waits on it. I
wouldn't have thought that's going to work for installing mods in a
REPL - imagine a long working session where I install 10 mods as I
explore options for a particular problem (I don't know how likely that
is in practice...) - there'd be a chain of 10+ Python processes, only
the last of which is still useful. It's probably not a massive problem
(I assume everything but the last process is paged out) but it's not
exactly friendly.

OTOH, if you lose the command history and the interpreter state after
each install, you'll probably get fed up long before the number of
processes is an issue...

> It would also be reasonable to say that the regular REPL just issues a
> warning that a restart might be needed, and it's only REPLs with a separate
> client process that offer a way to restart the subprocess where code
> actually executes.

This feels awfully like the traditional Windows "your mouse has moved
- please reboot to have your changes take effect" behaviour. I don't
think we're going to impress many people emulating that :-(

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/


Re: [Python-ideas] Moving typing out of the stdlib in Python 3.7?

2017-11-05 Thread Paul Moore
On 5 November 2017 at 10:48, Antoine Pitrou  wrote:
> On Sun, 5 Nov 2017 13:46:59 +1000
> Nick Coghlan  wrote:
>> * ensurepip gains the ability to also install bundled wheel files
>
> Why? Why wouldn't you put the wheel directly in site-packages on
> install?

I'm not quite sure what you mean? It needs to be "installed", in the
sense of being unpacked into site-packages, and the ensurepip
mechanism is already able to do that for pip and setuptools, so adding
an extra wheel to install wouldn't be too hard. If we don't install
like that, people won't be able to easily upgrade typing by just using
"pip install --upgrade typing".

Wheels don't support simply being added to sys.path the way that eggs
did, if that's what you mean.

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/


Re: [Python-ideas] Moving typing out of the stdlib in Python 3.7?

2017-11-05 Thread Paul Moore
On 5 November 2017 at 14:47, Antoine Pitrou  wrote:
>
> Le 05/11/2017 à 14:30, Paul Moore a écrit :
>> On 5 November 2017 at 10:48, Antoine Pitrou  wrote:
>>> On Sun, 5 Nov 2017 13:46:59 +1000
>>> Nick Coghlan  wrote:
>>>> * ensurepip gains the ability to also install bundled wheel files
>>>
>>> Why? Why wouldn't you put the wheel directly in site-packages on
>>> install?
>>
>> I'm not quite sure what you mean? It needs to be "installed", in the
>> sense of being unpacked into site-packages, and the ensurepip
>> mechanism is already able to do that for pip and setuptools, so adding
>> an extra wheel to install wouldn't be too hard.
>
> Ok, perhaps my question wasn't quite clear.  Are you suggesting that
> people have to run "python -m ensurepip typing" after they installed
> Python?  Or would the typing module be importable as soon as you have an
> installed Python, like stdlib modules are?

Ah, I get you now. I'd expect typing to be available exactly the same
way as pip is. For me (on Windows) that means that it's available in a
standard install. On Unix, I don't know (I think there's certain
situations where you need to take extra steps in a custom build to
ensure pip is available? I'd expect those steps to also install
typing.

So basically, yes, typing can be expected to be available in all
installations, exactly the same as pip is.

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/


Re: [Python-ideas] Moving typing out of the stdlib in Python 3.7?

2017-11-05 Thread Paul Moore
On 5 November 2017 at 18:40, Antoine Pitrou  wrote:
> I think typing shouldn't require any extra typing (ha) on Unix either.
> I don't remember what the rationale was for having to type
> "python -m ensurepip" to get pip installed, but typing is just a
> library, not an executable tool that may be able to mess with the
> system state, so I don't think it's worthwhile introducing an extra
> step for it.

Yes, I agree. I didn't realise that "give me pip" was an extra step on
Unix. I don't know what the arguments for doing it like that on Unix
were, but they certainly don't seem to apply to typing.

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/


Re: [Python-ideas] Moving typing out of the stdlib in Python 3.7?

2017-11-06 Thread Paul Moore
On 6 November 2017 at 06:42, Lukasz Langa  wrote:
>> Now it's annoying already. Because you have to write every tutorial to
>> include a special case for them. But at least it's not a required step
>> to run your program.
>>
>> However, if you do code using type hints and typing is not installed,
>> you can't even run the program without installing something. So we
>> finally have Python 3 by default on most Linux system, but still would
>> not be able to assume we can run a modern script on it.
>
> This is a valid concern. Although this particular problem is self-inflicted 
> by Debian, I can understand their rationale behind explicit packaging. They 
> need to have control over the entire package graph.

It's also a problem for virtual environments, which won't include
typing by default, and don't see the system installed packages. As
Nick says, we could modify venv to always include typing, but most
users, and all tools (tox, pew, pipenv, etc) use virtualenv rather
than venv still, so this would be of very limited benefit.

> I wonder if there's a way in .deb to specify a required installed package. 
> I'm not calling it a "dependency" since obviously it would rather be 
> "python3-typing" that depends on "python3". Barry, do you know?

There's always "include typing in the standard library" :-)

> But even if Debian installs python3-typing by default, will "pip install -U 
> typing" be possible in this scenario? I guess it wouldn't be terrible if that 
> only worked in virtualenvs, although ideally it would work also for the raw 
> host installation.

It would push yet more people into doing "sudo pip install -U typing",
which is something we've been trying really hard to encourage them to
stop doing over on the pip issues list. We strongly recommend using
system supplied packages, but I'd be surprised if Debian is any more
able to keep up with the latest versions of typing than Python core
is.

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/


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

2017-11-07 Thread Paul Moore
On 7 November 2017 at 12:44, Nick Coghlan  wrote:
>> - make sure the system path is correctly set
>
> Recent python.org Windows installers do this automatically, but there
> are unfortunately still lots of ways for things to go wrong.

I believe the latest installers switch it off again, because one of
the ways things can go wrong is that stuff put at the start of the
user path is still lower priority than stuff in the system path, and
we now default to user installs. This is an actual problem with mixed
python.org and Anaconda installations, for example - Anaconda adds
itself to the system PATH, and overrides a default user install of
python.org Python. So you can't prioritise python.org over Anaconda
without manual path hacking. (This hit me when I installed Visual
Studio and selected "include Python (Anaconda)" - I can't recall the
exact option, but it broke my python.org install).

As you say command-line environments are just inherently user-hostile,
and we can't do a lot about that. People who buy into the command line
experience learn how to deal with the complexity. People who use IDEs
like Visual Studio or PyCharm can rely on the IDE vendor to provide a
clean experience. But people who want to use core Python but who
aren't comfortable fighting with the command line have a bit of a
problem. We can't solve that problem for them, the best we can do is
offer suggestions on best practices, or tools that help alleviate the
issues.

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/


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

2017-11-07 Thread Paul Moore
On 7 November 2017 at 13:06, אלעזר  wrote:
> On Tue, Nov 7, 2017 at 2:45 PM Nick Coghlan  wrote:
>>
>> On 7 November 2017 at 03:52, Michel Desmoulin 
>> wrote:
>>
>> > And assume that stuff in any tutorial you make they know this stuff.
>> >
>> > This is a strong barrier or entry IMO.
>>
>> Sure, but it's not one we can readily fix - the user hostility of
>> command line environments and the compromises we have to make to abide
>> by platform conventions are in the hands of operating system vendors,
>> and there's only so much we can do to paper over those distinctions
>> when user lock-in and putting barriers in the way of cross-device
>> portability is a core part of commercial OS vendors' business models.
>>
>
> I don't know if you are referring to Microsoft Windows here, but I want to
> note that from my personal experience the Windows subsystem for Linux ("Bash
> on Ubuntu on Windows") is easy to work with, so making Windows feel
> (CLI-wise) like Ubuntu is not so difficult. I'm not sure how easy it is for
> students to set up, but it is an option at least.

It is, but like any such approach (Cygwin is similar, in principle if
not in execution) that makes one OS "look like" another, whether it's
appropriate is very dependent on circumstances. Training potential
Windows developers in a bash/Ubuntu style environment leaves them at a
disadvantage when they need to develop for actual Windows
environments.

It's certainly an option, but so is "train them on Linux".
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/


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

2017-11-07 Thread Paul Moore
On 7 November 2017 at 20:38, Chris Barker  wrote:
> On Tue, Nov 7, 2017 at 5:04 AM, Thomas Jollans  wrote:
>>
>> As Ivan said earlier, perhaps the Windows installers should provide a
>> "python3" executable, so "python3 -m pip" works everywhere.
>
> absolutely! I really, really thought it did (I'm amazed I never heard
> from a single student getting bit by that...)

On Windows, use py -X.Y to select the exact version of Python you
want. Maybe Unix should have a launcher like this, too? It doesn't
really need to be any more complex than


exec pythonX.Y $@

relying on the existence of versioned executables on Unix. (Excuse my
garbled don't-really-know-how-to-do-it shell scripting...)

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/


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

2017-11-10 Thread Paul Moore
On 10 November 2017 at 08:01, Nick Coghlan  wrote:
> You can't have it both ways - the only way we can systematically mask
> the environmental differences between Windows, Linux and Mac OS X is
> by providing tooling that actually masks those differences, which
> means introducing that tooling becomes a prerequisite for teaching.

On Windows, which is the only platform I can reasonably comment on,
the killer issue is that the installer doesn't make the commands
"python" and "pip" available by default. Just checking my PC, both go
and rust (which I installed *ages* ago) do appear to, so they "just
work". Java sort-of also works like that (the runtime is on PATH, but
the compilers need to be added manually).

The biggest reason we don't add Python to PATH, as I understand it, is
because we need to consider the implications of people having multiple
versions of Python installed. As far as I know, no other language
allows that. But equally, most beginners wouldn't actually *have*
multiple versions installed. So maybe we should optimise for that case
(only one version of Python installed). That would mean:

1. Go back to adding Python to PATH. Because our installers don't say
"do you want to uninstall the old version", we should probably do a
check for a "python" command on PATH in the installer, and if there is
one, warn the user "You already have Python installed - if you are
upgrading you should manually uninstall the old version first,
otherwise your old installation will remain the default". We could get
more complex at this point, but that depends on what capabilities we
can include in the installer - I don't know how powerful the toolset
is.
2. Explicitly document that multiple Python interpreters on one
machine is considered "advanced", and users with that sort of setup
should be prepared to manage PATH themselves. I'd put that as
something like "It is possible to install multiple versions of Python
at once, but if you do that, you should understand the implications -
the average user should not need to do this".

We still have to deal with the fact that basically every Unix
environment is "advanced" in the above sense (the python2/python3
split). I don't have a solution for that (other than "upgrade to
Windows" ;-)).

> It doesn't completely solve the problem (as getting into and out of
> the environment is still platform specific), but it does mean that the
> ubiquitous online instructions to run "pip install package-name" and
> "python -m command" will actually work once people are inside their
> working environment.
>
> That tooling is venv:
>
> * it ensures you have "pip" on your PATH
> * it ensures you have "python" on your PATH
> * it ensures that you have the required permissions to install new packages
> * it ensures that any commands you install from PyPI will be also on your PATH
>
> When we choose not to use venv, then it becomes necessary to ensure
> each of those things individually for each potential system starting
> state

Currently, the reality is that people use virtualenv, not venv. All
higher-level tools I'm aware of wrap virtualenv (to allow Python 2.7
support). Enhancing the capabilities of venv is fine, but promoting
venv over virtualenv involves technical challenges across the whole
toolset, not just documentation/education.

But agreed, once we get people into a virtual environment (of any
form) the portability issues become significantly reduced. The main
outstanding issue is managing multiple environments, which could be
handled by having a special "default" environment that is the only one
we'd expect beginners to use/need.

> That said, we'd *like* the default to be is per-user package
> installations into the user home directory, but that creates
> additional problems:
>
> * "python" may be missing, and you'll have to use "python3" or "py" instead
> * "pip" may be missing (or mean "install for Python 2.7")
> * you have to specify "--user" on *every* call to pip, and most online
> guides won't say that
> * there's a major backwards compatibility problem with switching pip
> over to per-user package installs as the default (we still want to do
> it eventually, though)
> * on Windows, system-wide Python installs can't adjust per-user PATH
> settings, and per-user installs are subject to being broken by
> system-wide installs
> * on Windows, the distinction between a per-user install of Python,
> and per-user installs of a package is hard to teach
> * on Debian, I believe ~/.local/bin still isn't on PATH by default

Also on Windows, the per-user bin directory isn't added to PATH even
if you add the system Python to PATH in the installer.

> That said, I think there is one improvement we could feasibly make,
> which would be to introduce the notion of a "default user environment"
> into `venv`, such that there was a single "python -m venv shell"
> command that:
>
> * created a default user environment if it didn't already exist
> * launched a subshell with that environment alre

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

2017-11-10 Thread Paul Moore
On 10 November 2017 at 10:01, Nick Coghlan  wrote:
> On 10 November 2017 at 19:50, Paul Moore  wrote:
>> On 10 November 2017 at 08:01, Nick Coghlan  wrote:
>>> That tooling is venv:
>>>
>>> * it ensures you have "pip" on your PATH
>>> * it ensures you have "python" on your PATH
>>> * it ensures that you have the required permissions to install new packages
>>> * it ensures that any commands you install from PyPI will be also on your 
>>> PATH
>>>
>>> When we choose not to use venv, then it becomes necessary to ensure
>>> each of those things individually for each potential system starting
>>> state
>>
>> Currently, the reality is that people use virtualenv, not venv. All
>> higher-level tools I'm aware of wrap virtualenv (to allow Python 2.7
>> support). Enhancing the capabilities of venv is fine, but promoting
>> venv over virtualenv involves technical challenges across the whole
>> toolset, not just documentation/education.
>
> We already assume there will be a step in understanding from "working
> with the latest Python 3.x locally" to "dealing with multiple Python
> versions". Switching from venv to virtualenv just becomes part of that
> process (and will often be hidden behind a higher level tool like
> pipenv, pew, or vex anyway).

OK, that's fair.
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/


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

2017-11-10 Thread Paul Moore
On 10 November 2017 at 11:37, Oleg Broytman  wrote:
> On Fri, Nov 10, 2017 at 07:48:35AM +0100, Michel Desmoulin 
>  wrote:
>> On linux you
>> can't pip install, you need --users, admin rights or a virtualenv.
>
>Isn't it the same on Windows? For an admin-installed Python you need
> --users, admin rights or a virtualenv. And a user-installed Python on
> Windows is equivalen to a user-compiled Python on Linux -- pip installs
> packages to the user-owned site-packages directory.

It is - but the default install on Windows (using the python.org
installer) is a per-user install. So beginners don't encounter
admin-installed Python (unless they ask for it, in which case they
made the choice so they should understand the implications ;-))

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/


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

2017-11-12 Thread Paul Moore
On 12 November 2017 at 06:19, Michel Desmoulin
 wrote:
>> 1. Go back to adding Python to PATH. Because our installers don't say
>> "do you want to uninstall the old version", we should probably do a
>> check for a "python" command on PATH in the installer, and if there is
>> one, warn the user "You already have Python installed - if you are
>> upgrading you should manually uninstall the old version first,
>> otherwise your old installation will remain the default". We could get
>> more complex at this point, but that depends on what capabilities we
>> can include in the installer - I don't know how powerful the toolset
>> is.
>
> You don't even have to do that. We can detect it and prompt : "which
> python version do you want to be available by default ?", and then list
> command to run the alternative versions.

I deliberately avoided suggesting automatically changing the default
version, because that's fraught with problems. You need to remove the
previous default from PATH, and if you're doing a user install but the
previous version is in the system PATH you don't have the privileges
to do that. If the previous version was another distribution (e.g.
Anaconda) you've no way to know that and conversely you don't know how
to remove that distribution's path entries (is there a Scripts
directory to remove, did they use bin instead, etc). The list of
potential problems is endless.

>> We still have to deal with the fact that basically every Unix
>> environment is "advanced" in the above sense (the python2/python3
>> split). I don't have a solution for that (other than "upgrade to
>> Windows" ;-)).
>
> Provide the "py" command on linux and mac. And make it the default
> recommended way in the documentation.

+1 from me.

> Well, not exactly. Do you do python -m venv, or py -x.x -m venv or
> pythonx -m venv ? Wait, it's not installed by default on debian.

Seriously? Debian don't provide venv in the standard Python install?
That's just broken.

> Virtualenvs are a hard tool to use for beginners.

Agreed. Genuine beginners just install Python, then use it. If they
install extra packages, they want them to be available to all of their
scripts.

> A lot of people on this list have forgotten their early years it seems.

Maybe. But the default beginner approach *does* have its problems, and
guiding beginners to a better approach is a good idea. It's just that
the starting point needs to be showing them why the problems solved by
tools like virtualenv matter to them.

At this point, though, we've moved into a much bigger issue than "it's
hard to get started with pip". We should keep the discussion focused
on the immediate problem, and not try to solve everything at once.

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/


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

2017-11-12 Thread Paul Moore
On 12 November 2017 at 13:18, Nick Coghlan  wrote:
>> Seriously? Debian don't provide venv in the standard Python install?
>> That's just broken.
>
> Yup. And RHEL/CentOS don't provide Python 3.x by default at all - you
> need to grab it via other means.

Wow. I have no problem with not providing Python 3 by default, but
shipping a version that omits features that are non-optional parts of
the standard library is ridiculous. I'm getting more and more inclined
to make my default response to bug reports from people on
Debian/Ubuntu be "report it to your vendor or demonstrate it on a
vanilla build of Python" :-(

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/


Re: [Python-ideas] venv *is* provided in the standard Python install on Debian/Ubuntu

2017-11-12 Thread Paul Moore
On 12 November 2017 at 18:38, Antoine Pitrou  wrote:
> On Sun, 12 Nov 2017 12:20:45 +
> Paul Moore  wrote:
>>
>> > Well, not exactly. Do you do python -m venv, or py -x.x -m venv or
>> > pythonx -m venv ? Wait, it's not installed by default on debian.
>>
>> Seriously? Debian don't provide venv in the standard Python install?
>> That's just broken.
>
> Frankly, I don't know where the current discussion comes from, but on
> two recent Debian and Ubuntu setups, I get:
>
> $ dpkg -S /usr/lib/python3.5/venv/__init__.py
> libpython3.5-stdlib:amd64: /usr/lib/python3.5/venv/__init__.py
>
>
> Which, for the uninitiated, means "the venv module is provided by the
> Debian/Ubuntu package named libpython3.5-stdlib".  That package is, in
> turn, a dependency of the "python3.5" package.

Thanks for the clarification. I was surprised by the assertion, but
didn't have a Debian system to check, so it's good to know it's false.

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/


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

2017-11-13 Thread Paul Moore
On 13 November 2017 at 18:57, Chris Barker  wrote:
> This has gotten to be a big thread, and it's a pretty intractable problem,
> but I think there are a few fairly small things that could be done to at
> least make it a bit easier:

In principle, I agree with the ideas here, but there are some
practical issues that make them somewhat less straightforward than we
might like.

> 1) Add python2.exe and python3.exe files to the Windows installers -- am I
> insane or did Windows used to have that? I really think it did -- maybe got
> removed when py.exe was added.

I don't think Windows ever had python2.exe/python3.exe, but I could be wrong.

The only possible way we'd get a python2.exe is by adding it to future
releases of Python 2.7, and we shouldn't be recommending Python 2 for
new users anyway. And I'm strongly -1 on promoting "python3.exe" as
the canonical way of getting Python 3. The python3 command is a result
of the Unix issues around switching to Python 3 as the default, and we
shouldn't perpetuate that approach on Windows, where it's unneeded.

Having said that, I don't object to including versioned executables as
a convenience (if it is one). I just dislike promoting the use of them
via standard documentation.

>   1a) alternatively, we could add a "py" executable to the standard linux
> builds, so there would be THAT one way to do it. But I think that's a "BAD
> IDEA" -- the whole "py" thing is not widely know or used, it's not going to
> show up in package install instructions for a LONG time, (actualy we could
> do both anyway)

I think that getting a "py" launcher on Unix is a lost cause at this
stage. It would be nice, and maybe if the original PEP had proposed a
cross-platform py command, it might have worked, but that's history
now, and I think the py launcher will probably always be a
Windows-only thing.

> Then "python2 -m pip install" would work everywhere (only with new
> installations, but at least with newbies, that's a bit more likely ...)

No newcomer should *ever* be getting told to use "python2 -m pip
install". Maybe "python3 -m pip install", but never Python 2 (outside
of specialised environments where training people in an out of date
version is required). And of course not all Unix distributions come
with Python 3 installed (Mac OS being an obvious example, and I think
Nick mentioned CentOS and RHEL) so python3 won't work everywhere
either...

> 2) Make adding to the PATH in Windows the default. I think there are really
> three user groups:
>
>- newbies starting from scratch -- they want it on the PATH
>
>- newbies with whatever left over cruft from previous installations on
> their systems -- they want it at the FRONT of their PATH. They SHOULD
> uninstall all the cruft, but if they don't this will still work with as few
> surprises a possible.
>
>- not-newbies with a previous version of python they need to continue
> using. They can uncheck the box, or use py.exe

Unfortunately, adding Python to the *front* of PATH is not possible.
It might be the best option, but it simply cannot be done. A per-user
install of Python (the default in Python 3.5+) does not have the
privileges to add items to the front of the system PATH, so the best
we can do is add it to the front of the user PATH. But the system PATH
always goes ahead of the user PATH, and system installs (for example,
default installs of Python 2.x or 3.4 or earlier) will come before
that. (Making a system install of Python be the default won't work
either, as then pip won't work from a normal prompt and we have the
same issues on Windows that Unix users have that results in people
doing "sudo pip install" with all the issues that brings).

So for (1) I agree. For (2) it simply isn't possible. For (3) you're
getting beyond newcomer so sure, "manually handle it" is a reasonable
option.

There's also the problem that file associations (i.e., what does
double clicking on a .py/.pyw file do) don't follow the same rules, as
they go through the launcher.

The only really sensible "do what I expect" situation is a single
Python 3 installation on the user's machine. For that case, adding
Python to PATH (it doesn't matter where as there's only one) is a
sensible option. The downside is that optimising for that case makes
the behaviour for other (more experienced) users worse. But it's not
unreasonable to make that trade-off.

> 3) Make --user be be automatic for pip install. Not actually the default,
> but pip could do a user install if you don't have the permissions for a
> non-user install.

The problem here is that the user scripts directory isn't on PATH. We
could put it on, but again we hit the "goes after the system PATH"
problem (on Windows).

> This means folks might accidentally install in user mode because they forgot
> to type sudo -- but that would be a mostly-sysadmin/sophisticated user
> problem. And maybe have an environment variable of configuration key for
> "prefer admin install". If tha was set, pip woul

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

2017-11-13 Thread Paul Moore
On 13 November 2017 at 20:43, MRAB  wrote:
> On 2017-11-13 19:10, Barry Warsaw wrote:
>> The specifics aren't as important as the general use case: multiple
>> tools competing for the same valuable real-estate.
>>
>> I have no ideas how to improve the situation, and of course any solution
>> would involve some coordination between all of these tools, but it's
>> beginning to feel like a losing battle.  Is there a better way?
>>
> I suppose that you could have suggest to them that they follow a convention
> such as:
>
> 1. There can be multiple pragmas in a comment, separated by semicolons: if
> you don't recognise it, skip past the semicolon.
>
> 2. A pragma can be prefixed with the name of the tool, e.g. "# flake8.noqa:
> F401": if there's a prefix, but it's not yours, skip past the semicolon.

An informational PEP defining a common convention for pragma-style
comments could standardise things. I'd suggest starting a discussion
(somewhere?) with the development teams for the relevant projects
(flake8, mypy, coverage...) with the intention of developing such a
PEP that they could all support.

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/


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

2017-11-14 Thread Paul Moore
On 14 November 2017 at 03:08, Nathaniel Smith  wrote:
> On Nov 13, 2017 6:47 PM, "Nick Coghlan"  wrote:

>> and a pip.bat with the equivalent contents on Windows?
>> (Bonus: maybe this would fix the problem with upgrading pip on
>> Windows?)
>
> Depending on how the batch file was written, I think the answer to
> that is "maybe":
> https://stackoverflow.com/questions/2888976/how-to-make-bat-file-delete-it-self-after-completion/20333152#20333152
>
>
> Sigh.

Batch files are not suitable for this task. The wrappers have to be
executables. See
http://paul-moores-notes.readthedocs.io/en/latest/wrappers.html for a
detailed analysis I did some time ago.

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/


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

2017-11-14 Thread Paul Moore
On 14 November 2017 at 10:02, Nathaniel Smith  wrote:
> On Tue, Nov 14, 2017 at 12:56 AM, Paul Moore  wrote:
>> On 14 November 2017 at 03:08, Nathaniel Smith  wrote:
>>> On Nov 13, 2017 6:47 PM, "Nick Coghlan"  wrote:
>>
>>>> and a pip.bat with the equivalent contents on Windows?
>>>> (Bonus: maybe this would fix the problem with upgrading pip on
>>>> Windows?)
>>>
>>> Depending on how the batch file was written, I think the answer to
>>> that is "maybe":
>>> https://stackoverflow.com/questions/2888976/how-to-make-bat-file-delete-it-self-after-completion/20333152#20333152
>>>
>>>
>>> Sigh.
>>
>> Batch files are not suitable for this task. The wrappers have to be
>> executables. See
>> http://paul-moores-notes.readthedocs.io/en/latest/wrappers.html for a
>> detailed analysis I did some time ago.
>
> Ah, interesting. My reason for suggesting it in the first place
> because I was hoping to avoid paying the process spawn overhead twice,
> but it sounds like this specific trick is misguided all around :-).

It doesn't even save the process overhead if you're running Powershell
as your main shell, or running pip from a terminal window in your
editor/IDE, ...

I really wish Windows *did* provide a usable "shell script"
implementation (of any form) but sadly it simply doesn't.

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/


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

2017-11-15 Thread Paul Moore
On 15 November 2017 at 08:22, Nick Coghlan  wrote:
> On 15 November 2017 at 16:13, Steve Barnes  wrote:
>>
>>   - "pip -X[.Y][-32|-64] operation ..." tries to find a python matching
>> -X[.Y][-32|-64] and if it succeeds executes "python -m pip operation
>> ..." with that python, (if it doesn't find a matching python is should
>> fail with a sensible error message and possibly list the valid python
>> specifiers).
>
>
> This is a genuinely interesting option, especially as `pipenv` has already
> implemented a feature somewhat akin to this:
> https://docs.pipenv.org/basics.html#specifying-versions-of-python
>
> `pipenv` also allows `pipenv --two` and `pipenv --three` when setting up
> your initial virtual environment.

This is an interesting idea for *any* tool that's about "working with
Python environments" as opposed to "writing Python code". So pip,
virtualenv, tox, pipenv, ... Many of these tools are variously
reinventing "tell me which Python environment to work on" options.
Having a common way to do this would be really useful. I'm not sure
how likely it would be for pip to be able to use it (pip introspects
sys.executable to get site-packages, etc), but it's certainly a
possibility.

Having a standardised library/wrapper that handles the "select a
Python environment" process would be a huge plus. There's
https://github.com/zooba/pep514tools which is a start on handling the
Windows registry scanning logic, and building on that to include Unix
and anything else we needed would be great.

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/


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

2017-11-15 Thread Paul Moore
On 15 November 2017 at 19: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.

Agreed. That sounds sufficiently awesome that I'll try to find some of
my essentially-non-existent coding time and largely-forgotten C skills
to implement it. Remind me of that promise in 6 months when I've
failed to report any progress :-)

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/


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/


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/


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

2017-11-17 Thread Paul Moore
On 17 November 2017 at 01:57, Nick Coghlan  wrote:
> 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

Note that if I *do* get round to working on this, my primary intention
will be to propose altering the launcher to allow it to be used under
different names, as described by Steve. However, I won't initially be
proposing that we add any additional links to the launcher by default,
leaving that for users to do manually, and/or for later revisions of
the PEP (or further PEPs) to propose this.

Reasons:

1. The launcher is typically in C:\Windows, which has a very high
priority on PATH, so getting the environment right will be tricky.
2. I don't have any real experience with the installer.
3. Backporting this change, or dealing with older versions of Python
that don't include the new launcher, is a complicated question.

I'd rather keep the initial PEP restricted to the simple behaviour
change. It's possible that the behaviour change may not even need a
PEP, but I think it'd be better to have one. The "how do we use the
new behaviour in the installers" question is likely to be much more
controversial...

Paul

PS This (particularly the replacement of python.exe) is almost
certainly too late for 3.7, so it's not as if there's a rush to answer
all the questions at once :-)
___
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-20 Thread Paul Moore
On 20 November 2017 at 21:59, Chris Barker  wrote:
> I don't understand any of this enough to have an opinion, so while I'd like
> to see py.exe be renamed python.exe, let's not let "the perfect be the enemy
> of good enough". So, if someone can make the case that they can restructure
> the whole py.exe / python.exe thing nicely in a way that will work, AND
> write the code to do it fairly quickly, then great!

I'm happy enough to modify the py.exe code to base its behaviour on
the name it's called with, as Steve suggested. I'm not sure if that
would require a PEP, but I'm willing to do one if it's felt that there
is a need. It should be possible to get that change in for 3.7. I
don't know what would be the best approach for adding copies/links of
the launcher under other names, though. And I don't have any
experience with the tools we use to build the installer, so that would
be for someone else. That part probably *would* need a PEP, and it may
well be controversial enough that getting agreement in time for 3.7
(i.e. in the next 2 months or so) will be challenging.

I think the launcher change is worthwhile in its own right. Even if we
don't install any aliases by default, users will be able to manually
add them. (And someone could write a 3rd party tool to manage creation
of such aliases, making that capability available to users who don't
have the necessary skills themselves).

> Otherwise, let's at least get a python3.exe into 3.7 -- and ideally into
> updates to 3.5, 3.6, and (python2.exe in this case, 2.7)

It's not going to be acceptable for 3.5, as that is now in security
fix only mode. I'm not certain it's even acceptable for bugfix-only
releases. It's a backward incompatible change (3.6.3 has no
python3.exe but python 3.6.4 does) but maybe an acceptable one - we'd
need feedback from the 3.6 and 2.7 release managers on that.

Also, I'm assuming here you mean "create a copy of python.exe called
python3.exe". If we do that, we risk making it harder to later switch
to making "python3.exe" a link to the launcher - for the same reason
that making "python.exe" be an alternative name for the launcher is
problematic right now.

> And maybe make "add to PATH" be the default in the installer.

I'm not willing to contradict Steve on this one. There are too many
not-uncommon cases that we could mess up badly here. It's the right
choice for "make new users' experience as easy as possible", but if we
do this at the cost of making the experience of people upgrading to
3.7 (possibly by installing 3.7 to gradually switch over, or starting
their migration from 2.7 with 3.7) unpleasant, then we risk getting
bad publicity for the 3.7 release.

The history of how we added Python to PATH across various versions is
messy and inconsistent. Add to that other distributions (Anaconda,
ActiveState) making different choices and adding yet more
inconsistency, means that anyone who *isn't* a brand new user probably
already has a tweaked, and likely fragile, setup. We're not doing them
any favours by adding another new behaviour. (And enabling "Add to
PATH" in 3.7 *would* be a new behaviour - I don't think we've enabled
add to path by default in any version since we switched to per-user
installs as the default).

We need *another* solution here. Not just variations on the existing
mess. That's why I like Steve's suggestion of making the launcher into
the canonical entry point. It's not easy, but at least it stands a
chance of breaking out of the cycle we're currently in, of switching
back and forth between "add to PATH" and "don't add to PATH".

> Those are quick and simple to do, result in little disruption, and make the
> whole cross-platform thing more manageable.

They aren't that simple. I've already discussed "add to PATH". And if
we add python3.exe, we have to consider questions like will venv be
modified to include it in virtual environments? Will virtualenv? If
not, will "python3" run the system Python rather than the current
virtualenv? That's just as much a problem for the option of having
python3 be an alias for the launcher, of course - but my point here is
you have to think about questions like this even for your "simple"
approach.

I just don't think there *is* a quick and simple solution here. So
better not to rush into a solution that isn't fully thought through,
IMO. "Although never is often better than *right* now" is the relevant
Zen here, not "Now is better than never" (nobody's suggesting we
*never* fix this).

> BTW -- does pip install a "pip3" on Windows?

No. Just "pip.exe".

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/


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

2017-11-20 Thread Paul Moore
>> BTW -- does pip install a "pip3" on Windows?
>
> No. Just "pip.exe".

Looks like I should have checked. As others pointed out, it does
(pip3.exe and pip3.6.exe). Apologies.
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/


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

2017-11-21 Thread Paul Moore
[Excuse any attribution errors, the quoting appears to have got badly
messed up somehow]

On 21 November 2017 at 06:21, Steve Barnes  wrote:
>
> On 21/11/2017 00:32, Chris Barker wrote:
>> I
>> don't know what would be the best approach for adding copies/links of
>> the launcher under other names, though.
>>
>>
>> this is the thing -- I wonder if py.exe has been a success at all :-)
>
> A lot of people, on windows, are using py.exe and pyw.exe without
> realising it - the default behaviour of the recent installer is to
> associate py.exe with *.py and pyw.exe with *.pyw so any user that is
> running python code by just typing the name of the file, or double
> clicking it, will be using it.

I use the py launcher a lot. Often just as "py" or "py -3.6". It
certainly isn't just limited to use via shebang lines.

I will say that I don't see beginners using it as much. That's
probably because there's so much documentation that says "use the
python command to start Python". That is of course an argument that we
should make the canonical command "python" rather than "py", but it
doesn't mean that if people find the "py" command they won't use it.
There's not a lot of evidence that isn't anecdotal either way on that
latter point.

>> So ti comes down to: does anyone USE py.exe???
>>
> As above.

And me.

>> we need th=e basic advice given out to *nix users to work:
>>
>> if you type "python" at the command line, and get python2, then you can
>> type "python3" to get python 3.

Um, we need the basic advice given to *everyone* to work. Insisting
that advice has to be "what Unix people do right now" is not the only
option. The advice "use python to run your default Python interpreter"
is too entrenched to change. The python2 and python3 aliases are a
platform-specific hack to get around the fact that some Linux
distributions couldn't switch the default Python to Python 3. Most of
the beginners I work with have no experience on Unix and no awareness
of python2/python3 commands.

"If you run python at the command line and get the wrong version of
Python, then..." - In that case you already have multiple versions of
Python on your system, and by the definitions we've been working to
here, you're an advanced user so you can fix it yourself.

Obviously, that's too harsh a stance for us to take. But let's not
ignore the fact that Unix users are typically *already* having to deal
with multiple versions of Python, and are typically more familiar with
command lines than Windows users. So there's no guarantee that a
solution that works for them is usable for Windows users who've never
used Python or the command line before, who downloaded Python 2.7 and
installed it, were then told "no, you should be using Python 3", and
installed 3.7, and now don't understand why "upgrading" didn't
uninstall the old version, what they need to do to work with Python 3,
etc...

> One of the nice things about embedding the behaviour into the launcher
> is that if the user/admin has installed a python that includes it it
> provides the behaviour for python installations that were already
> present and discoverable even if they didn't have it so if you have
> python 2.5 then after you install something with py.exe you can,
> currently, use py -2.5 to run it, (or py -2 if it is the only python 2).

+1. This is the biggest benefit for me. Also the fact that all the
older Python versions *don't need to be on PATH*. Having multiple
versions of Python on PATH is a bad thing (because of the Scripts
directory - if you want, I can explain in detail, but it's a side
issue for now).

>> I'm not willing to contradict Steve on this one.
>>
>  > I didn't know he'd made a clear statement about it.
>
> I am not sure that I spelt it out well enough but my personal feeling is
> that the installer should, (and I am reasonably sure that it should
> capable of this), default to add to path IF there is not a currently
> available python, (discoverable), and either default to don't add or
> prompt the installer if there is.

My apologies - I was unclear. I meant Steve Dower, who maintains the
installer, and who has strongly stated that the way the Windows PATH
works (separate system and user parts) makes sensible "add to PATH"
behaviour impossible. The reasons have all been described multiple
times, and I won't go into them again. Search the archives if you want
to see the details. Suffice it to say that wishing it was easy to
"just add Python to PATH" doesn't make it so...

> Of course the whole add to path or not becomes moot if the py.exe
> launcher is present as it is installed on the path, (C:\Windows), and
> then tries very hard just to "do the right thing".

That's why I prefer this option. There are still issues to address
(such as the Scripts directory), but it's much easier to keep the
complexity manageable with this approach.

>> But if people that understand these things say it's a bad idea, then
>> it's a bad idea. But we SHOULD make sure w

Re: [Python-ideas] Should Python have user-defined constants?

2017-11-21 Thread Paul Moore
-1. I don't see how this would improve any programs I've written or
seen. Tools like mypy or linters might benefit from a feature to track
constants and ensure they don't get changed, but I don't think it's
needed as a language feature. Seriously, has anyone ever written
"math.pi = 5" and been surprised that their code broke? Or even
modified an application constant like BUFFER_LIMIT? Do you have any
evidence that this would avoid bugs in real-world code?

Paul

PS Please fix your font - your posts are coming through with a huge
font size for some reason, which makes them extremely difficult to
read.

On 21 November 2017 at 06:33, Saeed Baig  wrote:
> Hey guys I am thinking of perhaps writing a PEP to introduce user-defined
> constants to Python. Something along the lines of Swift’s “let” syntax (e.g.
> “let pi = 3.14”).
>
> Do you guys think it would be a good idea? Why or why not? Do you think
> there’s a better way to do it? I’d like to know what others think about this
> idea before making any formal submission (I’ve already posted this same
> question on python-list, but I just wanted to gauge opinion here too).
>
> ___
> 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] Possible Enhancement to py.exe Python Launcher

2017-11-23 Thread Paul Moore
If I understand your proposal correctly, this is already possible, see
https://www.python.org/dev/peps/pep-0397/#python-version-qualifiers

The details are likely a little different than what you're proposing,
but if they don't cover what you're trying to do, maybe you could give
a more specific example of a use case that isn't currently possible?

Paul

On 23 November 2017 at 08:43, Steve Barnes  wrote:
> Following on from the discussions on pip I would like to suggest, (and
> possibly implement), a minor change to the current py.exe python launcher.
>
> Currently the launcher, when called without a version specifier,
> defaults to the highest version on the basis of 3>2, x.11 > x.9, -64 >
> -32 however this may not always be the most desirable behaviour.
>
> I would like to suggest that it take a configuration value for the
> default version to use, (and possibly a separate ones for pyw, & file
> associations), honouring the following with the later overriding:
>
> default - as current
> system setting - from registry
> user setting - from registry
> user setting - from config file maybe %appdata%\pylauncher\defaults.ini
> environment setting - from getenv
> local setting - from .pyconfig file in the current directory.
>
> Options would be the same format as the -X[.Y][-BB] format currently
> accepted on the command line plus a --No-Py-Default option which would
> always error out if the version to invoke was not specified.
>
> I see this as potentially adding quite a lot of value for people with
> multiple python versions installed and it could tie in quite well with
> the possible use of py.exe as an entry point for tools such as pip.
>
> It might also increase the awareness of the launcher as those who have
> to stick with python 2 for the moment or in a specific context could set
> the default to what they need but can always override.
>
> --
> 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/
___
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] How assignment should work with generators?

2017-11-27 Thread Paul Moore
On 27 November 2017 at 12:31, Kirill Balunov  wrote:
> As I can see at the moment, these cases should behave differently:
>
 x, y = [1,2,3,4] # must raise ValueError
 x, y = iter([1,2,3,4])  # should work
>
> But at the same time, it violates current situation. So maybe, as you have
> said we need special syntax. I will think about it.

I would find this confusing. Consider where you don't have literals:

def f(vals):
x, y = vals

data = [1,2,3,4]

f(data)
data = iter(data)
f(data)

Having the two calls behave differently would be a recipe for errors
as someone refactors the calling code.

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/


Re: [Python-ideas] How assignment should work with generators?

2017-11-27 Thread Paul Moore
On 27 November 2017 at 16:05, Chris Angelico  wrote:
> On Tue, Nov 28, 2017 at 2:35 AM, Steven D'Aprano  wrote:
>> In this case, there is a small but real benefit to counting the
>> assignment targets and being explicit about the number of items to
>> slice. Consider an extension to this "non-consuming" unpacking that
>> allowed syntax like this to pass silently:
>>
>> a, b = x, y, z
>>
>> That ought to be a clear error, right? I would hope you don't think that
>> Python should let that through. Okay, now we put x, y, z into a list,
>> then unpack the list:
>>
>> L = [x, y, z]
>> a, b = L
>>
>> That ought to still be an error, unless we explicity silence it. One way
>> to do so is with an explicit slice:
>>
>> a, b = L[:2]
>
> I absolutely agree with this for the default case. That's why I am
> ONLY in favour of the explicit options. So, for instance:
>
> a, b = x, y, z # error
> a, b, ... = x, y, z # valid (evaluates and ignores z)

Agreed, only explicit options are even worth considering (because of
backward compatibility if for no other reason). However, the unpacking
syntax is already complex, and hard to search for. Making it more
complex needs a strong justification. And good luck in doing a google
search for "..." if you saw that code in a project you had to
maintain. Seriously, has anyone done a proper investigation into how
much benefit this proposal would provide? It should be reasonably easy
to do a code search for something like "=.*islice", to find code
that's a candidate for using the proposed syntax. I suspect there's
very little code like that.

I'm -1 on this proposal without a much better justification of the
benefits it will bring.
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/


Re: [Python-ideas] How assignment should work with generators?

2017-11-27 Thread Paul Moore
On 27 November 2017 at 21:54, Kirill Balunov  wrote:
> 2017-11-27 19:23 GMT+03:00 Paul Moore :
>
>>
>> It should be reasonably easy
>> to do a code search for something like "=.*islice", to find code
>> that's a candidate for using the proposed syntax. I suspect there's
>> very little code like that.
>
>
> While isclice is something  equivalent, it can be used in places like:
>
> x, y = seq[:2]
> x, y, z = seq[:3]

But in those places,

x, y, *_ = seq

works fine at the moment. So if the programmer didn't feel inclined to
use x, y, *_ = seq, there's no reason to assume that they would get
any benefit from x, y, ... = seq either.

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/


Re: [Python-ideas] Using an appropriate tone in emails (was: Adding a thin wrapper class around the functions in stdlib.heapq)

2017-11-27 Thread Paul Moore
On 27 November 2017 at 21:59, Nick Timkovich  wrote:
> On Mon, Nov 27, 2017 at 8:17 PM, Brett Cannon  wrote:
>>
>> But calling it "atrocious" and so bad that it needs to be fixed
>> "immediately" as if it's a blight upon the stdlib is unnecessarily insulting
>> to those that have worked on the module. To convey the feeling that you
>> think an OO wrapper would be helpful as the current design doesn't work for
>> you, you could just phrase it as I just did to get the same point across
>> without insulting anyone. Basically if you wouldn't like your own work
>> called "atrocious" by someone you respect, then it's probably best to not
>> use that phrasing when talking about a stranger's code either.
>
>
> Sorry for the curt tone, I did lose some sight on the code being designed by
> people rather than a faceless organization. My intention wasn't to disparage
> the original authors but sprung more out of my frustration and perception
> from that thread and those before that the status quo would not change and
> that if a contribution was proffered, would simply be dismissed or ignored.
> To motivate any change, there must be some argument levied against the
> status quo, but hopefully I can articulate it better.
>
> That little corner is something I'm interested in, and not having
> contributed to CPython before, I'm unsure how it "really works". The steps
> at https://devguide.python.org/stdlibchanges/ suggest trying to elicit
> community feedback from the lists as a step, so negative feedback tends to
> kill the enthusiasm to actually make the PR. In the absence of code,
> concrete arguments are almost impossible as we're discussing the shape of
> clouds.

In my experience (and this reiterates Brett's point) the proposals
that get the best responses are those that are presented positively -
instead of focusing on the (perceived) problems with the current
situation, describe the benefits that will come from the proposed
change. If you can't do that, then it's unlikely there is enough
justification for a change. Certainly, negative feedback can be
demotivating, and when you have a great idea and all you hear is "but
what if...?" it's hard to remain positive. But you're not going to get
better feedback if you criticise - at best, people will stop
listening, and you'll have avoided some of the arguments, but at the
cost of no-one being willing to support your proposal and so it dies.

Your perception isn't wrong, by the way. It *is* hard to persuade
people that the status quo needs to change. But that's not because
there's no interest in change. Rather, it's because there's a strong
sense among both the core developers and the frequent contributors on
this list, of the significant impact any change will have - it's hard
to conceive of just how many people will be affected by even the
smallest change we make, and that's a big responsibility.

So while it's often hard, focusing on the positives (and being willing
to accept that the status quo is sufficient for many people) really is
the only way to gain support.

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/


Re: [Python-ideas] Repurpose `assert' into a general-purpose check

2017-11-28 Thread Paul Moore
On 28 November 2017 at 13:36, Nick Coghlan  wrote:
> On 28 November 2017 at 15:41, Steven D'Aprano  wrote:
>> On Tue, Nov 28, 2017 at 05:12:36AM +0300, Ivan Pozdeev via Python-ideas 
>> wrote:
>>> Unlike C, Python does the aforementioned checks all the time, i.e. it's
>>> effectively always in "debug mode".
>>
>> Apart from -O which disables assertions. But in any case, the best use
>> of assertions is not checking things which the interpreter is going to
>> do anyway, but checking things which the interpreter can not and does
>> not check automatically: your program logic. There is no way that the
>> Python interpreter is going to do this check automatically, unless I
>> write the assertion:
>>
>> assert 0 <= r < abs(y)
>>
>> That is copied straight out of one of my functions.
>
> I'll make the same observation I usually do each time one of these
> threads comes up:
>
> * I'm opposed to making assert substantially different from the way it works 
> now
> * I'm in favour of adding a new "ensure()" builtin that encapsulates
> the check-and-raise logic
>
> The reasons I prefer this approach:
>
> - assert is a statement *solely* so that the compiler can optimise it
> out. If it's not optional,
>   it doesn't need to be a statement any more
> - if the existing assert statements are left alone, there are no
> performance or compatibility
>   concerns for folks that rely on the current behaviour
> - if it's a function, it doesn't need to be called "assert", it can use the 
> more
>   imperative term "ensure" (meaning "ensure this condition is true
> before continuing")
> - if it's a function, it can easily be emulated on old versions via
> compatibility libraries
> - "ensure() is required, assert is optional" is a better answer to
> complaints about
>   assertions being optional than suggesting "if cond: raise 
> AssertionError(msg)"
>   as a reasonable alternative to "assert cond, msg"
> - if it's a function, we get access to all the regular function
> machinery, so we're
>   not restricted to positional-only arguments the way the assert statement is
>
> My initial proposed behaviour for the function:
>
> def ensure(cond, msg=None, exc_type=RuntimeError):
> """Raise an exception if the given condition is not true"""
> if not cond:
> if msg is None:
> frame = sys._getframe(1)
> line = frame.f_lineno
> modname = frame.f_globals.get("__name__", "")
> msg = f"Condition not met on line {line:d} in {modname!r}"
> raise exc_type(msg)
>
> Cheers,
> Nick.
>
> P.S. No, I'm not offering to write that PEP myself, I'd just be in
> favour of the idea if someone else were to write it :)

+1 on everything Nick said.

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/


Re: [Python-ideas] [Python-Dev] What's the status of PEP 505: None-aware operators?

2017-11-29 Thread Paul Moore
On 29 November 2017 at 12:41, Nick Coghlan  wrote:
> On 29 November 2017 at 22:38, Stephan Houben  wrote:
>> What about more English-like syntax:
>>
>> X or else Y
>
> The problem with constructs like this is that they look like they
> should mean the same thing as "X or Y".

Keyword based and multi-word approaches also break down much faster
when you get more terms.

X or else Y

looks OK (ignoring Nick's comment - I could pick another keyword-based
proposal, but I'm too lazy to look for one I like), but when you have
4 options,

X or else Y or else Z or else W

the benefit isn't as obvious. Use lower-case and longer names

item_one or else item_two or else list_one[the_index] or dict_one['key_one']

and it becomes just a muddle of words.

Conversely, punctuation-based examples look worse with shorter
variables and with expressions rather than identifiers:

item_one ?? item_two ?? another_item ?? one_more_possibility

vs

x ?? y[2] ?? kw['id'] ?? 3 + 7

IMO, this is a case where artificial examples are unusually bad at
conveying the actual feel of a proposal. It's pretty easy to turn
someone's acceptable-looking example into an incomprehensible mess,
just by changing variable names and example terms. So I think it's
critically important for any proposal along these lines (even just
posts to the mailing list, and definitely for a PEP), that it's argued
in terms of actual code examples in current projects that would
reasonably be modified to use the proposed syntax. And people wanting
to be particularly honest in their proposals should probably include
both best-case and worst-case examples of readability.

Paul

PS Also, I want a pony. (I really do understand that the above is not
realistic, but maybe I can hope that at least anyone writing a PEP
take it into consideration :-))
___
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] How assignment should work with generators?

2017-11-30 Thread Paul Moore
On 30 November 2017 at 16:16, Steve Barnes  wrote:
> I had a sneaky feeling that it did, which raises the question of what
> the bleep this enormous thread is about, since the fundamental syntax
> currently exists

Essentially, it's about the fact that to build remainder you need to
copy all of the remaining items out of the RHS. And for an infinite
iterator like count() this is an infinite loop.

There's also the point that if the RHS is an iterator, reading *any*
values out of it changes its state - and
1. a, b, *remainder = rhs therefore exhausts rhs
2. a.b = rhs reads "one too many" values from rhs to check if
there are extra values (which the programmer has asserted shouldn't be
there by not including *remainder).

Mostly corner cases, and I don't believe there have been any
non-artificial examples posted in this thread. Certainly no-one has
offered a real-life code example that is made significantly worse by
the current semantics, and/or which couldn't be easily worked around
without needing a language change.

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/


Re: [Python-ideas] How assignment should work with generators?

2017-12-01 Thread Paul Moore
On 1 December 2017 at 09:48, Kirill Balunov  wrote:
> Probably, some time ago it was necessary to split this thread into two
> questions:
> 1. Philosophical question regarding sequences and iterators. In particular,
> should they behave differently depending on the context,
> or, in other words, whether to emphasize their different nature as
> fixed-size containers and those that are lazily produce values on demand.
> 2. Additional syntax in the assignment statement for partial extraction of
> values from the iterable.

That's a good summary of the two elements of the discussion here.

On (1), I'd say that Python should *not* have context-dependent
semantics like this. It's something Perl was famous for (list and
scalar contexts) and IMO makes for pretty unreadable code. Python's
Zen here is "Explicit is better than implicit". Specifically, having
the semantics of the assignment statement vary depending on the type
of the value being assigned seems like a very subtle distinction, and
not in line with any other statement in the language.

On (2), that's something that is relatively simple to debate - all of
the normal rules for new syntax proposals apply - what problem does it
solve, how much of an improvement over existing ways of solving the
problem does the proposal give, how easy is it for beginners to
understand and for people encountering it to locate the documentation,
does it break backward compatibility, etc... Personally I don't think
it's a significant enough benefit but I'm willing to be swayed if good
enough arguments are presented (currently the "a, b, ... = value"
syntax is my preferred proposal, but I don't think there's enough
benefit to justify implementing it).

> 2017-11-30 22:19 GMT+03:00 Paul Moore :
>>
>>
>> Mostly corner cases, and I don't believe there have been any
>> non-artificial examples posted in this thread.
>>
>> Certainly no-one has offered a real-life code example that is made
>> significantly worse by
>> the current semantics, and/or which couldn't be easily worked around
>> without needing a language change.
>
>
> Yes, in fact, this is a good question, is whether that is sufficiently
> useful to justify extending the syntax. But it is not about corner cases, it
> is rather usual situation.
> Nevertheless, this is the most difficult moment for Rationale. By now, this
> feature does not give you new opportunities for solving problems. It's more
> about expressiveness and convenience. You can write:
>
> x, y, ... = iterable
>
> or,
>
> it = iter(iterable)
> x, y = next(it), next(it)
>
> or,
>
> from itertools import isclice
> x, y = islice(iterable, 2)
>
> or,
> x, y = iterable[:2]
>
> and others, also in some cases when you have infinite generator or iterator,
> you should use 2nd or 3rd.

It's significant to me that you're still only able to offer artificial
code as examples. In real code, I've certainly needed this type of
behaviour, but it's never been particularly problematic to just use

first_result = next(it)
second_result - next(it)

Or if I have an actual sequence, x, y = seq[:2]

The next() approach actually has some issues if the iterator
terminates early - StopIteration is typically not the exception I
want, here. But all that means is that I should use islice more. The
reason i don't think to is because I need to import it from itertools.
But that's *not* a good argument - we could use the same argument to
make everything a builtin. Importing functionality from modules is
fundamental to Python, and "this is a common requirement, so it should
be a builtin" is an argument that should be treated with extreme
suspicion. What I *don't* have a problem with is the need to specify
the number of items - that seems completely natural to me, I'm
confirming that I require an iterable that has at least 2 elements at
this point in my code.

The above is an anecdotal explanation of my experience with real code
- still not compelling, but hopefully better than an artificial
example with no real-world context :-)


> In fact, this has already been said and probably
> I will not explain it better:
>
> 2017-11-28 1:40 GMT+03:00 Greg Ewing :
>>
>> Guido van Rossum wrote:
>>>
>>> Is this problem really important enough that it requires dedicated
>>> syntax? Isn't the itertools-based solution good enough?
>>
>>
>> Well, it works, but it feels very clumsy. It's annoying to
>> have to specify the number of items in two places.
>>
>> Also, it seems perverse to have to tell Python to do *more*
>> stuff to mitigate the effects of stuff it does that you
>> didn't want it to

Re: [Python-ideas] PEP 505 vs matrix multiplication

2017-12-01 Thread Paul Moore
On 1 December 2017 at 13:40, Nick Coghlan  wrote:
> I genuinely don't think these kinds of operators are all that useful
> outside the specific domain of working with semi-structured
> hierarchical data stored in graph databases and document stores like
> MongoDB, ElasticSearch, and PostgreSQL JSONB columns, or else piping
> data between such stores and JSON consuming clients.

In that case, surely there are 3rd party libraries that help with
extracting such data from raw objects? Or if not, how seriously has
anyone looked at developing one? With the ability to create
specialised getattr and getitem behaviour, is it really so difficult
to produce a class that allows users to extract hierarchical data? I
know it probably couldn't do as good a job as if there were dedicated
syntax, but as a basis for a proposal that said "current best practice
(using module XXX) looks like this, but would be improved with the
following language support" it would help to ground the discussion in
real use cases. In the context of comparisons with matrix
multiplication, PEP 465 put a lot of time into explaining how all the
ways of approaching the problem short of a language change had been
tried and found wanting. Maybe PEP 505 should be held to a similar
standard?

At the moment, 99% of the discussion seems rooted in generalised "it
would help a lot of code" with readability arguments based on
artificial examples, and that's not really helping move the discussion
forward.

To be clear, I understand the problem of reading semi-structured data.
I've hit it myself and been frustrated by it. But my reaction was "why
am I not able to find a library that does this?", and when I couldn't
find such a library, my assumption was that people in general don't
find the current behaviour sufficiently frustrating to do anything
about it. And I was in the same situation - it annoys me, but not
enough to write a helper module (and certainly not enough that I'm
crying out for a language change). So I do appreciate the need, I just
don't think "language change" should be the first thing that's
suggested.

Paul

PS Some of the above may have been covered in the PEPs and previous
discussions. I haven't reread them - but any serious reboot of the
discussion should probably start with a summary of where we're up to.
___
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 sorting protocol dunder method?

2017-12-04 Thread Paul Moore
On 4 December 2017 at 11:41, Steven D'Aprano  wrote:
> On Sun, Dec 03, 2017 at 10:48:18PM -0800, Carl Meyer wrote:
>> I think this is an interesting idea, and I don't believe that either
>> performance or "sortable vs comparable" are very relevant.
>
> Performance is always relevant -- while performance shouldn't be the
> sole deciding factor, it should be a factor.
>
> And since the entire use-case for this is sorting versus comparison
> operators, I'm having trouble understanding why you think that sorting
> versus comparison operators is irrelevant.

I'm not completely clear on what the expectation is (in terms of
"sortable vs comparable") here. Clearly if a class has __lt__, it's
both sortable and comparable, and that's fine. If it doesn't have
__lt__, then the implication is that the class designer doesn't
believe it's reasonable for it to be ordered. That's what not having
comparison methods *means* (well, excepting the case that the designer
didn't think of it, which is probably the case for 99% of my classes
;-))

If we have a __key__ method on a class, then the following becomes true:

* We can work out which of 2 instances is bigger/smaller using max/min.
* We can compare two items by doing a sort.

So while the *intent* may not be to allow comparisons, that's what you've done.

As a result, I don't think it's an important consideration to worry
about classes that "should be sortable, but shouldn't be orderable".
That's basically a contradiction in terms, and will likely only come
up in corner cases where for technical reasons you may need your
instances to participate in sorting without raising exceptions, but
you don't consider them orderable (the NLTK example mentioned above).

Conversely, when sorting a key can provide significant performance
improvements. A single O(n) pass to compute keys, followed by O(n
log(n)) comparisons could be significantly faster, assuming comparing
keys is faster than extracting them from the object. So allowing
classes to define __key__ could be a performance win over a __lt__
defined as (effectively)

def __lt__(self, other):
return self.__key__() < other.__key__()

Overall, I don't see any problem with the idea, although it's not
something I've ever needed myself, and I doubt that in practice it
will make *that* much difference. The main practical benefit, I
suspect, would be if there were an "Orderable" ABC that auto-generated
the comparison methods given either __lt__ or __key__ (I could have
sworn there was such an ABC for __lt__ already, but I can't find it in
the library ref :-()

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/


Re: [Python-ideas] Support floating-point values in collections.Counter

2017-12-19 Thread Paul Moore
On 18 December 2017 at 23:51, Joel Croteau  wrote:
> It would be useful in many scenarios for values in collections.Counter to be
> allowed to be floating point.

Do you have any evidence of this? Code examples that would be
significantly improved by such a change?  I can't think of any myself.

I might consider writing

totals - defaultdict(float)
for ...:
totals[something] = calculation(something)

but using a counter is neither noticeably easier, nor clearer...

One way of demonstrating such a need would be if your proposed
behaviour were available on PyPI and getting used a lot - I'm not
aware of any such module if it is.

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/


Re: [Python-ideas] Support floating-point values in collections.Counter

2017-12-20 Thread Paul Moore
On 20 December 2017 at 03:09, Joel Croteau  wrote:
> Well here is some code I wrote recently to build a histogram over a weighted
> graph, before becoming aware that Counter existed (score is a float here):
>
> from collections import defaultdict
>
> total_score_by_depth = defaultdict(float)
> total_items_by_depth = defaultdict(int)
> num_nodes_by_score = defaultdict(int)
> num_nodes_by_log_score = defaultdict(int)
> num_edges_by_score = defaultdict(int)
> for state in iter_graph_components():
> try:
> # There is probably some overlap here
> ak = state['ak']
> _, c = ak.score_paths(max_depth=15)
> for edge in state['graph'].edges:
> num_edges_by_score[np.ceil(20.0 * edge.score) / 20.0] += 1
> for node in c.nodes:
> total_score_by_depth[node.depth] += node.score
> total_items_by_depth[node.depth] += 1
> num_nodes_by_score[np.ceil(20.0 * node.score) / 20.0] += 1
> num_nodes_by_log_score[np.ceil(-np.log10(node.score))] += 1
> num_nodes_by_score[0.0] += len(state['graph'].nodes) - len(c.nodes)
> num_nodes_by_log_score[100.0] += len(state['graph'].nodes) -
> len(c.nodes)
> except MemoryError:
> print("Skipped massive.")
>
> Without going too much into what this does, note that I could replace the
> other defaultdicts with Counters, but I can't do the same thing with a
> total_score_by_depth, at least not without violating the API.

Hmm, OK. I can't see any huge benefit from switching to a Counter,
though. You're not using any features of a Counter that aren't shared
by a defaultdict, nor is there any code here that could be simplified
or replaced by using such features...

> I would
> suggest that with a name like Counter, treating a class like a Counter
> should be the more common use case. If it's meant to be a multiset, we
> should call it a Multiset.

Personally, I consider "counting" to be something we do with integers
(whole numbers), not with floats. So for me the name Counter clearly
implies an integer. Multiset would be a reasonable alternative name,
but Python has a tradition of using "natural language" names over
"computer science" names, so I'm not surprised Counter was chosen
instead.

I guess it's ultimately a matter of opinion whether a float-based
Counter is a natural extension or not.

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/


Re: [Python-ideas] __intancehook__ special method

2017-12-26 Thread Paul Moore
On 26 December 2017 at 09:13, Yahya Abou 'Imran via Python-ideas
 wrote:
> In a personnal project I feel the need (or the desire) to implement
> something like this:
>
> assert isinstance(1, PositiveInteger)
> assert not isinstance(-1, PositiveInteger)

To me, this seems like an over-use of classes for something they are
not really appropriate for (in Python, at least). In my experience,
it's people coming from other languages that are more strongly class
based, such as Java, that prefer this type of construct.

In Python, I'd write this as

assert isinstance(1, int) and 1 > 0
assert not isinstance(-1, int) or -1 < 0
# or maybe you meant isinstance(-1, int) and -1 < 0 for the second one...?

That reads far more naturally to me in Python.

> So I began looking a lot in the abc module, and I end unp using an
> __instancehook__ special method wich is called by __instancechek__ in the
> corresponding metaclass, just like the __subclasshook__ special method
> called by __subclasscheck__.
[...]
> What do you think about that ?

I don't think it's needed - it feels to me like a solution to a
problem that Python doesn't have in practice. (Of course, there may be
more complex or specialised cases where it would be useful, but as
you've demonstrated, you can write the implementation yourself for the
rare cases it might be needed, so that may well be sufficient).

Thanks for the idea - it's interesting to see how other people
approach problems like this even if it turns out not to be something
worth adding.

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/


Re: [Python-ideas] Syntax to import modules before running command from the command line

2018-01-05 Thread Paul Moore
On 5 January 2018 at 08:12, Nick Coghlan  wrote:
> However, the issue then is that "python -M numpy" would just be a less
> flexible alternative to a command like "python -C 'import numpy as
> np'".

For quick one-liners don't underestimate the value of avoiding punctuation:

# No punctuation at all
python -M numpy
# Needs quotes - if quoted itself, needs nested quotes
python -C "import numpy"
# Needs quotes and semicolon
python -c "import numpy; ..."

This may not be a big deal on Unix shells (IMO, it's still an issue
there, just less critical) but on less-capable shells like Windows'
CMD, avoiding unnecessary punctuation can be a big improvement.

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/


Re: [Python-ideas] Syntax to import modules before running command from the command line

2018-01-10 Thread Paul Moore
On 10 January 2018 at 02:39, Nick Coghlan  wrote:
> For the coverage.py use case, an environment-based solution is also
> genuinely helpful, since you typically can't modify subprocess
> invocations just because the software is being tested. At the moment,
> there are approaches that rely on using either `sitecustomize` or
> `*.pth` files, but being able to write `PYTHONRUNFIRST="import
> coverage; coverage.process_startup()"` would be a fair bit clearer
> about what was actually going on.

It's worth remembering that Windows doesn't have the equivalent of the
Unix "VAR=xxx prog arg arg" syntax for one-time setting of an
environment variable, so environment variable based solutions are
strictly less useful than command line arguments. That's one reason I
prefer -C over PYTHONRUNFIRST.

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/


Re: [Python-ideas] Support WHATWG versions of legacy encodings

2018-01-10 Thread Paul Moore
On 10 January 2018 at 04:16, Nick Coghlan  wrote:
> On 10 January 2018 at 13:56, Rob Speer  wrote:
>> One other thing I've noticed that's related to the WHATWG encoding list: in
>> Python, the encoding name "windows-874" seems to be missing. The _encoding_
>> is there, as "cp874", but "windows-874" doesn't work as an alias for it the
>> way that "windows-1252" works as an alias for "cp1252". That alias should be
>> added, right?
>
> Aye, that would make sense.

Agreed - extending the encodings and adding the alias both sound like
reasonable enhancements to me.
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/


Re: [Python-ideas] Repurpose `assert' into a general-purpose check

2018-01-16 Thread Paul Moore
Grr, Google Groups gateway messes up reply-to. Apologies to anyone who
gets a double-post, please can posters ensure that reply-to is set to
the list, and *not* to the Google Groups gateway? Thanks.
Paul

On 16 January 2018 at 15:54, Paul Moore  wrote:
> On 16 January 2018 at 15:37, smarie
>  wrote:
>
>>> If you, the developer, don't want a check to be disabled, then you
>>> shouldn't call it an assertion and use assert.
>>
>>
>> That is exactly what I'm saying. It seems that we both agree that
>> applicative value validation is different from asserts, and that assert
>> should not be used for applicative value validation.
>> For this reason, I do not suggest to go in the direction the OP is
>> mentioning but rather to explicitly separate the 2 concepts by creating a
>> new statement for value validation.
>>
>>>
>>> The problem with a statement called "validate" is that it will break a
>>> huge number of programs that already include functions and methods using
>>> that name.
>>
>> You definitely make a point here. But that would be the case for absolutely
>> *any* language evolution as soon as the proposed statements are plain old
>> english words. Should it be a show-stopper ? I dont think so.
>
> Why does this need to be a statement at all? Unlike assert, it's
> always executed, so it can be defined as a simple function:
>
> def validate(test, message):
> if not test:
> raise ValidartionError(message)
>
>>> But apart from the use of a keyword, we already have a way to do almost
>>> exactly what you want:
>>>
>>> if not expression: raise ValidationError(message)
>>>
>>> after defining some appropriate ValidationError class. And it is only a
>>> few key presses longer than the proposed:
>>>
>>> validate expression, ValidationError, message
>>
>>
>> This is precisely what is not good in my opinion: here you do not separate
>>  from . Of course if 
>> is just a "x > 0" statement, it works, but now what if you rely on a
>> 3d-party provided validation function (or even yours) such as e.g.
>> "is_foo_compliant" ?
>>
>> if not is_foo_compliant(x): raise ValidationError(message)
>>
>> What if this third part method raises an exception instead of returning
>> False in some cases ?
>>
>> try:
>> if not is_foo_compliant(x): raise ValidationError(message)
>> except:
>> raise MyValidationError(message)
>>
>> What if you want to compose this third party function with *another* one
>> that returns False but not exceptions ? Say, with an OR ? (one or the other
>> should work). Yields:
>>
>> try:
>> if not is_foo_compliant(x): raise ValidationError(message)
>> except:
>> if not is_bar_compliant(x):
>> raise MyValidationError(message)
>>
>> It starts to be quite ugly, messy... while the applicative intent is clear
>> and could be expressed directly as:
>>
>> validate is_foo_compliant(x) or is_bar_compliant(x)
>> ValidationError(message)
>
> I don't see how a validate statement avoids having to deal with all of
> the complexity you mention here. And it's *far* easier to handle this
> as a standalone function - if you find a new requirement like the ones
> you suggest above, you simply modify the function (and release an
> updated version of your package, if you choose to release your code on
> PyPI) and you're done. With a new statement, you'd need to raise a
> Python feature request, wait for at least the next Python release to
> see the modification, and *still* have to support people on older
> versions of Python with the unfixed version.
>
> Also, a validate() function will wor on older versions of Python, all
> the way back to Python 2.7 if you want.
>
> 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/


Re: [Python-ideas] Repurpose `assert' into a general-purpose check

2018-01-16 Thread Paul Moore
I fixed the reply-to this time, looks like you're still getting messed
up by Google Groups.

On 16 January 2018 at 16:25, smarie
 wrote:
> Let's consider this example where users want to define on-the-fly one of the
> validation functions, and combine it with another with a 'or':
>
> assert_valid('surface', surf, or_(lambda x: (x >= 0) & (x < 1),
> is_foo_compliant), help_msg="surface should be 0=
> How ugly for something so simple ! I tried to make it slightly more compact
> by developping a mini lambda syntax but it obviously makes it slower.

Why do you do this? What's the requirement for delaying evaluation of
the condition? A validate statement in Python wouldn't be any better
able to do that, so it'd be just as ugly with a statement. There's no
reason I can see why I'd ever need delayed evaluation, so what's wrong
with just

assert_valid(0 <= surf < 1 and is_foo_compliant(surf),
help_msg="surface should be 0= There are three reasons why having a 'validate' statement would improve
> this:
>
>  * no more parenthesis: more elegant and readable
>  * inline use of python (1): no more use of lambda or mini_lambda, no
> performance overhead
>  * inline use of python (2): composition would not require custom function
> composition operators such as 'or_' (above) or mini-lambda composition
> anymore, it could be built-in in any language element used after 
>
> resulting in
>
> validate (surf >= 0) & (surf < 1) or is_foo_compliant(surf),
> "surface should be 0=
> (I removed the variable name alias 'surface' since I don't know if it should
> remain or not)
>
> Elegant, isn't it ?

No more so than my function version, but yes far more so than yours...

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/


Re: [Python-ideas] Repurpose `assert' into a general-purpose check

2018-01-16 Thread Paul Moore
On 16 January 2018 at 17:36, Sylvain MARIE
 wrote:
> (trying with direct reply this time)
>
>> Why do you do this? What's the requirement for delaying evaluation of the 
>> condition?
>
> Thanks for challenging my poorly chosen examples :)
>
> The primary requirement is about *catching* 
> unwanted/uncontrolled/heterogenous exceptions happening in the underlying 
> functions that are combined together to provide the validation means, so as 
> to provide a uniform/consistent outcome however diverse the underlying 
> functions are (they can return booleans or raise exceptions, or both).
>
> In your proposal, if 'is_foo_compliant' raises an exception, it will not be 
> caught by 'assert_valid', therefore the ValidationError will not be raised. 
> So this is not what I want as an application developer.

Ah, OK. But nothing in your proposal for a new statement suggests you
wanted that, and assert doesn't work like that, so I hadn't realised
that's what you were after.

You could of course simply do:

def assert_valid(expr, help_msg):
# Catch exceptions in expr() as you see fit
if not expr():
raise ValidationError(help_msg)

assert_valid(lambda: 0 <= surf < 1 and is_foo_compliant(surf),
help_msg="surface should be 0=https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


Re: [Python-ideas] Official site-packages/test directory

2018-01-19 Thread Paul Moore
Another common approach is to not ship tests as part of your (runtime)
package at all - they are in the sdist but not the wheels nor are they
deployed with "setup.py install". In my experience, this is the usual
approach projects take if they don't have the tests in the package
directory. (I don't think I've *ever* seen a project try to install
tests except by including them in the package directory...)

Paul

On 19 January 2018 at 16:10, Guido van Rossum  wrote:
> IIUC another common layout is to have folders named test or tests inside
> each package. This would avoid requiring any changes to the site-packages
> layout.
>
> On Fri, Jan 19, 2018 at 6:27 AM, Stefan Krah  wrote:
>>
>>
>> Hello,
>>
>> I wonder if we could get an official site-packages/test directory.
>> Currently
>> it seems to be problematic to distribute tests if they are outside the
>> package
>> directory.  Here is a nice overview of the two main layout possibilities:
>>
>>
>> http://pytest.readthedocs.io/en/reorganize-docs/new-docs/user/directory_structure.html
>>
>>
>> I like the outside-the-package approach, mostly for reasons described very
>> eloquently here:
>>
>>
>> http://python-notes.curiousefficiency.org/en/latest/python_concepts/import_traps.html
>>
>>
>> CPython itself of course also uses Lib/foo.py and Lib/test/test_foo.py, so
>> it
>> would make sense to have site-packages/foo.py and
>> site-packages/test/test_foo.py.
>>
>> For me, this is the natural layout.
___
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] Official site-packages/test directory

2018-01-19 Thread Paul Moore
On 19 January 2018 at 17:08, Stefan Krah  wrote:
> On Fri, Jan 19, 2018 at 04:23:23PM +0000, Paul Moore wrote:
>> Another common approach is to not ship tests as part of your (runtime)
>> package at all - they are in the sdist but not the wheels nor are they
>> deployed with "setup.py install". In my experience, this is the usual
>> approach projects take if they don't have the tests in the package
>> directory. (I don't think I've *ever* seen a project try to install
>> tests except by including them in the package directory...)
>
> Yes, given the current situation not shipping is definitely the best
> approach in that case.
>
> I just thought that if we did have something like site-packages/stest
> (Guido correctly noted that "test" wouldn't work), people might use it.
>
>
> But it is all very speculative and I'm not really sure myself.

To be usable, tools like pip, wheel, setuptools, flit, etc, would all
need to be updated to take into account this option, as well as the
relevant standards (the wheel spec for one). Add to that the changes
needed to places like the sysconfig package to allow introspecting the
location of the new test directory. Would there be a test directory in
user-site as well? What about in virtual environments? (If only in
site-packages, then it'll likely be read-only in a lot of
environments). Also, would we need to reserve the directory name
chosen to prohibit 3rd party packages using it? As we've seen the
stdlib test package clashes with the original proposal, who's to say
there's nothing on PyPI that uses stest?

The idea isn't a bad one in principle - there's a proposal from some
time back on distutils-sig that Python packaging support more "target
locations" matching the POSIX style locations - for docs, config, etc.
A test directory would fit in with this idea. But it's a pretty big
change in practice, and no-one has yet done much beyond talk about it.
And the proposal would likely have put the test directory *outside*
site-packages, which avoids the name clash problem.

I'd think that the idea of a site-packages/stest directory would need
a much more compelling use case to justify it.

Paul

PS There's nothing stopping a (distribution) package FOO from
installing (Python) packages foo and foo-tests. It's not common, and
probably violates people's expectations, but it's not *illegal* (the
setuptools distribution installs pkg_resources as well as setuptools,
for a well-known example). So in theory, if people wanted this enough,
they could have implemented it right now, without needing any change
to Python or the packaging ecosystem.
___
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] Official site-packages/test directory

2018-01-19 Thread Paul Moore
On 19 January 2018 at 18:19, Stefan Krah  wrote:
> On Fri, Jan 19, 2018 at 05:30:43PM +0000, Paul Moore wrote:
> [cut]
>> I'd think that the idea of a site-packages/stest directory would need
>> a much more compelling use case to justify it.
>
> Thanks for the detailed explanation!  It sounds that there's much more work
> involved than I thought, so it's probably better to drop this proposal.
>
>
>> PS There's nothing stopping a (distribution) package FOO from
>> installing (Python) packages foo and foo-tests. It's not common, and
>> probably violates people's expectations, but it's not *illegal* (the
>> setuptools distribution installs pkg_resources as well as setuptools,
>> for a well-known example). So in theory, if people wanted this enough,
>> they could have implemented it right now, without needing any change
>> to Python or the packaging ecosystem.
>
> If people don't come with pitchforks, that's a good solution. I suspected
> that people would complain both if foo-tests were installed automatically
> like pkg_resources but also if foo-tests were a separate optional package
> (too much hassle).

Personally, I prefer packages that don't install their tests (I'm just
about willing to tolerate the tests-inside-the package-approach) so I
actually dislike this option myself - I was just saying it's possible.

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/


Re: [Python-ideas] Support WHATWG versions of legacy encodings

2018-02-05 Thread Paul Moore
On 5 February 2018 at 06:40, Serhiy Storchaka  wrote:
> 05.02.18 05:01, Nick Coghlan пише:
>>
>> On 2 February 2018 at 16:52, Steven D'Aprano  wrote:
>>>
>>> If it were my decision, I'd have these codecs raise a warning (not an
>>> error) when used for encoding. But I guess some people will consider
>>> that either going too far or not far enough :-)
>>
>>
>> Rob pointed out that one of the main use cases for these codecs is
>> when going "Oh, this was decoded with a WHATWG encoding, which isn't
>> right, so I need to re-encode it with that encoding, and then decode
>> it with the right encoding". So encoding is very much part of the
>> usage model: it's needed when you've received the data over a Unicode
>> based interface rather than a binary one.
>
>
> Wasn't the "surrogateescape" error handler designed for this purpose?
>
> WHATWG encodings solve the same problem that "surrogateescape", but
>
> 1) They use different range for representing unmapped characters.
> 2) Not all unmapped characters can be decoded, thus a decoding is lossy, and
> a round-trip not always works.

Surrogateescape is for when the source of the Unicode data is also
Python. The WHATWG encodings (AIUI) can be used by any tool to attempt
to decode data. If that "I think this is what it is" data is passed as
Unicode to Python, and the Python code determines that the guess was
wrong, then re-encoding it using the WHATWG encoding lets you try
again to decode it properly. The result would be lossy, yes. Whether
this is a problem, I can't say, as I've never encountered the sorts of
use cases being discussed here. I assume that the people advocating
for this have, and consider this option, even if it's lossy, to be the
best approach.

For a non-stdlib based solution, I see no problem with this. If the
codecs are to go into the stdlib, then I do think we should be able to
document clearly what the use case is for these encodings, and why a
user reading the codecs docs should pick these encodings over another
one. That's where I think the proposal currently falls down - not in
the usefulness of the codecs, nor in the naming (both of which seem to
me to have been covered) but in providing a good enough explanation
*to non-specialists* of why these codecs exist, how they should be
used, and what the caveats are. Something that we'd be comfortable
including in the docs.

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/


Re: [Python-ideas] Possible Enhancement to py Launcher - set default

2018-02-05 Thread Paul Moore
On 5 February 2018 at 08:10, Steve Barnes  wrote:
> When a new version of python is in alpha/beta it is often desirable to
> have it installed for tests but remain on a previous version for day to
> day use.
>
> However, currently the Windows py launcher defaults to the highest
> version that it finds, which means that unless you are very careful you
> will end up having to explicitly specify your older version every time
> that you start python with it once you have installed the newer version.
>
> I an thinking that it would be relatively simple to expand the current
> launcher functionality to allow the user to set the default version to
> be used.
>
> One possible syntax, echoing the way that versions are displayed with
> the -0 option would be to allow py -n.m* to set and store, either in the
> registry, environment variable or a configuration file, the desired
> default to be invoked by py or pyw.
>
> Personally I thing that this would encourage more people to undertake
> testing of new candidate releases of python.
>
> I would be interested in any feedback on the value that this might add.

There's a `py.ini` file that lets you set the default version. See
https://docs.python.org/3.6/using/windows.html#customization for
details. Is that just something you weren't aware of, or does it not
address the issue you're having?

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/


Re: [Python-ideas] Possible Enhancement to py Launcher - set default

2018-02-06 Thread Paul Moore
I'm reluctant to expand the feature set of the launcher in this
direction. It's written in C, and tightly focused on being a
lightweight launcher. Adding code to manage user options and persist
them to the py.ini file would be a non-trivial overhead, as well as
being hard to maintain (because C code and text handling :-)) It's not
that hard to manage an ini file, and if anyone wants a friendlier
interface, writing such a thing in Python as a standalone utility
would be easy, and far more robust, flexible and maintainable than
adding it to the launcher directly (you could even add a GUI if you
like ;-)).

Conceded, I'm saying this from the perspective of writing and
maintaining the code, and not from the UX/UI perspective. If someone
wants to add this feature to the launcher, I don't mind, but
*personally* I don't think it's worth it.

Paul

On 6 February 2018 at 10:10, Alex Walters  wrote:
> I actually like the idea of being able to modify the py.ini file to set the
> default from py.exe.  That seams like the most intuitive thing to me.

>> From: Python-ideas [mailto:python-ideas-bounces+tritium-
>>
>> Maybe the Windows installer should offer to set/change that, especially
>> when installing a non-release version?
___
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] Possible Enhancement to py Launcher - set default

2018-02-06 Thread Paul Moore
There are a few different points here:

1. There's no relationship between pip and the py launcher - they are
separate tools/projects. Any co-operation in terms of file locations
would have to be a result of common standards. Those would normally be
platform standards, not Python ones.
2. On Windows, pip.ini is in $env:APPDATA\pip, not ~/pip. Are you
confusing Windows and Unix conventions?
3. $env:APPDATA and $env:LOCALAPPDATA have different functions, and
the choice between the two needs to be made on a case by case basis.
However, the difference between the two is subtle, and frankly is
probably lost on Unix developers. So which gets used is somewhat
random, in practice. But it does matter, in certain environments. I
*think* the different usages here are correct (although on the systems
I work on, the distinction doesn't matter in practice so I can't
confirm that).
4. Python projects tend to actually be *better* at following Windows
platform conventions than other applications (which often use the Unix
convention of putting stuff under ~) in my experience. What looks like
inconsistency is sometimes (not in the case of py vs pip, admittedly)
just people transferring expectations from one platform to another (or
worse, transferring expectations from Unix programs naively ported to
Windows over to other Windows programs).
5. Windows history for "where you should store your application
config" is a mess - inconsistencies, changes in recommendations, and
use cases not catered for, abound. So even in the ideal situation,
what is right now was probably wrong 5 years ago. And will likely be
wrong 5 years from now (although we can hope...)

But +1 on a world where config data all gets stored consistently. Oh,
and can I have a pony? :-)

Paul


On 6 February 2018 at 14:22, Eric Fahlgren  wrote:
> My only request for change would be to consolidate the various tools'
> behavior wrt their .ini file locations.  Pip, for example, wants the file in
> ~/pip/pip.ini, while py.exe (on Windows) wants its py.ini in $LOCALAPPDATA.
> If they were all in a common location (or the same file with separate
> sections), that would make life a tiny bit easier.
>
> Eric
>
> On Tue, Feb 6, 2018 at 3:30 AM, Paul Moore  wrote:
>>
>> I'm reluctant to expand the feature set of the launcher in this
>> direction. It's written in C, and tightly focused on being a
>> lightweight launcher. Adding code to manage user options and persist
>> them to the py.ini file would be a non-trivial overhead, as well as
>> being hard to maintain (because C code and text handling :-)) It's not
>> that hard to manage an ini file, and if anyone wants a friendlier
>> interface, writing such a thing in Python as a standalone utility
>> would be easy, and far more robust, flexible and maintainable than
>> adding it to the launcher directly (you could even add a GUI if you
>> like ;-)).
>>
>> Conceded, I'm saying this from the perspective of writing and
>> maintaining the code, and not from the UX/UI perspective. If someone
>> wants to add this feature to the launcher, I don't mind, but
>> *personally* I don't think it's worth it.
>>
>> Paul
>>
>> On 6 February 2018 at 10:10, Alex Walters  wrote:
>> > I actually like the idea of being able to modify the py.ini file to set
>> > the
>> > default from py.exe.  That seams like the most intuitive thing to me.
>>
>> >> From: Python-ideas [mailto:python-ideas-bounces+tritium-
>> >>
>> >> Maybe the Windows installer should offer to set/change that, especially
>> >> when installing a non-release version?
>> ___
>> 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/


<    1   2   3   4   5   6   7   8   9   >