Re: [Python-Dev] Syntax suggestion for imports
[GvR]
I wonder if your perceived need for this isn't skewed by your working within the core?
The need was perceived by a colleague who does not work on the core. My own skew was in the opposite direction -- I've seen the pattern so often that I'm oblivious to it. Before posting, I ran some scans of our code base at work and found plenty of examples (mostly third-party cmodules vs python equivalents and a few that searched for similar functionality in different packages). It might be helpful if others were to also search their own code bases and post their findings: find . -name "*py" | xargs grep -C2 ImportError *py Also, Google's codesearch gives some examples (and a lot of cases that really do need the try/except form): http://www.google.com/codesearch?q=+lang:python+%22except+ImportError%22 I was surprised to see many examples in the form of: try: import xyz except ImportError: xyz = None I was also surprised to find plenty of code that is likely to be buggy because the two alternative loaded different names: try: from Products.OpenPT.OpenPTFile import OpenPTFile as ptFile except ImportError: from Products.PageTemplates.PageTemplateFile import PageTemplateFile I was not surprised to see searches for similar functionality across different packages like kjbuckets vs kjbuckets0 , Zope vs Zope2, or HTMLParser vs SGMLParser, or attempts to load any of several packages compliant with the DBAPI. Surely, Py3.0's automatic vectoring to C equivalent modules will help with the cases like cStringIO, cPickle. I don't think it will help with the general case of searching for a best available package (like gdbm vs dbm vs dumbdbm or threading vs dummythreading) or a best available implementation of a single function (like twisted.protocols._c_urlarg.unquote vs urllib.unquote or one of the various implementations of date utilities or encryption functions). Am curious to see what everyone else finds in their own code searches. [John Barham]
This I find more problematic as "emptymodule" seems too magical. . . . try: readline = None import readline except ImportError: pass
Perhaps "import readline or None" would have been a better way to capture that pattern as well as the "except pass" pattern. Raymond
-On [20080103 04:29], Raymond Hettinger (python@rcn.com) wrote:
Am curious to see what everyone else finds in their own code searches.
On the Trac project using your grep gives me 203 lines, if we take ~2 lines for and after in consideration, it still means 203/5 ~= 40 occurences. -- Jeroen Ruigrok van der Werven <asmodai(-at-)in-nomine.org> / asmodai イェルーン ラウフロック ヴァン デル ウェルヴェン http://www.in-nomine.org/ | http://www.rangaku.org/ In every stone sleeps a crystal...
[Jeroen Ruigrok van der Werven]
On the Trac project using your grep gives me 203 lines, if we take ~2 lines for and after in consideration, it still means 203/5 ~= 40 occurences.
Thanks. I'm more curious about the content of those lines. Does the proposed syntax help, does the need go away in Py3.0, what is the typical pattern? Raymond
-On [20080103 08:53], Raymond Hettinger (python@rcn.com) wrote:
Thanks. I'm more curious about the content of those lines. Does the proposed syntax help, does the need go away in Py3.0, what is the typical pattern?
These are some of the examples, I've tried to reduce them to specific use patterns: To determine if some feature is available: try: pygments = __import__('pygments', {}, {}, []) have_pygments = True except ImportError: have_pygments = False try: from docutils import nodes from docutils.core import publish_parts from docutils.parsers import rst from docutils import __version__ except ImportError: raise TracError(_('Docutils not found')) if StrictVersion(__version__) < StrictVersion('0.3.9'): raise TracError(_('Docutils version >= %(version)s required, ' '%(found)s found', version='0.3.9', found=__version__)) To specify which specific version we have of a given module: try: import pysqlite2.dbapi2 as sqlite have_pysqlite = 2 except ImportError: try: import sqlite3 as sqlite have_pysqlite = 2 except ImportError: try: import sqlite have_pysqlite = 1 except ImportError: have_pysqlite = 0 This gets repeated a lot in order to see if we have threading: try: import threading except ImportError: import dummy_threading as threading threading._get_ident = lambda: 0 Functions we do use and need, fall-back to support code if not present: try: from operator import attrgetter, itemgetter except ImportError: def attrgetter(name): def _getattr(obj): return getattr(obj, name) return _getattr def itemgetter(name): def _getitem(obj): return obj[name] return _getitem Masking functions if a particular function is not found: try: from base64 import b64decode except ImportError: from base64 import decodestring as b64decode -- Jeroen Ruigrok van der Werven <asmodai(-at-)in-nomine.org> / asmodai イェルーン ラウフロック ヴァン デル ウェルヴェン http://www.in-nomine.org/ | http://www.rangaku.org/ Only I can change my life. No one can do it for me...
Raymond Hettinger wrote:
[Jeroen Ruigrok van der Werven]
On the Trac project using your grep gives me 203 lines, if we take ~2 lines for and after in consideration, it still means 203/5 ~= 40 occurences.
Thanks. I'm more curious about the content of those lines. Does the proposed syntax help, does the need go away in Py3.0, what is the typical pattern?
I dont think I would use this based on a survey of 16 cases over 35k lines here..... The proposed syntax could be easily used 11 times. 10 of those are the 'or None' variant and account for platform-specific modules. 2 of those currently issue a warning about the missing module in the exception branch, but I guess I could live without that. Two other cases uses a different fallback value other than None; one a string literal, and the other 'object'. The remaining three cases do not really fit the proposed syntax. They are currently in the form: try: import xxx except ImportError: recovery actions else: do something with xxx
On Wed, Jan 02, 2008, Raymond Hettinger wrote:
Before posting, I ran some scans of our code base at work and found plenty of examples (mostly third-party cmodules vs python equivalents and a few that searched for similar functionality in different packages). It might be helpful if others were to also search their own code bases and post their findings:
find . -name "*py" | xargs grep -C2 ImportError *py
Most of my company's examples fall into cases like this: try: klass = load_class(foo) except ImportError: klass = NullClass -- Aahz (aahz@pythoncraft.com) <*> http://www.pythoncraft.com/ Weinberg's Second Law: If builders built buildings the way programmers wrote programs, then the first woodpecker that came along would destroy civilization.
participants (4)
-
Aahz -
Jeroen Ruigrok van der Werven -
Raymond Hettinger -
Toby Dickenson