
Hi All, I see a lot of Python like this: try: from cDecimal import Decimal except ImportError: from decimal import Decimal ...and nest deeper if you're talking about ElementTree. How about some syntactical sugar to make this less obnoxious: from cDecimal or decimal import Decimal from x.y.z import X as X or a.b.z import Y as X or what do people think? Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk

We used to have a lot more of these. The agreed-upon solution is to have this hidden inside (for instance) the decimal module. E.g. if you import heapq, you get heapq.py which attempts to import _heapq but gives you the Python implementation if that fails. --Guido On Thu, Mar 8, 2012 at 9:55 AM, Chris Withers <chris@simplistix.co.uk> wrote:
-- --Guido van Rossum (python.org/~guido)

On 08/03/2012 10:03, Guido van Rossum wrote:
Okay, but I'm thinking about the situation where there are genuinely several possible import sources, with no clear order of fallbacks and where not all of the packages know about each other. The ElementTree example is currently a good one... This seems particularly relevant with things like argparse, unittest2, distutils2, packaging... I suspect it'll also be relevant where code uses libraries where the author has chosen to have differently named packages for Python 2 and 3. It would also be extremely relevant if any of the misguided "provisional packages in stdlib" PEPs make it through... Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk

On Thu, Mar 8, 2012 at 12:55 PM, Chris Withers <chris@simplistix.co.uk> wrote:
It's worthy of note that the `import cFoo as foo` pattern has given way to implementing foo to try to defer to cFoo on import. The other situation--a dropin replacement potentially-third-party module--like the various etree implementations is somewhat less that compelling since a) these are rare and a few lines to do it doesn't hurt and b) they're usually lies--a lot of use-lxml-but-fallback-on-xml.etree import programs out there would fail if lxml wasn't present anyhow. If something like this is introduced, we should consider an "import foo or None" kind of case (maybe not written exactly like that) to replace the conditional-dependency pattern of try: import foo except ImportError: foo = None Mike

On Mar 8, 2012, at 9:55 AM, Chris Withers wrote:
It's been proposed before, you might want to read this old thread: http://mail.python.org/pipermail/python-dev/2008-January/075788.html -- Philip Jenvey

On 08/03/2012 11:06, Philip Jenvey wrote:
It's been proposed before, you might want to read this old thread:
http://mail.python.org/pipermail/python-dev/2008-January/075788.html
Heh, interesting that the same thing came up without me ever reading that thread. I think it's got legs, why do other people dislike the idea? Chris PS For clarification, only thinking about this for 3.x, not 2.x... -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk

Chris Withers wrote:
Because it adds more complexity to the language and parser for minimal benefit. In my experience, the construct try: import ham except ImportError: import spam as ham is not common enough or difficult enough to need special syntax for it. Not every special case needs special syntax, and if you don't like that it is a four-liner you can cut it down to a two-liner: try: import ham except ImportError: import spam as ham Every new piece of syntax adds complexity to the language, increasing the overall burden of writing a piece of code. The try...except idiom is a general idiom that applies *everywhere* -- you try something, and if that fails, you do something else, regardless of the nature of the things you are trying. You're not limited to only catching ImportError and retrying the import, so it is easy to extend the idiom to variations such as: try: from spam import x except ImportError: # Must be an old version. Log it and fall back. log('using old version of spam') from spam import y and here's a real piece of code from one of my libraries: try: from math import isfinite except ImportError: # Python 2.6 or older. try: from math import isnan, isinf except ImportError: # Python 2.5. Quick and dirty substitutes. def isnan(x): return x != x def isinf(x): return x - x != 0 def isfinite(x): return not (isnan(x) or isinf(x)) "import x or y" doesn't have anywhere near the flexibility or power of a generalised try...except block because it is limited to a tiny subset of the actions you might want to take after catching ImportError. Most special syntax for special cases doesn't add any new idioms for solving general problems, they just solve a single, narrowly defined, problem. Your suggestion is one of them: it can be used to solve two specific import problems: import ham or spam as ham from ham or spam import x and I suppose it could even be extended, at the cost of even more complexity, to solve a third: from ham or spam import x or y as z but even so, it is still too narrowly focused on single idiom: try: import some thing except ImportError: import some other thing as a fallback with no ability to do anything else. That makes it fall foul of the "Special cases" line from the Zen. If the idiom being replaced was difficult enough, then maybe your suggestion would fly, but I don't believe it does. It's a pretty trivial transformation. Compare your suggestion with the "yield from" PEP, and you will see that while yield from initially seems trivial, there are in fact a whole lot of complicated special cases with coroutines that make it compelling. I don't believe that yours has anything like that. Consequently, although I think your syntax is kinda cute, I don't think it adds enough benefit to be worth the change. My vote is +0. -- Steven

On Thu, Mar 08, 2012 at 09:55:35AM -0800, Chris Withers wrote:
I seem to recall something like this proposed some time ago. I believe one argument against it was that or would have to change its meaning based on context. Changes to the language need to make expressing a particular idiom possible, simpler, and more readable. To me the proposed expression is less clear, and the current method is very clear and works quite well. -1

We used to have a lot more of these. The agreed-upon solution is to have this hidden inside (for instance) the decimal module. E.g. if you import heapq, you get heapq.py which attempts to import _heapq but gives you the Python implementation if that fails. --Guido On Thu, Mar 8, 2012 at 9:55 AM, Chris Withers <chris@simplistix.co.uk> wrote:
-- --Guido van Rossum (python.org/~guido)

On 08/03/2012 10:03, Guido van Rossum wrote:
Okay, but I'm thinking about the situation where there are genuinely several possible import sources, with no clear order of fallbacks and where not all of the packages know about each other. The ElementTree example is currently a good one... This seems particularly relevant with things like argparse, unittest2, distutils2, packaging... I suspect it'll also be relevant where code uses libraries where the author has chosen to have differently named packages for Python 2 and 3. It would also be extremely relevant if any of the misguided "provisional packages in stdlib" PEPs make it through... Chris -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk

On Thu, Mar 8, 2012 at 12:55 PM, Chris Withers <chris@simplistix.co.uk> wrote:
It's worthy of note that the `import cFoo as foo` pattern has given way to implementing foo to try to defer to cFoo on import. The other situation--a dropin replacement potentially-third-party module--like the various etree implementations is somewhat less that compelling since a) these are rare and a few lines to do it doesn't hurt and b) they're usually lies--a lot of use-lxml-but-fallback-on-xml.etree import programs out there would fail if lxml wasn't present anyhow. If something like this is introduced, we should consider an "import foo or None" kind of case (maybe not written exactly like that) to replace the conditional-dependency pattern of try: import foo except ImportError: foo = None Mike

On Mar 8, 2012, at 9:55 AM, Chris Withers wrote:
It's been proposed before, you might want to read this old thread: http://mail.python.org/pipermail/python-dev/2008-January/075788.html -- Philip Jenvey

On 08/03/2012 11:06, Philip Jenvey wrote:
It's been proposed before, you might want to read this old thread:
http://mail.python.org/pipermail/python-dev/2008-January/075788.html
Heh, interesting that the same thing came up without me ever reading that thread. I think it's got legs, why do other people dislike the idea? Chris PS For clarification, only thinking about this for 3.x, not 2.x... -- Simplistix - Content Management, Batch Processing & Python Consulting - http://www.simplistix.co.uk

Chris Withers wrote:
Because it adds more complexity to the language and parser for minimal benefit. In my experience, the construct try: import ham except ImportError: import spam as ham is not common enough or difficult enough to need special syntax for it. Not every special case needs special syntax, and if you don't like that it is a four-liner you can cut it down to a two-liner: try: import ham except ImportError: import spam as ham Every new piece of syntax adds complexity to the language, increasing the overall burden of writing a piece of code. The try...except idiom is a general idiom that applies *everywhere* -- you try something, and if that fails, you do something else, regardless of the nature of the things you are trying. You're not limited to only catching ImportError and retrying the import, so it is easy to extend the idiom to variations such as: try: from spam import x except ImportError: # Must be an old version. Log it and fall back. log('using old version of spam') from spam import y and here's a real piece of code from one of my libraries: try: from math import isfinite except ImportError: # Python 2.6 or older. try: from math import isnan, isinf except ImportError: # Python 2.5. Quick and dirty substitutes. def isnan(x): return x != x def isinf(x): return x - x != 0 def isfinite(x): return not (isnan(x) or isinf(x)) "import x or y" doesn't have anywhere near the flexibility or power of a generalised try...except block because it is limited to a tiny subset of the actions you might want to take after catching ImportError. Most special syntax for special cases doesn't add any new idioms for solving general problems, they just solve a single, narrowly defined, problem. Your suggestion is one of them: it can be used to solve two specific import problems: import ham or spam as ham from ham or spam import x and I suppose it could even be extended, at the cost of even more complexity, to solve a third: from ham or spam import x or y as z but even so, it is still too narrowly focused on single idiom: try: import some thing except ImportError: import some other thing as a fallback with no ability to do anything else. That makes it fall foul of the "Special cases" line from the Zen. If the idiom being replaced was difficult enough, then maybe your suggestion would fly, but I don't believe it does. It's a pretty trivial transformation. Compare your suggestion with the "yield from" PEP, and you will see that while yield from initially seems trivial, there are in fact a whole lot of complicated special cases with coroutines that make it compelling. I don't believe that yours has anything like that. Consequently, although I think your syntax is kinda cute, I don't think it adds enough benefit to be worth the change. My vote is +0. -- Steven

On Thu, Mar 08, 2012 at 09:55:35AM -0800, Chris Withers wrote:
I seem to recall something like this proposed some time ago. I believe one argument against it was that or would have to change its meaning based on context. Changes to the language need to make expressing a particular idiom possible, simpler, and more readable. To me the proposed expression is less clear, and the current method is very clear and works quite well. -1
participants (8)
-
Chris Withers
-
Guido van Rossum
-
Matt Joiner
-
Mike Graham
-
Philip Jenvey
-
Steven D'Aprano
-
Westley Martínez
-
Éric Araujo