Re: [Python-ideas] Improving Catching Exceptions

2017-06-22 Thread MRAB

On 2017-06-23 00:29, Cameron Simpson wrote:

On 23Jun2017 06:55, Steven D'Aprano  wrote:

On Thu, Jun 22, 2017 at 10:30:57PM +0200, Sven R. Kunze wrote:

We usually teach our newbies to catch exceptions as narrowly as
possible, i.e. MyModel.DoesNotExist instead of a plain Exception. This
works out quite well for now but the number of examples continue to grow
where it's not enough.


(1) Under what circumstances is it not enough?


I believe that he means that it isn't precise enough. In particular, "nested
exceptions" to me, from his use cases, means exceptions thrown from within
functions called at the top level. I want this control too sometimes.

Consider:

 try:
 foo(bah[5])
 except IndexError as e:
 ... infer that there is no bah[5] ...

Of course, it is possible that bah[5] existed and that foo() raised an
IndexError of its own. One might intend some sane handling of a missing bah[5]
but instead silently conceal the IndexError from foo() by mishandling it as a
missing bah[5].

Naturally one can rearrange this code to call foo() outside that try/except,
but that degree of control often leads to quite fiddly looking code with the
core flow obscured by many tiny try/excepts.

One can easily want, instead, some kind of "shallow except", which would catch
exceptions only if they were directly raised from the surface code; such a
construct would catch the IndexError from a missing bah[5] in the example
above, but _not_ catch an IndexError raised from deeper code such within the
foo() function.

Something equivalent to:

 try:
 foo(bah[5])
 except IndexError as e:
 if e.__traceback__ not directly from the try..except lines:
 raise
 ... infer that there is no bah[5] ...

There doesn't seem to be a concise way to write that. It might not even be
feasible at all, as one doesn't have a way to identify the line(s) within the
try/except in a form that one can recognise in a traceback.


[snip]

Increment a counter on every function call and record it on the 
exception, perhaps?


If the exception's call count == the current call count, it was raised 
in this function.

___
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] Improving Catching Exceptions

2017-06-22 Thread Nick Coghlan
On 23 June 2017 at 09:29, Cameron Simpson  wrote:
> This is so common that I actually keep around a special hack:
>
>def prop(func):
>  ''' The builtin @property decorator lets internal AttributeErrors
> escape.
>  While that can support properties that appear to exist
> conditionally,
>  in practice this is almost never what I want, and it masks deeper
> errors.
>  Hence this wrapper for @property that transmutes internal
> AttributeErrors
>  into RuntimeErrors.
>  '''
>  def wrapper(*a, **kw):
>try:
>  return func(*a, **kw)
>except AttributeError as e:
>  e2 = RuntimeError("inner function %s raised %s" % (func, e))
>  if sys.version_info[0] >= 3:
>try:
>  eval('raise e2 from e', globals(), locals())
>except:
>  # FIXME: why does this raise a SyntaxError?
>  raise e
>  else:
>raise e2
>  return property(wrapper)

Slight tangent, but I do sometimes wonder if adding a decorator
factory like the following to functools might be useful:

def raise_when_returned(return_exc):
def decorator(f):
@wraps(f)
def wrapper(*args, **kwds):
try:
result = f(*args, **kwds)
except selective_exc as unexpected_exc:
msg = "inner function {} raised {}".format(f,
unexpected_exc)
raise RuntimeError(msg) from unexpected_exc
if isinstance(result, return_exc):
raise result
return result

It's essentially a generalisation of PEP 479 to arbitrary exception
types, since it lets you mark a particular exception type as being
communicated back to the wrapper via the return channel rather than as
a regular exception:

def with_traceback(exc):
try:
raise exc
except BaseException as caught_exc:
return caught_exc

@property
@raise_when_returned(AttributeError)
def target(self):
if len(self.targets) == 1:
return self.targets[0]
return with_traceback(AttributeError('only exists when this
has exactly one target'))

The part I don't like about that approach is the fact that you need to
mess about with the exception internals to get a halfway decent
traceback on the AttributeError.

The main alternative would be to add a "convert_exception" context
manager in contextlib, so you could write the example property as:

@property
def target(self):
with convert_exception(AttributeError):
if len(self.targets) == 1:
return self.targets[0]
raise AttributeError('only exists when this has exactly one target')

Where "convert_exception" would be something like:

def convert_exception(exc_type):
"""Prevents the given exception type from escaping a region of
code by converting it to RuntimeError"""
if not issubclass(exc_type, Exception):
raise TypeError("Only Exception subclasses can be flagged
as unexpected")
try:
 yield
except exc_type as unexpected_exc:
new_exc = RuntimeError("Unexpected exception")
raise new_exc from unexpected_exc

The API for this could potentially be made more flexible to allow easy
substition of lookup errors with attribute errors and vice-versa (e.g.
via additional keyword-only parameters)

To bring the tangent back closer to Sven's original point, there are
probably also some parts of the import system (such as executing the
body of a found module) where the case can be made that we should be
converting ImportError to RuntimeError, rather than letting the
ImportError escape (with essentially the same rationale as PEP 479).


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] [Python-Dev] Language proposal: variable assignment in functional context

2017-06-22 Thread Michał Żukowski
I've implemented a PoC of `where` expression some time ago.

https://github.com/thektulu/cpython/commit/9e669d63d292a639eb6ba2ecea3ed2c0c23f2636

just compile and have fun.



2017-06-17 2:27 GMT+02:00 Steven D'Aprano :

> Welcome Robert. My response below.
>
> Follow-ups to Python-Ideas, thanks. You'll need to subscribe to see any
> further discussion.
>
>
> On Fri, Jun 16, 2017 at 11:32:19AM +, Robert Vanden Eynde wrote:
>
> > In a nutshell, I would like to be able to write:
> > y = (b+2 for b = a + 1)
>
> I think this is somewhat similar to a suggestion of Nick Coghlan's. One
> possible syntax as a statement might be:
>
> y = b + 2 given:
> b = a + 1
>
>
> https://www.python.org/dev/peps/pep-3150/
>
> In mathematics, I might write:
>
> y = b + 2 where b = a + 1
>
> although of course I wouldn't do so for anything so simple. Here's a
> better example, the quadratic formula:
>
>   -b ± √Δ
> x =  ─
>  2a
>
> where Δ = b² - 4ac
>
> although even there I'd usually write Δ in place.
>
>
> > Python already have the "functional if", lambdas, list comprehension,
> > but not simple assignment functional style.
>
> I think you mean "if *expression*" rather than "functional if". The term
> "functional" in programming usually refers to a particular paradigm:
>
> https://en.wikipedia.org/wiki/Functional_programming
>
>
> --
> 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/
>
___
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] Language proposal: variable assignment in functional context

2017-06-22 Thread Sven R. Kunze

On 17.06.2017 17:51, Nick Coghlan wrote:

You've pretty much hit on why that PEP's been deferred for ~5 years or
so - I'm waiting to see use cases where we can genuinely say "this
would be so much easier and more readable if we had a given
construct!" :)


This PEP accepted, we would have 3 ways of doing 1 thing (imperative 
programming):

1) flat inline execution namespace
2) structured inline execution namespace
3) named code used in 1) oder 2)


Is that simple enough for Python?


Just one side thought: internally, we have a guideline which says: 
"please reduce the number of indentations" -> less else, less if, less 
while, etc. The goal is more compact, less complex code.

Our code is already complex enough due to its sher amount.

"given" would fall under the same rule here: keep it flat and simple; 
otherwise, give it a name.



Then asyncio (and variants like
curio and trio) came along and asked the question: what if we built on
the concepts explored by Twisted's inlineDeferred's, and instead made
it easier to write asynchronous code without explicitly constructing
callback chains?


Does it relate? I can imagine having both "given" and "async given".


However, in my own work,
having to come up with a sensible name for the encapsulated operation
generally comes with a readability benefit as well, so...


Well said. In the end (when it comes to professional code), you need to 
test those little things anyway. So addressing them is necessary.
In interactive code, well, honestly, I don't care so much about spoiling 
namespaces and using variables names such as 'a' or 'bb' is quite common 
to try things out.


@Steven
Good post, thanks for explaining it. :)

Might be too much for the simple Python I know and value but hey if it 
helps. Maybe it will enable a lot of cool stuff and we cannot imagine 
right now just because David Beazley cannot try it out in practice.


Regards,
Sven
___
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] socket module: plain stuples vs named tuples - Thank you

2017-06-22 Thread Thomas Güttler
thank you! I am happy that Guido is open for  a pull request ... There were +1 votes, too (and some concern about python 
startup time).



I stopped coding in spare time, since my children are more important at the moment .. if some wants to try it ... go 
ahead and implement named tuples for the socket standard library - would be great.


Just for the records, I came here because of this feature request:

   https://github.com/giampaolo/psutil/issues/928

Regards,
  Thomas Güttler

PS: For some strange reasons I received only some mails of this thread. But I 
could
find the whole thread in the archive.

Am 20.06.2017 um 04:05 schrieb INADA Naoki:

Namedtuple in Python make startup time slow.
So I'm very conservative to convert tuple to namedtuple in Python.
INADA Naoki  


On Tue, Jun 20, 2017 at 7:27 AM, Victor Stinner
 wrote:

Oh, about the cost of writing C code, we started to enhance the socket
module in socket.py but keep the C code unchanged. I am thinking to the
support of enums. Some C functions are wrapped in Python.

Victor

Le 19 juin 2017 11:59 PM, "Guido van Rossum"  a écrit :


There are examples in timemodule.c which went through a similar conversion
from plain tuples to (sort-of) named tuples. I agree that upgrading the
tuples returned by the socket module to named tuples would be nice, but it's
a low priority project. Maybe someone interested can create a PR? (First
open an issue stating that you're interested; point to this email from me to
prevent that some other core dev just closes it again.)

On Mon, Jun 19, 2017 at 2:24 PM, Victor Stinner 
wrote:


Hi,

2017-06-13 22:13 GMT+02:00 Thomas Güttler :

AFAIK the socket module returns plain tuples in Python3:

   https://docs.python.org/3/library/socket.html

Why not use named tuples?


For technical reasons: the socket module is mostly implemented in the
C language, and define a "named tuple" in C requires to implement a
"sequence" time which requires much more code than creating a tuple.

In short, create a tuple is as simple as Py_BuildValue("OO", item1,
item2).

Creating a "sequence" type requires something like 50 lines of code,
maybe more, I don't know exactly.

Victor
___
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/


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



--
Thomas Guettler http://www.thomas-guettler.de/
___
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/