Re: [Python-Dev] Cherry-pick between Python 3.4 RC2 and final?
On 5 Mar 2014 12:48, "Larry Hastings" wrote: > > On 03/04/2014 03:59 PM, Barry Warsaw wrote: >> >> I too would like an rc3, especially to see if issue 19021 can be fixed, which >> I suspect will hit a lot of people. > > > I talked to the other guys on the 3.4 team, and we're all willing to do an rc3 this weekend. I'll add that to PEP 429. Thanks Larry, I just saw that commit. It's genuinely appreciated! :) > In other news, I'm thrilled to confirm something Antoine mentioned a week or two ago: it is literally impossible for garden-variety core devs to push new branches back into trunk. I tried to, early this morning (PST), with someone logged in to hg.python.org ready to clean up in case it actually worked. But happily hg hooks on the server reject new branches every time. Ah, *now* I understand your concern - yes, that hook was put in place during the initial migration to Mercurial, but if you weren't aware of it, then your desire to keep the release clone offline to prevent erroneous pushes makes a lot more sense to me :) > Since this banishes my chief objection to publishing the repo where I do my cherry picking, I'll be publishing that repo this week. I think I still have a rebase ahead of me, so I'm going wait until after the latest (and hopefully last!) round of cherry-picking. I'll post to python-dev once the tree is public. Sweet, thanks! Cheers, Nick. > > > /arry > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com > ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Cherry-pick between Python 3.4 RC2 and final?
Le 05/03/2014 03:46, Larry Hastings a écrit : On 03/04/2014 03:59 PM, Barry Warsaw wrote: I too would like an rc3, especially to see if issue 19021 can be fixed, which I suspect will hit a lot of people. I talked to the other guys on the 3.4 team, and we're all willing to do an rc3 this weekend. I'll add that to PEP 429. In other news, I'm thrilled to confirm something Antoine mentioned a week or two ago: it is literally impossible for garden-variety core devs to push new branches back into trunk. I tried to, early this morning (PST), with someone logged in to hg.python.org ready to clean up in case it actually worked. But happily hg hooks on the server reject new branches every time. And I thought the hook would be overkill! Regards Antoine. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
[Python-Dev] Reference cycles in Exception.__traceback__
Hi, Python 3 now stores the traceback object in Exception.__traceback__ and exceptions can be chained through Exception.__context__. It's convinient but it introduced tricky reference cycles if the exception object is used out of the except block. Refrences: Exception.__traceback__ -> traceback -> frames -> local variables Exception.__traceback__ keeps strong references to local variables which will only be deleted after the exception is destroyed. It becomes worse if the exception is stored in an object which is also a local variables somewhere in the traceback: DebugObject -> Exception -> ... frame -> DebugObject For a concrete example of object storing an exception, see Future.set_exception() of the ayncio module. Python 3.4 introduced frame.clear(), but frame.clear() raises an RuntimeError if the frame is still running. And it doesn't break all reference cycles. An obvious workaround is to store the traceback as text, but this operation is "expensive" especially if the traceback is only needed in rare cases. I tried to write "views" of the traceback (and frames), but Exception.__traceback__ rejects types other than traceback and traceback instances cannot be created. It's possible to store the traceback somewhere else and set Exception.__traceback__ to None, but there is still the problem with chained exceptions. Any idea for a generic fix to such problem? Another workaround is to set Exception.__traceback__ to None in release mode, and leaves it unchanged in debug mode. But it's not a good solution because bugs also occur in production, and most tricky bugs *only* occur in production :-) For more info, see: http://bugs.python.org/issue20032 http://code.google.com/p/tulip/issues/detail?id=42 http://code.google.com/p/tulip/issues/detail?id=155 Victor ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
Le 05/03/2014 17:37, Victor Stinner a écrit : Python 3.4 introduced frame.clear(), but frame.clear() raises an RuntimeError if the frame is still running. And it doesn't break all reference cycles. An obvious workaround is to store the traceback as text, but this operation is "expensive" especially if the traceback is only needed in rare cases. Another "obvious" workaround is to call frame.clear() from the parent function (i.e. have a dedicated wrapping layer). Regards Antoine. ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
On 2014-03-05, 11:37 AM, Victor Stinner wrote: [snip] I tried to write "views" of the traceback (and frames), but Exception.__traceback__ rejects types other than traceback and traceback instances cannot be created. It's possible to store the traceback somewhere else and set Exception.__traceback__ to None, but there is still the problem with chained exceptions. Can we allow instantiation of types.FrameType and types.TracebackType? If it's allowed, we can write a simple code, that will recreate tracebacks with cleaned-up frames without references to locals etc. Yury ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
On Thu, Feb 27, 2014 at 1:29 PM, Chris Angelico wrote:
> +Had this facility existed early in Python's history, there would have been
> +no need to create dict.get() and related methods;
FWIW, after experimenting and some consideration I've come to the
conclusion that this is incorrect. 'd[k] except KeyError: default' is still
much broader than dict.get(k):
Python 3.4.0rc1+ (default:aa2ae744e701+, Feb 24 2014, 01:22:15)
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> expensive_calculation = hash
>>> class C:
... _hash_cache = {}
... def __init__(self, value):
... self.value = value
... if value not in self._hash_cache:
... self._hash_cache[value] = expensive_calculation(value)
... def __hash__(self):
... return self._hash_cache[self.value]
... def __eq__(self, other):
... return self.value == other
...
>>> a, b, c, d = C(1), C(2), C(3), C(4)
>>> D = {a: 1, b: 2, c: 3, d: 4}
>>>
>>> a.value = 5
>>> print("except expr:", (D[a] except KeyError: 'default'))
except expr: default
>>> print("dict.get:", D.get(a, 'default'))
Traceback (most recent call last):
File "", line 1, in
File "", line 8, in __hash__
KeyError: 5
All in all I believe I will continue to prefer specific methods for
specific use-cases; I'm -0 on the idea of an except-expression, -0 on the
syntax with the mandatory parentheses around the whole thing (and so far -1
on any of the other suggested forms.) I can see the attractiveness, but
frankly, all the suggested changes to the stdlib fall in two categories:
easier to express (and narrower in its exception handling) with e.g.
dict.get for the trivial ones, or much better written out using temporary
variables for the complex ones. As soon as an except-expression has trouble
fitting on two lines it becomes an unsightly mess; it no longer becomes
obvious what it does from a glance. Not having except-expr may mean we keep
adding methods (with different names, and slightly different semantics) to
cover specific use-cases of specific types, but I can live with that.
--
Thomas Wouters
Hi! I'm an email virus! Think twice before sending your email to help me
spread!
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Cherry-pick between Python 3.4 RC2 and final?
On 6 Mar 2014 01:32, "Antoine Pitrou" wrote: > > Le 05/03/2014 03:46, Larry Hastings a écrit : > >> On 03/04/2014 03:59 PM, Barry Warsaw wrote: >>> >>> I too would like an rc3, especially to see if issue 19021 can be fixed, which >>> I suspect will hit a lot of people. >> >> >> I talked to the other guys on the 3.4 team, and we're all willing to do >> an rc3 this weekend. I'll add that to PEP 429. >> >> >> In other news, I'm thrilled to confirm something Antoine mentioned a >> week or two ago: it is literally impossible for garden-variety core devs >> to push new branches back into trunk. I tried to, early this morning >> (PST), with someone logged in to hg.python.org ready to clean up in case >> it actually worked. But happily hg hooks on the server reject new >> branches every time. > > > And I thought the hook would be overkill! I found it to be quite a handy failsafe in the early days of using Mercurial. Haven't triggered it since I set up my separate sandbox repo, though :) Cheers, Nick. > > Regards > > Antoine. > > > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
On 6 Mar 2014 02:43, "Antoine Pitrou" wrote: > > Le 05/03/2014 17:37, Victor Stinner a écrit : > >> >> Python 3.4 introduced frame.clear(), but frame.clear() raises an >> RuntimeError if the frame is still running. And it doesn't break all >> reference cycles. >> >> An obvious workaround is to store the traceback as text, but this >> operation is "expensive" especially if the traceback is only needed in >> rare cases. > > > Another "obvious" workaround is to call frame.clear() from the parent function (i.e. have a dedicated wrapping layer). Guido had a fix in mind - splitting traceback formatting into two pieces. The first would convert a traceback to a sequence of named tuples, the second would do the actual string formatting. There's an RFE for it on the tracker, but I don't have a link handy. Cheers, Nick. > > Regards > > Antoine. > > > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
I think it was http://bugs.python.org/issue17911 On Wed, Mar 5, 2014 at 1:54 PM, Nick Coghlan wrote: > > On 6 Mar 2014 02:43, "Antoine Pitrou" wrote: > > > > Le 05/03/2014 17:37, Victor Stinner a écrit : > > > >> > >> Python 3.4 introduced frame.clear(), but frame.clear() raises an > >> RuntimeError if the frame is still running. And it doesn't break all > >> reference cycles. > >> > >> An obvious workaround is to store the traceback as text, but this > >> operation is "expensive" especially if the traceback is only needed in > >> rare cases. > > > > > > Another "obvious" workaround is to call frame.clear() from the parent > function (i.e. have a dedicated wrapping layer). > > Guido had a fix in mind - splitting traceback formatting into two pieces. > The first would convert a traceback to a sequence of named tuples, the > second would do the actual string formatting. > > There's an RFE for it on the tracker, but I don't have a link handy. > > Cheers, > Nick. > > > > > Regards > > > > Antoine. > > > > > > > > ___ > > Python-Dev mailing list > > [email protected] > > https://mail.python.org/mailman/listinfo/python-dev > > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com > > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: > https://mail.python.org/mailman/options/python-dev/guido%40python.org > > -- --Guido van Rossum (python.org/~guido) ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
On Wed, Mar 5, 2014 at 2:54 PM, Nick Coghlan wrote: > Guido had a fix in mind - splitting traceback formatting into two pieces. > The first would convert a traceback to a sequence of named tuples, the > second would do the actual string formatting. +1 This is basically how I've handled pickling tracebacks in a project at work (using 2.7). You can already using extract_tb() and format_list() from the traceback module to get the effect. As to how to use this to avoid holding those references (without taking a performance hit), that will take some more thought. :) -eric ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
On 2014-03-05, 4:54 PM, Nick Coghlan wrote: On 6 Mar 2014 02:43, "Antoine Pitrou" wrote: Le 05/03/2014 17:37, Victor Stinner a écrit : Python 3.4 introduced frame.clear(), but frame.clear() raises an RuntimeError if the frame is still running. And it doesn't break all reference cycles. An obvious workaround is to store the traceback as text, but this operation is "expensive" especially if the traceback is only needed in rare cases. Another "obvious" workaround is to call frame.clear() from the parent function (i.e. have a dedicated wrapping layer). Guido had a fix in mind - splitting traceback formatting into two pieces. The first would convert a traceback to a sequence of named tuples, the second would do the actual string formatting. I don't like the idea of using tuples instead of tracebacks in 'exception.__traceback__'. Lots of introspection and logging tools except to find tracebacks in exceptions, and do custom formatting or submitting data to remote servers for further analysis (sometimes with values of local variables in frames). If asyncio starts stripping exception.__traceback__ and using namedtuples, it will make it harder to write/integrate such tools. Yury ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] Reference cycles in Exception.__traceback__
On 6 Mar 2014 08:32, "Yury Selivanov" wrote: > > > On 2014-03-05, 4:54 PM, Nick Coghlan wrote: >> >> On 6 Mar 2014 02:43, "Antoine Pitrou" wrote: >>> >>> Le 05/03/2014 17:37, Victor Stinner a écrit : >>> Python 3.4 introduced frame.clear(), but frame.clear() raises an RuntimeError if the frame is still running. And it doesn't break all reference cycles. An obvious workaround is to store the traceback as text, but this operation is "expensive" especially if the traceback is only needed in rare cases. >>> >>> >>> Another "obvious" workaround is to call frame.clear() from the parent >> >> function (i.e. have a dedicated wrapping layer). >> >> Guido had a fix in mind - splitting traceback formatting into two pieces. >> The first would convert a traceback to a sequence of named tuples, the >> second would do the actual string formatting. > > > I don't like the idea of using tuples instead of tracebacks > in 'exception.__traceback__'. Lots of introspection and logging > tools except to find tracebacks in exceptions, and do custom > formatting or submitting data to remote servers for further > analysis (sometimes with values of local variables in frames). > If asyncio starts stripping exception.__traceback__ and using > namedtuples, it will make it harder to write/integrate such > tools. __traceback__ wouldn't change - this is a variant on Victor's point that it is currently easy to store the already formatted traceback as a string, but that wastes time formatting a string you may never display, and is hard to manipulate programmatically. Extracting a traceback summary from __traceback__ instead can address both limitations. Cheers, Nick. > > Yury > > ___ > Python-Dev mailing list > [email protected] > https://mail.python.org/mailman/listinfo/python-dev > Unsubscribe: https://mail.python.org/mailman/options/python-dev/ncoghlan%40gmail.com ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
On Thu, Mar 6, 2014 at 7:57 AM, Thomas Wouters wrote: > On Thu, Feb 27, 2014 at 1:29 PM, Chris Angelico wrote: >> >> +Had this facility existed early in Python's history, there would have >> been >> +no need to create dict.get() and related methods; > > > FWIW, after experimenting and some consideration I've come to the conclusion > that this is incorrect. 'd[k] except KeyError: default' is still much > broader than dict.get(k): *Much* broader? You prove that it's broader, yes, but most types aren't defining __hash__ methods that can fail with KeyError. Can you show any real-world code that trips this? I'd say the broadened exception scope (or, putting it the other way, the narrowed exception scope of adding dict.get() after except-expressions had already existed) is insufficiently significant to justify adding an extra method to the dict. Since the method does exist, it will continue to be useful, but if except expressions did and dict.get() didn't, there'd have been very little justification for them. And certainly hasattr() wouldn't need to exist, since it exactly _does_ try to get the attribute and see if AttributeError is raised. ChrisA ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
On Thu, Mar 6, 2014 at 7:57 AM, Thomas Wouters wrote:
> All in all I believe I will continue to prefer specific methods for specific
> use-cases; I'm -0 on the idea of an except-expression, -0 on the syntax with
> the mandatory parentheses around the whole thing (and so far -1 on any of
> the other suggested forms.) I can see the attractiveness, but frankly, all
> the suggested changes to the stdlib fall in two categories: easier to
> express (and narrower in its exception handling) with e.g. dict.get for the
> trivial ones, or much better written out using temporary variables for the
> complex ones. As soon as an except-expression has trouble fitting on two
> lines it becomes an unsightly mess; it no longer becomes obvious what it
> does from a glance. Not having except-expr may mean we keep adding methods
> (with different names, and slightly different semantics) to cover specific
> use-cases of specific types, but I can live with that.
Most of those concerns could also be aimed at the if/else expression.
There are definitely places that do not merit its use, but that
doesn't mean the feature is a bad one. The PEP has a number of
examples that fit quite happily on a single line, and it's those that
I'm advocating. We have comprehensions, genexps, etc, etc, all (or at
least most) of which can be written out in some form of long-hand, and
it's usually better to use the short-hand - it's not just laziness,
it's expressiveness.
Speaking of the PEP, if someone could apply the latest changes, I
think it's pretty much ready for pronouncement. Thanks!
Content:
https://raw.github.com/Rosuav/ExceptExpr/master/pep-0463.txt
Diff from current peps repo:
diff -r 2cf89e9e50a3 pep-0463.txt
--- a/pep-0463.txt Tue Mar 04 18:47:44 2014 -0800
+++ b/pep-0463.txt Thu Mar 06 11:12:44 2014 +1100
@@ -250,7 +250,8 @@
alternatives listed above must (by the nature of functions) evaluate their
default values eagerly. The preferred form, using the colon, parallels
try/except by using "except exception_list:", and parallels lambda by having
-"keyword name_list: subexpression". Using the arrow introduces a token many
+"keyword name_list: subexpression"; it also can be read as mapping Exception
+to the default value, dict-style. Using the arrow introduces a token many
programmers will not be familiar with, and which currently has no similar
meaning, but is otherwise quite readable. The English word "pass" has a
vaguely similar meaning (consider the common usage "pass by value/reference"
@@ -271,6 +272,18 @@
Using the preferred order, subexpressions will always be evaluated from
left to right, no matter how the syntax is nested.
+Keeping the existing notation, but shifting the mandatory parentheses, we
+have the following suggestion::
+
+value = expr except (Exception: default)
+value = expr except(Exception: default)
+
+This is reminiscent of a function call, or a dict initializer. The colon
+cannot be confused with introducing a suite, but on the other hand, the new
+syntax guarantees lazy evaluation, which a dict does not. The potential
+to reduce confusion is considered unjustified by the corresponding potential
+to increase it.
+
Example usage
=
@@ -854,6 +867,32 @@
expression to achieve this.
+Common objections
+=
+
+Colons always introduce suites
+--
+
+While it is true that many of Python's syntactic elements use the colon to
+introduce a statement suite (if, while, with, for, etcetera), this is not
+by any means the sole use of the colon. Currently, Python syntax includes
+four cases where a colon introduces a subexpression:
+
+* dict display - { ... key:value ... }
+* slice notation - [start:stop:step]
+* function definition - parameter : annotation
+* lambda - arg list: return value
+
+This proposal simply adds a fifth:
+
+* except-expression - exception list: result
+
+Style guides and PEP 8 should recommend not having the colon at the end of
+a wrapped line, which could potentially look like the introduction of a
+suite, but instead advocate wrapping before the exception list, keeping the
+colon clearly between two expressions.
+
+
Copyright
=
ChrisA
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
On Wed, Mar 5, 2014 at 4:28 PM, Chris Angelico wrote:
> On Thu, Mar 6, 2014 at 7:57 AM, Thomas Wouters wrote:
> > All in all I believe I will continue to prefer specific methods for
> specific
> > use-cases; I'm -0 on the idea of an except-expression, -0 on the syntax
> with
> > the mandatory parentheses around the whole thing (and so far -1 on any of
> > the other suggested forms.) I can see the attractiveness, but frankly,
> all
> > the suggested changes to the stdlib fall in two categories: easier to
> > express (and narrower in its exception handling) with e.g. dict.get for
> the
> > trivial ones, or much better written out using temporary variables for
> the
> > complex ones. As soon as an except-expression has trouble fitting on two
> > lines it becomes an unsightly mess; it no longer becomes obvious what it
> > does from a glance. Not having except-expr may mean we keep adding
> methods
> > (with different names, and slightly different semantics) to cover
> specific
> > use-cases of specific types, but I can live with that.
>
> Most of those concerns could also be aimed at the if/else expression.
>
And I did :) But the if-else expression had a single thing going for it,
the thing that landed the actual feature: it prevents people from using
buggy alternatives in the quest for short code, the and-or trick. You may
remember that Guido initially rejected the if-else expression, until he
realized people were going to use something like it whether he liked it or
not. The except-expression has a different issue: people catching
exceptions too broadly. I don't believe that's as big a problem, nor is it
as subtly wrong. And the except-expression doesn't solve _all_ such issues,
just a very small subset. It's just another thing to learn when you're new,
and just another thing to consider when reviewing code.
> There are definitely places that do not merit its use, but that
> doesn't mean the feature is a bad one. The PEP has a number of
> examples that fit quite happily on a single line, and it's those that
> I'm advocating. We have comprehensions, genexps, etc, etc, all (or at
> least most) of which can be written out in some form of long-hand, and
> it's usually better to use the short-hand - it's not just laziness,
> it's expressiveness.
>
It's not a question of it being expressive, it's a question of it being
worth separate syntax. I don't think it's worth syntax.
>
> Speaking of the PEP, if someone could apply the latest changes, I
> think it's pretty much ready for pronouncement. Thanks!
>
PEP update pushed (changeset 59653081cdf6.)
>
> Content:
> https://raw.github.com/Rosuav/ExceptExpr/master/pep-0463.txt
>
> Diff from current peps repo:
>
> diff -r 2cf89e9e50a3 pep-0463.txt
> --- a/pep-0463.txt Tue Mar 04 18:47:44 2014 -0800
> +++ b/pep-0463.txt Thu Mar 06 11:12:44 2014 +1100
> @@ -250,7 +250,8 @@
> alternatives listed above must (by the nature of functions) evaluate their
> default values eagerly. The preferred form, using the colon, parallels
> try/except by using "except exception_list:", and parallels lambda by
> having
> -"keyword name_list: subexpression". Using the arrow introduces a token
> many
> +"keyword name_list: subexpression"; it also can be read as mapping
> Exception
> +to the default value, dict-style. Using the arrow introduces a token many
> programmers will not be familiar with, and which currently has no similar
> meaning, but is otherwise quite readable. The English word "pass" has a
> vaguely similar meaning (consider the common usage "pass by
> value/reference"
> @@ -271,6 +272,18 @@
> Using the preferred order, subexpressions will always be evaluated from
> left to right, no matter how the syntax is nested.
>
> +Keeping the existing notation, but shifting the mandatory parentheses, we
> +have the following suggestion::
> +
> +value = expr except (Exception: default)
> +value = expr except(Exception: default)
> +
> +This is reminiscent of a function call, or a dict initializer. The colon
> +cannot be confused with introducing a suite, but on the other hand, the
> new
> +syntax guarantees lazy evaluation, which a dict does not. The potential
> +to reduce confusion is considered unjustified by the corresponding
> potential
> +to increase it.
> +
>
> Example usage
> =
> @@ -854,6 +867,32 @@
> expression to achieve this.
>
>
> +Common objections
> +=
> +
> +Colons always introduce suites
> +--
> +
> +While it is true that many of Python's syntactic elements use the colon to
> +introduce a statement suite (if, while, with, for, etcetera), this is not
> +by any means the sole use of the colon. Currently, Python syntax includes
> +four cases where a colon introduces a subexpression:
> +
> +* dict display - { ... key:value ... }
> +* slice notation - [start:stop:step]
> +* function definition - parameter : annotation
> +* lambda - arg list: return value
> +
> +This proposal simply adds a fif
Re: [Python-Dev] PEP 463: Exception-catching expressions
On Thu, Mar 6, 2014 at 12:03 PM, Thomas Wouters wrote: > PEP update pushed (changeset 59653081cdf6.) > Thanks for that! ChrisA ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
On Wed, Mar 05, 2014 at 12:57:03PM -0800, Thomas Wouters wrote:
> On Thu, Feb 27, 2014 at 1:29 PM, Chris Angelico wrote:
>
> > +Had this facility existed early in Python's history, there would have been
> > +no need to create dict.get() and related methods;
>
>
> FWIW, after experimenting and some consideration I've come to the
> conclusion that this is incorrect. 'd[k] except KeyError: default' is still
> much broader than dict.get(k):
I don't think your example proves what you think it does. I think it
demonstrates a bug in the dict.get method. The documentation for get
states clearly that get will never raise KeyError:
Return the value for key if key is in the dictionary, else default.
If default is not given, it defaults to None, so that this method
never raises a KeyError.
http://docs.python.org/3/library/stdtypes.html#dict.get
but your example demonstrates that in fact it can raise KeyError
(albeit under some rather unusual circumstances):
> Python 3.4.0rc1+ (default:aa2ae744e701+, Feb 24 2014, 01:22:15)
> [GCC 4.6.3] on linux
> Type "help", "copyright", "credits" or "license" for more information.
> >>> expensive_calculation = hash
> >>> class C:
> ... _hash_cache = {}
> ... def __init__(self, value):
> ... self.value = value
> ... if value not in self._hash_cache:
> ... self._hash_cache[value] = expensive_calculation(value)
> ... def __hash__(self):
> ... return self._hash_cache[self.value]
> ... def __eq__(self, other):
> ... return self.value == other
> ...
> >>> a, b, c, d = C(1), C(2), C(3), C(4)
> >>> D = {a: 1, b: 2, c: 3, d: 4}
> >>> a.value = 5
> >>> print("except expr:", (D[a] except KeyError: 'default'))
> except expr: default
> >>> print("dict.get:", D.get(a, 'default'))
> Traceback (most recent call last):
> File "", line 1, in
> File "", line 8, in __hash__
> KeyError: 5
According to the documentation, this behaviour is wrong.
Now, you might argue that the documentation is wrong. I'm sympathetic to
that argument, but *as documented now*, dict.get is documented as being
logically equivalent to:
try:
return d[key]
except KeyError:
return default
The fact that it actually isn't is an artifact of the specific
implementation used. If it were a deliberate design choice, that design
is not reflected in the documentation.
Whether the current behaviour is wrong, or the documentation is wrong,
is irrelevant to the question of whether or not the developers back in
nineteen-ninety-whatever would have choosen to add dict.get had there
been syntax for catching the KeyError in an expression. Perhaps they
would have argued:
"Sure, you can catch the KeyError yourself, but 'get' is a fundamental
operation for mappings, and I think that dict should implement a 'get'
method just to be complete."
Or perhaps not. Some developers prefer minimalist APIs, some developers
prefer more exhaustive APIs.
Regardless of what might have happened back in 199x when dict.get was
first discussed, I think we can agree that an except expression will
lower the pressure on Python to add *more* "get-like" methods, or add
default arguments, in the future.
--
Steven
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
On 3/5/2014 8:15 PM, Steven D'Aprano wrote:
On Wed, Mar 05, 2014 at 12:57:03PM -0800, Thomas Wouters wrote:
On Thu, Feb 27, 2014 at 1:29 PM, Chris Angelico wrote:
+Had this facility existed early in Python's history, there would have been
+no need to create dict.get() and related methods;
FWIW, after experimenting and some consideration I've come to the
conclusion that this is incorrect. 'd[k] except KeyError: default' is still
much broader than dict.get(k):
I don't think your example proves what you think it does. I think it
demonstrates a bug in the dict.get method. The documentation for get
states clearly that get will never raise KeyError:
Return the value for key if key is in the dictionary, else default.
If default is not given, it defaults to None, so that this method
never raises a KeyError.
http://docs.python.org/3/library/stdtypes.html#dict.get
but your example demonstrates that in fact it can raise KeyError
(albeit under some rather unusual circumstances):
Python 3.4.0rc1+ (default:aa2ae744e701+, Feb 24 2014, 01:22:15)
[GCC 4.6.3] on linux
Type "help", "copyright", "credits" or "license" for more information.
expensive_calculation = hash
class C:
... _hash_cache = {}
... def __init__(self, value):
... self.value = value
... if value not in self._hash_cache:
... self._hash_cache[value] = expensive_calculation(value)
... def __hash__(self):
... return self._hash_cache[self.value]
This is a buggy special method. According to the docs for hash and
__hash__ and the general convention on exceptions, a __hash__ method
should return an int or raise TypeError.
... def __eq__(self, other):
... return self.value == other
...
a, b, c, d = C(1), C(2), C(3), C(4)
D = {a: 1, b: 2, c: 3, d: 4}
a.value = 5
This breaks the implied C invariant and makes the object 'a' incoherent
and buggy
print("dict.get:", D.get(a, 'default'))
Traceback (most recent call last):
File "", line 1, in
File "", line 8, in __hash__
KeyError: 5
According to the documentation, this behaviour is wrong.
One could argue that an error raised in a special method is not raised
*by* a function that uses the special method. The docs constantly assume
that special methods are coded correctly.
'''bool([x])
Convert a value to a Boolean, using the standard truth testing
procedure. If x is false or omitted, this returns False; otherwise it
returns True.'''
... unless x.__bool__ raises or returns something other than True/False
-- in which case bool itself raises.
TypeError: __bool__ should return bool, returned int
Now, you might argue that the documentation is wrong. I'm sympathetic to
that argument, but *as documented now*, dict.get is documented as being
logically equivalent to:
try:
return d[key]
except KeyError:
return default
It appears to be actually equivalent to
key_hash = hash(key)
try:
return d._hashlookup(key_has)
except KeyError:
return default
The fact that it actually isn't is an artifact of the specific
implementation used. If it were a deliberate design choice,
Given that the choice is that bugs in special methods should not pass
silently, I would presume that it is intentional.
> that design is not reflected in the documentation.
The docs generally describe behavior in the absence of coding errors.
--
Terry Jan Reedy
___
Python-Dev mailing list
[email protected]
https://mail.python.org/mailman/listinfo/python-dev
Unsubscribe:
https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
Re: [Python-Dev] PEP 463: Exception-catching expressions
Steven D'Aprano wrote: Return the value for key if key is in the dictionary, else default. If default is not given, it defaults to None, so that this method never raises a KeyError. I think that's supposed to mean that it won't raise KeyError as a result of the key not being in the dictionary. The actual behaviour is correct, IMO, because it avoids masking bugs, so this could probably be worded better. -- Greg ___ Python-Dev mailing list [email protected] https://mail.python.org/mailman/listinfo/python-dev Unsubscribe: https://mail.python.org/mailman/options/python-dev/archive%40mail-archive.com
