Re: [Python-ideas] + operator on generators
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...
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
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
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
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
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
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
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
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
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]
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]
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]
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]
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
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
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
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?
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?
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?
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
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
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
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
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
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
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
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
>>> 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
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
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
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
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
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
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
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
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
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
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
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"
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"
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"
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"
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
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"
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
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
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?
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?
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?
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
>> 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
[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?
-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
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?
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?
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?
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)
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
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?
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?
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?
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
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?
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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/