[Python-ideas] __dir__ in which folder is this py file
Hi Ideas, I often need to reference a script's current directory. I end up writing: import os SRC_DIR = os.path.dirname(__file__) But I would prefer to have a new dunder for that. I propose: "__dir__". I was wondering if others would find it convenient to include such a shortcut. Here are some examples of dirname(__file__) in prominent projects. https://github.com/tensorflow/models/search?l=Python&q=dirname&type= https://github.com/django/django/search?l=Python&q=dirname&type= https://github.com/nose-devs/nose/search?l=Python&q=dirname&type= Reasons not to add __dir__: * There already is one way to do it and it's clear and fairly short. * Avoid the bikeshed discussion of __dir__, __folder__, and other candidates. Reasons to add it: * os.path.dirname(__file__) returns the empty string when you're in the same directory as the script. Luckily, os.path.join understands an empty string as a ".", but this still is suboptimal for logging where it might be surprising to find the empty string. __dir__ could be implemented to contain a "." in that case. * I would save about 20 characters and a line from 50% of my python scripts. * This is such a common construct that everyone giving it their own name seems suboptimal for communicating. Common names include: here, path, dirname, module_dir. Cheers, Yuval Greenfield P.s. nodejs has it - https://nodejs.org/docs/latest/api/modules.html#modules_dirname also I apologize if this has been suggested before - my googling didn't find a previous thread. ___ 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] Inline assignments using "given" clauses
[Nick] >... > There were a couple key reasons I left the "for x in y" case out of the > initial proposal: > > 1. The "for x in y" header is already quite busy, especially when tuple > unpacking is used in the assignment target > 2. Putting the "given" clause at the end would make it ambiguous as to > whether it's executed once when setting up the iterator, or on every > iteration > 3. You can stick in an explicit "if True" if you don't need the given > variable in the filter condition > > [(fx**2, fx**3) for x in xs if True given fx = f(x)] > > And then once you've had an entire release where the filter condition was > mandatory for the comprehension form, allowing the "if True" in "[(fx**2, > fx**3) for x in xs given fx = f(x)]" to be implicit would be less ambiguous. And some people claim ":=" would make Python harder to teach ;-) [Tim] >> ... >> It''s certain sanest as >> >> if x**2 + y**2 > 9 given x, y = func_returning_twople(): >> >> "given" really shines there! > Yep, that's why I don't have the same immediate reaction of "It would need > to be limited to simple names as targets" reaction as I do for assignment > expressions. It might still be a good restriction to start out with, though I contrived that specific "use case", of course - I actually didn't stumble into any real code where multiple targets would benefit to my eyes. Perhaps because, as you noted above of `"for x in y" headers`, multiple-target assignment statements are often quite busy already too (I have no interest in cramming as much logic as possible into each line - but "sparse is better than dense" doesn't also mean "almost empty is better than sparse" ;-) ). > (especially if we wanted to allow multiple name bindings in a single given > clause). >> ... >> The one-letter variable name obscures that it doesn't >> actually reduce _redundancy_, though. That is, in the current >> >> match = pattern.search(data) >> if match: >> >> it's obviously less redundant typing as: >> >> if match := pattern.search(data): >> >> In >> >> if match given match = pattern.search(data): >> >> the annoying visual redundancy (& typing) persists. > Right, but that's specific to the case where the desired condition really is > just "bool(target)". Not only. If the result _needs_ to be used N times in total in the test, binding expressions allow for that, but `given` requires N+1 instances of the name (the "extra one" to establish the name to begin with). For example, where `probable_prime()` returns `True` or `False`, and `bool(candidate)` is irrelevant: # highbit is a power of 2 >= 2; create a random prime # whose highest bit is highbit while (not probable_prime(candidate) given candidate = highbit | randrange(1, highbit, 2)): pass versus while not probable_prime(candidate := highbit | randrange(1, highbit, 2)): pass There I picked a "long" name to make the redundancy visually annoying ;-) > That's certainly likely to be a *common* use case, In all the code I looked at where I believe a gimmick like this would actually help, it was indeed by far _most_ common that the result only needed to be used once in the test. In all such cases, the binding expression spelling of the test requires one instance of the name, and the `given` spelling two. > but if we decide that it's *that* particular flavour of redundancy that really > bothers us, then there's always the "if expr as name:" spelling (similar to > the way that Python had "a and b" and "a or b" logical control flow > operators long before it got "a if c else b"). Reducing each redundancy is a small win to me, but reaches "importance" because it's so frequent. Binding expressions have more uses than _just_ that, though. But I'm sure I don't know what they all are. When a _general_ feature is added, people find surprising uses for it. For example, at times I'd love to write code like this, but can't: while any(n % p == 0 for p in small_primes): # divide p out - but what is p? Generator expressions prevent me from seeing which value of `p` succeeded. While that's often "a feature", sometimes it's a PITA. I don't know whether this binding-expression stab would work instead (I'm not sure the PEP realized there's "an issue" here, about the intended scope for `thisp`): while any(n % (thisp := p) == 0 for p in small_primes): n //= thisp If that is made to work, I think that counts as "a surprising use" (capturing a witness for `any(genexp)` and a counterexample for `all(genexp)`, both of which are wanted at times, but neither of which `any()`/`all()` will ever support on their own).. I suppose I could do it with `given` like so: while p is not None given p = next( (p for p in small_primes if n % p == 0), None): n //= p but at that point I'd pay to go back to the original loop-and-a-half ;-) >> One more, a
Re: [Python-ideas] Add "default" kw argument to operator.itemgetter and operator.attrgetter
Hi Vincent, Your idea is interesting but we are worried that there are not enough real use cases where it would be useful. Have you encountered situations yourself where this would make a difference? I am asking not for clarifying examples (you already provided one and from that it's perfectly clear to me what you are proposing) but for real-world code that would benefit from this addition to the itemgetter API. --Guido On Wed, May 2, 2018 at 1:08 AM, Vincent Maillol wrote: > Hi everybody, > > Our PEP idea would be to purpose to add a global default value for > itemgeet and attrgetter method. > > This was inspired from bug 14384 (https://bugs.python.org/issue14384); > opened by Miki TEBEKA. > > For example, we could do: > > p1 = {'x': 43; 'y': 55} > x, y, z = itemgetter('x', 'y', 'z', default=0)(values) > print(x, y, z) > 43, 55, 0 > > instead of: > > values = {'x': 43; 'y': 55} > x = values.get('x', 0) > y = values.get('y', 0) > z = values.get('z', 0) > print(x, y, z) > 43, 55, 0 > > The goal is to have have concise code and improve consistency with > getattr, attrgetter and itemgetter > > What are you thinking about this? > > MAILLOL Vincent > GALODE Alexandre > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > -- --Guido van Rossum (python.org/~guido) ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Python-ideas Digest, Vol 138, Issue 32
On 6 May 2018 at 07:59, Angus Hollands wrote: > If, however, the motivation for the PEP was deemed significant enough that > warrant its inclusion in a future release, then I would like to suggest > that the keyword approach is superior to the operator variant. In > particular, I prefer the `where` to the `given` or 'let' candidates, as I > think it is more descriptive and slightly shorter to type ;) > Aside from an API naming conflict with NumPy, the key problem with using "where" for this purpose is that "where" is explicitly used to name *filtering* clauses in SQL, NumPy, and other contexts ("having" is used in a similar way for filtering on SQL aggregate groups). So in "[(x, y, x/y) for x in data if y where y = f(x)]", having both an "if" clause and a "where" clause makes it look like there are two filters being defined (and a mispelt "==" in the second one), rather than a filter and a name binding. The virtue of "given" is that in any context which uses it, the intended meaning is to associate a name with a value (either directly, as in the mathematical usage, or indirectly, as in the hypothesis API usage), which is exactly the meaning we're interested in here. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Inline assignments using "given" clauses
On 6 May 2018 at 02:06, Nick Coghlan wrote: > On 4 May 2018 at 22:06, Nick Coghlan wrote: > >> (Note: Guido's already told me off-list that he doesn't like the way this >> spelling reads, but I wanted to share it anyway since it addresses one of >> the recurring requests in the PEP 572 discussions for a more targeted >> proposal that focused specifically on the use cases that folks had agreed >> were reasonable potential use cases for inline assignment expressions. >> >> I'll also note that another potential concern with this specific proposal >> is that even though "given" wasn't used as a term in any easily discovered >> Python APIs back when I first wrote PEP 3150, it's now part of the >> Hypothesis testing API, so adopting it as a keyword now would be markedly >> more disruptive than it might have been historically) >> > > Since I genuinely don't think this idea is important enough to disrupt > hypothesis's public API, I've been pondering potential synonyms that are > less likely to be common in real world code, while still being > comprehensible and useful mnemonics for the proposed functionality. > I've also been pondering Tim's suggestion of instead enhancing the code generation pipeline's native support for pseudo-keywords in a way that can be explicitly represented in the Grammar and AST, rather than having to be hacked in specifically every time we want to introduce a new keyword without a mandatory __future__ statement (and without creating major compatibility headaches for code that uses those new keywords as attribute or variable names). While I haven't actually tried this out yet, the way I'm thinking that might look is to add the following nodes to the grammar: name_plus: NAME | pseudo_keyword pseudo_keyword: 'given' and the replace all direct uses of 'NAME' in the grammar with 'name_plus'. That way, to allow a new keyword to be used as a name in addition to its syntactic use case, we'd add it to the pseudo_keyword list in addition to adding it to . To avoid ambiguities in the grammar, this could only be done for keywords that *can't* be used to start a new expression or statement (so it wouldn't have been sufficient for the async/await case, since 'async' can start statements, and 'await' can start both statements and expressions). So if Guido's view on the out-of-order execution approach to inline name binding softens, I think this would be a better approach to pursue than making a more awkward keyword choice. Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Add "default" kw argument to operator.itemgetter and operator.attrgetter
At some point, we're really better off just using a lambda. Maybe I'm slow today, but I'm having trouble seeing how to write this as a lambda. >>> values = {'x': 43, 'y': 55} >>> x, y, z = (lambda *args : tuple(values.get(arg,0) for arg in args))('x','y','z') >>> print(x, y, z) (43, 55, 0) >>> Rob Cliffe ___ 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-ideas Digest, Vol 138, Issue 32
Hi all! Really interesting discussion on here. Personally I feel that PEP 572, as it stands, undermines the readability of the language, in particular for those new to the language, programming. I have issue with both the in-expression assignment, and the current proposed operator approach. Below is a modified version of a comment I made on a Reddit thread about this. I think the first point is that, beginners often read more code than they write - to build a mental picture of how the language works, and to build their solution from existing parts. Whether this is a good means of learning, or not, it's quite commonplace (and I learned using such a method). If this PEP passes, you will find people use the syntax. And it may well end up being disproportionately used in the early stages because of "new feature" semantics. Here is an extract from the Wikipedia A* search function reconstruct_path(cameFrom, current) total_path := [current] while current in cameFrom.Keys: current := cameFrom[current] total_path.append(current) return total_path In Python 3.7, that looks like this: def reconstruct_path(cameFrom, current): total_path = [current] while current in cameFrom.keys(): current = cameFrom[current] total_path.append(current) return total_path (of course it's not entirely Pythonic), but the point is - the pseudo code is designed to be semantically readable, and the Python code is very similar However with PEP572, now, the beginner will encounter both := assignments, and = assignments. When to use which one? Now they need to learn the edge cases / semantic differences between expression and statement explicitly, rather than picking this up as they go. I am not making this argument because I think that this is they best way to learn a programming language, I'm simply arguing that there is more cognitive overhead when unfamiliar with the language, in order to use the appropriate feature. In terms of implementation, it's especially odd that the current proposal (AFAICT) only binds to a name, rather than an assignment target. This feels very wrong, despite the fact that I can understand why it is suggested. I feel like the Python 3 series in particular has been making syntax more uniform, so that there aren't quirks and edge cases of "this only works in this context" (besides async, of course), which is one of the things that makes Python so expressive. Furthermore, with this PEP, assignment can now happen inside of expressions - and so one of the most fundamental benefits of expressions being effectively immutable in terms of local names is lost. In terms of prevalence, I don't think that these situations do occur all that often. I definitely agree that regex is the prime candidate for this kind of syntax. However, in the examples given (matching 3+ regexes), I would use a loop for simplicity anyway. When it comes to assigning to a result that is only used in the conditional block, this is certainly a case that benefits from the PEP. If, however, the motivation for the PEP was deemed significant enough that warrant its inclusion in a future release, then I would like to suggest that the keyword approach is superior to the operator variant. In particular, I prefer the `where` to the `given` or 'let' candidates, as I think it is more descriptive and slightly shorter to type ;) Thanks! Angus Hollands ___ 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] Pattern Matching Syntax
[Tim] ... I liked the way he _reached_ that conclusion: by looking at real- life Python code that may have been written instead to use constructs "like this". I find such examination far more persuasive than abstract arguments or made-up examples. [Serhiy] >>> I would like to see such examination for PEP 572. And for all other >>> syntax changing ideas. [Tim] >> I did it myself for 572, and posted several times about what I found. [Serhiy] > Could you please give links to these results? It is hard to find something > in hundreds of messages. It's no easier for me to find old messages, and you'd just ask for more & more anyway ;-) The "short course" I already gave didn't skip anything vital: Short course: I found a small win frequently, a large win rarely, but in most cases wouldn't use it. In all I expect I'd use it significantly more often than ternary "if", but far less often than augmented assignment. More importantly: But that's me - everybody needs to look at their own code to apply _their_ judgment. It's _applying_ the approach I find persuasive & productive, not someone else writing up the results of _their_ taking the approach. I'm not trying to change peoples' minds - just suggesting a more fruitful way (than abstract arguments, fashion, ...) to make up their minds to begin with. > I withdrew some my ideas and patches when my examinations showed that the > number of cases in the stdlib that will take a benefit from rewriting using > a new feature or from applying a compiler optimization is not large enough. Bingo! Note your "my examinations" in that. Someone who hasn't done their own examination is basically guessing. They may or may not reach the same conclusions if they did the work, but neither eloquence nor confidence is a reliable predictor of whether they would. Passion may even be negatively correlated ;-) ___ 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] Inline assignments using "given" clauses
On 4 May 2018 at 22:06, Nick Coghlan wrote: > (Note: Guido's already told me off-list that he doesn't like the way this > spelling reads, but I wanted to share it anyway since it addresses one of > the recurring requests in the PEP 572 discussions for a more targeted > proposal that focused specifically on the use cases that folks had agreed > were reasonable potential use cases for inline assignment expressions. > > I'll also note that another potential concern with this specific proposal > is that even though "given" wasn't used as a term in any easily discovered > Python APIs back when I first wrote PEP 3150, it's now part of the > Hypothesis testing API, so adopting it as a keyword now would be markedly > more disruptive than it might have been historically) > Since I genuinely don't think this idea is important enough to disrupt hypothesis's public API, I've been pondering potential synonyms that are less likely to be common in real world code, while still being comprehensible and useful mnemonics for the proposed functionality. The variant I've most liked is the word "letting" (in the sense of "while letting these names have these values, do ..."): # Exactly one branch is executed here if m letting m = pattern.search(data): ... elif m letting m = other_pattern.search(data)): ... else: ... # This name is rebound on each trip around the loop while m letting m = pattern.search(remaining_data): ... # "f(x)" is only evaluated once on each iteration result = [(x, y, x/y) for x in data if y letting y = f(x)] # Tim's "bind two expressions" example if diff and g > 1 letting diff = x - x_base, g = gcd(diff, n): return g # The "bind two expressions" example across multiple lines while diff and g > 1 letting ( diff = x - x_base, g = gcd(diff, n), ): ... # Do something with diff and g Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Inline assignments using "given" clauses
On 5 May 2018 at 13:36, Tim Peters wrote: > [Nick Coghlan ] > > ... > > The essence of the given clause concept would be to modify *these > specific > > cases* (at least initially) to allow the condition expression to be > followed > > by an inline assignment, of the form "given TARGET = EXPR". > > I'm not clear on what "these specific cases" are, specifically ;-) > Conditions in "if", "elif", and "while" statement expressions? > Exactly the 3 cases presented (if/elif/while conditions). The usage in comprehensions would mirror the usage in if statements, and avoid allowing name bindings in arbitrary locations due to the implicity nested scopes used by comprehensions. Conditional expressions would be initially omitted since including them would allow arbitrary name bindings in arbitrary locations via the quirky "x if x given x = expr else x" spelling, and because "else" isn't as distinctive an ending token as "given ... :", "given ... )", "given ... ]", or "given ... }". > Restricted to one "given" clause, or can they chain? In a listcomp, > is it one "given" clause per "if", or after at most one "if"? Or is > an "if" even needed at all in a listcomp? For example, > > [(f(x)**2, f(x)**3) for x in xs] > > has no conditions, and > > [(fx := f(x))**2, fx**3) for x in xs] > > is one reasonable use for binding expressions. > > [(fx**2, fx**3) for x in xs given fx = f(x)] > > reads better, although it's initially surprising (to my eyes) to find > fx defined "at the end". But no more surprising than the current: > > [(fx**2, fx**3) for x in xs for fx in [f(x)]] > > trick. > > There were a couple key reasons I left the "for x in y" case out of the initial proposal: 1. The "for x in y" header is already quite busy, especially when tuple unpacking is used in the assignment target 2. Putting the "given" clause at the end would make it ambiguous as to whether it's executed once when setting up the iterator, or on every iteration 3. You can stick in an explicit "if True" if you don't need the given variable in the filter condition [(fx**2, fx**3) for x in xs if True given fx = f(x)] And then once you've had an entire release where the filter condition was mandatory for the comprehension form, allowing the "if True" in "[(fx**2, fx**3) for x in xs given fx = f(x)]" to be implicit would be less ambiguous. [snip] > It''s certain sanest as > > if x**2 + y**2 > 9 given x, y = func_returning_twople(): > > "given" really shines there! > Yep, that's why I don't have the same immediate reaction of "It would need to be limited to simple names as targets" reaction as I do for assignment expressions. It might still be a good restriction to start out with, though (especially if we wanted to allow multiple name bindings in a single given clause). [snip] The one-letter variable name obscures that it doesn't > actually reduce _redundancy_, though. That is, in the current > > match = pattern.search(data) > if match: > > it's obviously less redundant typing as: > > if match := pattern.search(data): > > In > > if match given match = pattern.search(data): > > the annoying visual redundancy (& typing) persists. > Right, but that's specific to the case where the desired condition really is just "bool(target)". That's certainly likely to be a *common* use case, but if we decide that it's *that* particular flavour of redundancy that really bothers us, then there's always the "if expr as name:" spelling (similar to the way that Python had "a and b" and "a or b" logical control flow operators long before it got "a if c else b"). One more, a lovely (to my eyes) binding expression simplification > requiring two bindings in an `if` test, taken from real-life code I > happened to write during the PEP discussion: > > diff = x - x_base > if diff: > g = gcd(diff, n) > if g > 1: > return g > > collapsed to the crisp & clear: > > if (diff := x - x_base) and (g := gcd(diff, n)) > 1: > return g > > If only one trailing "given" clause can be given per `if` test > expression, presumably I couldn't do that without trickery. I was actually thinking that if we did want to allow multiple assignments, and we limited targets to single names, we could just use a comma as a separator: if diff and g > 1 given diff = x - x_base, g = gcd(diff, n): return g Similar to import statements, optional parentheses could be included in the grammar, allowing the name bindings to be split across multiple lines: if diff and g > 1 given ( diff = x - x_base, g = gcd(diff, n), ): return g (Other potential separators would be ";", but that reads weirdly to me since my brain expects the semi-colon to end the entire statement, and "and", but that feels overly verbose, while also being overly different from its regular meaning) > If it's > more general, > > if (diff given diff = x _ xbase) and g > 1 given g = gcd(diff, n):
Re: [Python-ideas] Runtime assertion with no overhead when not active
05.05.18 18:04, Eloi Gaudry пише: By 'self-contained', I meant that using the assert keyword and its expression is sufficient. An inline assertive expression as the one you describe does not fulfill this assert requirement. Sufficient for what? And why writing with using the existing syntax is not sufficient? My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime. The main property of the assert statement is that has a zero overhead in non-debug run. If you remove this property, it will be not the assert statement, and you will not need a special syntax support for writing this runtime check. The syntax example I gave illustrated what I meant by syntax aware. It doesn't illustrate why a new syntax is necessary. Or I can't understand this illustration. ___ 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] Inline assignments using "given" clauses
05.05.18 18:26, Nick Coghlan пише: 3. writing back to the local namespace via exec doesn't work consistently at function scope (and assuming PEP 558 is eventually accepted, will some day reliably *never* work) At end you can convert the source of the whole script to a string literal and write the whole script in one line. The problem solved! ___ 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] Runtime assertion with no overhead when not active
On Sat, May 05, 2018 at 08:04:45AM +, Eloi Gaudry wrote: > Hi folks, > I intend to add a runtime assertion feature in python. I'm very interested in this idea, but I'm afraid your draft PEP isn't very clear about this feature. Comments below. > Rationale > There is no runtime assert relying on python grammar available. For > diagnostics and/or debugging reasons, it would be valuable to add such > a feature. Why not this? if DEBUG_ENABLED: run_check(expression) where run_check is an ordinary function. If DEBUG_ENABLED is false, the only runtime overhead is the name lookup and bool test, the expression is not evaluated. What features does your suggestion offer over this simple technique? [...] > A brief example why avoiding evaluating the expression is needed to > avoid any overhead in case the runtime assert should be ignored. > :: > runtime_assert( 999 in { i:None for i in range( 1000 ) } ) You say that you have been using this feature in production for two years. You should give real-life examples, not fake examples like the above. That example would be better written as: runtime_assert(True) since no part of the test actually depends on either the enormous dict or range objects that you build only to throw away. > Usage > :: > > runtime_assert( expr ) > > #would result in > if expr and runtime_assert_active: > print RuntimeAssertionError() Surely the test should be the other way around? if runtime_assert_active and expr: print(RuntimeAssertionError()) otherwise the expression is evaluated regardless of whether the runtime assertions are active or not. Please use Python 3 syntax for the PEP, as Python 2 is in maintenance mode and will absolutely not get any new language features. Some more observations: I like the idea of more control over runtime checking, but your PEP should justify why this is a good idea and why "just write more unit tests" isn't the solution. What happens if the caller has defined their own function or variable called runtime_assert? Can the caller customise the assertion error message? If you are changing the grammar, why not make runtime_assert a statement? Can the caller set an application-wide global across all modules, or do they have to set runtime_assert_active = True in every module they want to use runtime_assert? -- Steve ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Inline assignments using "given" clauses
On 6 May 2018 at 00:33, Mikhail V wrote: > recently I have discovered interesting fact: it seems one > can already use 'inline assignment' with current syntax. E.g.: > > if exec("m = input()") or m: > print (m) > > It seem to work as inline assignment correctly. > Yes it is just coincidence, BUT: this has the wanted effect! > - hides one line in "if" and "while" > - leaves the assignment statement (or is it expression now? ;) > - has explicit appearance > > So we have it already? > Not really, since: 1. exec with a plain string has a very high runtime cost (the compiler is pretty slow, since we assume the results will be cached) 2. exec'ed strings are generally opaque to static analysis tools 3. writing back to the local namespace via exec doesn't work consistently at function scope (and assuming PEP 558 is eventually accepted, will some day reliably *never* work) Cheers, Nick. -- Nick Coghlan | ncogh...@gmail.com | Brisbane, Australia ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Runtime assertion with no overhead when not active
By 'self-contained', I meant that using the assert keyword and its expression is sufficient. An inline assertive expression as the one you describe does not fulfill this assert requirement. My proposal is simply to extend the current assert to non-debug builds and allow to switch it off/on at runtime. The syntax example I gave illustrated what I meant by syntax aware. De : Serhiy Storchaka Envoyé : samedi 5 mai à 15:10 Objet : Re: [Python-ideas] Runtime assertion with no overhead when not active À : python-ideas@python.org 05.05.18 15:54, Eloi Gaudry пише: > I meant avoiding the overhead of the expression evaluation enclosed in the assert itself, not the active/disabled state (that comes at virtually no cost). > ex: runtime_assert( { i:None for i in range( 1000 ) } ) > > By using the syntax you describe ('boolean and not expr'), you loose all the benefit of the Python grammar: > - self-contained Could you please explain what you mean? > - able to catch semantic/syntax bugs > > ex: f=1 runtime_assert( f==1 ) runtime_assert( f=1 ) > File "", line 1 > runtime_assert( f=1 ) > ^ > SyntaxError: invalid syntax Until inline assignment expression is implemented, this is an error too: >>> if debug and not f=1: File "", line 1 if debug and not f=1: ^ SyntaxError: invalid syntax ___ 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] Inline assignments using "given" clauses
On Fri, May 4, 2018 at 3:06 PM, Nick Coghlan wrote: > > With that spelling, the three examples above would become: > > # Exactly one branch is executed here > if m given m = pattern.search(data): > ... > elif m given m = other_pattern.search(data)): > ... > else: > ... > > # This name is rebound on each trip around the loop > while m given m = pattern.search(remaining_data): > ... > > # "f(x)" is only evaluated once on each iteration > result = [(x, y, x/y) for x in data if y given y = f(x)] > Well, I think it looks good. Nice job Nick! I like that it leaves the "=" alone finally (but it's maybe the reason why I am biased towards this syntax :) It has clear look so as not to confuse with conditionals and the variable is emphasized so it's well understood what it means. I wish I could like the whole idea of inline assignments more now - but well, it is just what it is. Something that can help on rare occasion. But as said, your variant feels right to me. Unlike with most other proposed constructs here my first impression - this is Python. If the new keyword is too much, there are some options too choose from. (though I've no idea whether this is plausible due to parsing ambiguities) if m given m = pattern.search(data): vs: if m with m = pattern.search(data): if m def m = pattern.search(data): if m as m = pattern.search(data): Yes, all these reads strange, but IMO understandable. BTW, using your keyword, in comprehensions vs the original idea of Chris then merely I suppose: result = [(x, y, x/y) given y = f(x) for x in data if y ]vs result = [(x, y, x/y) with y = f(x) for x in data if y ] result = [(x, y, x/y) def y = f(x) for x in data if y ] result = [(x, y, x/y) as y = f(x) for x in data if y ] vs result = [(x, y, x/y) for x in data if y given y = f(x)] vs result = [(x, y, x/y) for x in data if y with y = f(x)] result = [(x, y, x/y) for x in data if y def y = f(x)] result = [(x, y, x/y) for x in data if y as y = f(x)] I can't say for sure what is better but the former order seems to be slightly more appealing for some reson. [Tim] > it's obviously less redundant typing as: > if match := pattern.search(data): > In > if match given match = pattern.search(data): I disagree, I think it is not redundant but it's just how it is - namely it does not introduce 'implicitness' in the first place, and that is what I like about Nick's variant. But of course it is less compact. PS: recently I have discovered interesting fact: it seems one can already use 'inline assignment' with current syntax. E.g.: if exec("m = input()") or m: print (m) It seem to work as inline assignment correctly. Yes it is just coincidence, BUT: this has the wanted effect! - hides one line in "if" and "while" - leaves the assignment statement (or is it expression now? ;) - has explicit appearance So we have it already? Mikhail ___ 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] Runtime assertion with no overhead when not active
05.05.18 15:54, Eloi Gaudry пише: I meant avoiding the overhead of the expression evaluation enclosed in the assert itself, not the active/disabled state (that comes at virtually no cost). ex: runtime_assert( { i:None for i in range( 1000 ) } ) By using the syntax you describe ('boolean and not expr'), you loose all the benefit of the Python grammar: - self-contained Could you please explain what you mean? - able to catch semantic/syntax bugs ex: f=1 runtime_assert( f==1 ) runtime_assert( f=1 ) File "", line 1 runtime_assert( f=1 ) ^ SyntaxError: invalid syntax Until inline assignment expression is implemented, this is an error too: >>> if debug and not f=1: File "", line 1 if debug and not f=1: ^ SyntaxError: invalid syntax ___ 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] Runtime assertion with no overhead when not active
I meant avoiding the overhead of the expression evaluation enclosed in the assert itself, not the active/disabled state (that comes at virtually no cost). ex: >>> runtime_assert( { i:None for i in range( 1000 ) } ) By using the syntax you describe ('boolean and not expr'), you loose all the benefit of the Python grammar: - self-contained - able to catch semantic/syntax bugs ex: >>> f=1 >>> runtime_assert( f==1 ) >>> runtime_assert( f=1 ) File "", line 1 runtime_assert( f=1 ) ^ SyntaxError: invalid syntax -Original Message- From: Python-ideas On Behalf Of Serhiy Storchaka Sent: Saturday, May 5, 2018 2:05 PM To: python-ideas@python.org Subject: Re: [Python-ideas] Runtime assertion with no overhead when not active 05.05.18 11:04, Eloi Gaudry пише: > Briefly, the idea is to add a new assert that can be switch on/off > depending on some variable/mechanism at runtime. The whole point of > this assert is that it should not bring any overhead when off, i.e. > by avoiding evaluating the expression enclosed in the runtime > assert. It thus relies on Python grammar. You should have an overhead for checking if it is switched on/off, isn't? And this overhead is virtually the same as testing the value of the global boolean variable. > runtime_assert( expr ) > > #would result in if expr and runtime_assert_active: > > print RuntimeAssertionError() How this will be different from if debug and not expr: print(RuntimeAssertionError()) ? ___ 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] Runtime assertion with no overhead when not active
05.05.18 11:04, Eloi Gaudry пише: Briefly, the idea is to add a new assert that can be switch on/off depending on some variable/mechanism at runtime. The whole point of this assert is that it should not bring any overhead when off, i.e. by avoiding evaluating the expression enclosed in the runtime assert. It thus relies on Python grammar. You should have an overhead for checking if it is switched on/off, isn't? And this overhead is virtually the same as testing the value of the global boolean variable. runtime_assert( expr ) #would result in if expr and runtime_assert_active: print RuntimeAssertionError() How this will be different from if debug and not expr: print(RuntimeAssertionError()) ? ___ 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] Runtime assertion with no overhead when not active
Hi folks, I intend to add a runtime assertion feature in python. Before submitting a PEP, I am sending a draft to this mailing list to discuss whether it would make sense (above this message). I have actually been using it for the last 2 years and it has proven to be robust and has achieved its primary goal. Briefly, the idea is to add a new assert that can be switch on/off depending on some variable/mechanism at runtime. The whole point of this assert is that it should not bring any overhead when off, i.e. by avoiding evaluating the expression enclosed in the runtime assert. It thus relies on Python grammar. Thanks for your feedback. Eloi Abstract This PEP aims at offering a runtime assert functionnality, extending the compiletime assert already available. Rationale There is no runtime assert relying on python grammar available. For diagnostics and/or debugging reasons, it would be valuable to add such a feature. A runtime assert makes sense when extra checks would be needed in a production environment (where non-debug builds are used). By extending the current python grammar, it would be possible to limit the overhead induces by those runtime asserts when running in a non "assertive" mode (-ed). The idea here is to avoid evaluating the expression when runtime assertion is not active. A brief example why avoiding evaluating the expression is needed to avoid any overhead in case the runtime assert should be ignored. :: runtime_assert( 999 in { i:None for i in range( 1000 ) } ) Usage :: runtime_assert( expr ) #would result in if expr and runtime_assert_active: print RuntimeAssertionError() Implementation details There is already an implementation available, robust enough for production. The implementation is mainly grammar based, and thus the parser and the grammar needs to be updated: * Python/graminit.c * Python/ast.c * Python/symtable.c * Python/compile.c * Python/Python-ast.c * Python/sysmodule.c * Modules/parsermodule.c * Include/Python-ast.h * Include/graminit.h * Include/pydebug.h * Grammar/Grammar * Parser/Python.asdl * Lib/lib2to3/Grammar.txt * Lib/compiler/ast.py * Lib/compiler/pycodegen.py * Lib/compiler/transformer.py * Lib/symbol.py * Modules/parsermodule.c References [1] PEP 306, How to Change Python's Grammar (http://www.python.org/dev/peps/pep-0306) Copyright This document has been placed in the public domain. ___ 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] Inline assignments using "given" clauses
I think that "expr as y" was discarded too quickly. It would be a syntax completely familiar to Python programmers, and the new semantics would be obvious. That choice would also be in line with the Zen of Python. The special cases that may arise over "except" and "with" can be worked out and documented. Cheers, On Sat, May 5, 2018 at 5:22 AM, Robert Vanden Eynde wrote: > I agree it would be useful to have new keywords without being reserved, > and we could even go with mechanism like infix operators created by user. > > It would allow things like [given for x in range(5) given given = x+1] or > even [given for given in range(given) given given = given + 1] haha, but as > other pointed out, it would be called Bad practice ^^ > > By the way, I still prefer "where" to "given". > > Le sam. 5 mai 2018 à 10:52, Greg Ewing a > écrit : > >> Tim Peters wrote: >> > "async def", "async for", and "async with" statements were added >> > _without_ making "async" a new reserved word. It may require pain in >> > the parser, but it's often doable anyway. >> >> There would be less pain if the parser generator could >> deal with non-reserved keywords more directly. >> >> -- >> Greg >> ___ >> Python-ideas mailing list >> Python-ideas@python.org >> https://mail.python.org/mailman/listinfo/python-ideas >> Code of Conduct: http://python.org/psf/codeofconduct/ >> > > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > > -- Juancarlo *Añez* ___ 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] Inline assignments using "given" clauses
I agree it would be useful to have new keywords without being reserved, and we could even go with mechanism like infix operators created by user. It would allow things like [given for x in range(5) given given = x+1] or even [given for given in range(given) given given = given + 1] haha, but as other pointed out, it would be called Bad practice ^^ By the way, I still prefer "where" to "given". Le sam. 5 mai 2018 à 10:52, Greg Ewing a écrit : > Tim Peters wrote: > > "async def", "async for", and "async with" statements were added > > _without_ making "async" a new reserved word. It may require pain in > > the parser, but it's often doable anyway. > > There would be less pain if the parser generator could > deal with non-reserved keywords more directly. > > -- > Greg > ___ > Python-ideas mailing list > Python-ideas@python.org > https://mail.python.org/mailman/listinfo/python-ideas > Code of Conduct: http://python.org/psf/codeofconduct/ > ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/
Re: [Python-ideas] Inline assignments using "given" clauses
Tim Peters wrote: "async def", "async for", and "async with" statements were added _without_ making "async" a new reserved word. It may require pain in the parser, but it's often doable anyway. There would be less pain if the parser generator could deal with non-reserved keywords more directly. -- Greg ___ Python-ideas mailing list Python-ideas@python.org https://mail.python.org/mailman/listinfo/python-ideas Code of Conduct: http://python.org/psf/codeofconduct/