| # epydoc -- Backwards compatibility |
| # |
| # Copyright (C) 2005 Edward Loper |
| # Author: Edward Loper <[email protected]> |
| # URL: <http://epydoc.sf.net> |
| # |
| # $Id: util.py 956 2006-03-10 01:30:51Z edloper $ |
| |
| """ |
| Backwards compatibility with previous versions of Python. |
| |
| This module provides backwards compatibility by defining several |
| functions and classes that were not available in earlier versions of |
| Python. Intented usage: |
| |
| >>> from epydoc.compat import * |
| |
| Currently, epydoc requires Python 2.3+. |
| """ |
| __docformat__ = 'epytext' |
| |
| ###################################################################### |
| #{ New in Python 2.4 |
| ###################################################################### |
| |
| # set |
| try: |
| set |
| except NameError: |
| try: |
| from sets import Set as set, ImmutableSet as frozenset |
| except ImportError: |
| pass # use fallback, in the next section. |
| |
| # sorted |
| try: |
| sorted |
| except NameError: |
| def sorted(iterable, cmp=None, key=None, reverse=False): |
| if key is None: |
| elts = list(iterable) |
| else: |
| elts = [(key(v), v) for v in iterable] |
| |
| if reverse: elts.reverse() # stable sort. |
| if cmp is None: elts.sort() |
| else: elts.sort(cmp) |
| if reverse: elts.reverse() |
| |
| if key is None: |
| return elts |
| else: |
| return [v for (k,v) in elts] |
| |
| # reversed |
| try: |
| reversed |
| except NameError: |
| def reversed(iterable): |
| elts = list(iterable) |
| elts.reverse() |
| return elts |
| |
| ###################################################################### |
| #{ New in Python 2.3 |
| ###################################################################### |
| # Below is my initial attempt at backporting enough code that |
| # epydoc 3 would run under python 2.2. However, I'm starting |
| # to think that it's not worth the trouble. At the very least, |
| # epydoc's current unicode handling still doesn't work under |
| # 2.2 (after the backports below), since the 'xmlcharrefreplace' |
| # error handler was introduced in python 2.3. |
| |
| # # basestring |
| # try: |
| # basestring |
| # except NameError: |
| # basestring = (str, unicode) |
| |
| # # sum |
| # try: |
| # sum |
| # except NameError: |
| # def _add(a,b): return a+b |
| # def sum(vals): return reduce(_add, vals, 0) |
| |
| # # True & False |
| # try: |
| # True |
| # except NameError: |
| # True = 1 |
| # False = 0 |
| |
| # # enumerate |
| # try: |
| # enumerate |
| # except NameError: |
| # def enumerate(iterable): |
| # lst = list(iterable) |
| # return zip(range(len(lst)), lst) |
| |
| # # set |
| # try: |
| # set |
| # except NameError: |
| # class set(dict): |
| # def __init__(self, elts=()): |
| # dict.__init__(self, [(e,1) for e in elts]) |
| # def __repr__(self): |
| # return 'set(%r)' % list(self) |
| # def add(self, key): self[key] = 1 |
| # def copy(self): |
| # return set(dict.copy(self)) |
| # def difference(self, other): |
| # return set([v for v in self if v not in other]) |
| # def difference_udpate(self, other): |
| # newval = self.difference(other) |
| # self.clear(); self.update(newval) |
| # def discard(self, elt): |
| # try: del self[elt] |
| # except: pass |
| # def intersection(self, other): |
| # return self.copy().update(other) |
| # def intersection_update(self, other): |
| # newval = self.intersection(other) |
| # self.clear(); self.update(newval) |
| # def issubset(self, other): |
| # for elt in self: |
| # if elt not in other: return False |
| # return True |
| # def issuperset(self, other): |
| # for elt in other: |
| # if elt not in self: return False |
| # return True |
| # def pop(self): self.popitem()[0] |
| # def remove(self, elt): del self[elt] |
| # def symmetric_difference(self, other): |
| # return set([v for v in list(self)+list(other) |
| # if (v in self)^(v in other)]) |
| # def symmatric_difference_update(self, other): |
| # newval = self.symmetric_difference(other) |
| # self.clear(); self.update(newval) |
| # def union(self, other): |
| # return set([v for v in list(self)+list(other) |
| # if (v in self) or (v in other)]) |
| # def union_update(self, other): |
| # newval = self.union(other) |
| # self.clear(); self.update(newval) |
| # def update(self, other): |
| # dict.update(self, set(other)) |
| |
| # # optparse module |
| # try: |
| # import optparse |
| # except ImportError: |
| # import new, sys, getopt |
| # class _OptionVals: |
| # def __init__(self, vals): self.__dict__.update(vals) |
| # class OptionParser: |
| # def __init__(self, usage=None, version=None): |
| # self.usage = usage |
| # self.version = version |
| # self.shortops = ['h'] |
| # self.longops = [] |
| # self.option_specs = {} |
| # self.defaults = {} |
| # def fail(self, message, exitval=1): |
| # print >>sys.stderr, message |
| # system.exit(exitval) |
| # def add_option_group(self, group): pass |
| # def set_defaults(self, **defaults): |
| # self.defaults = defaults.copy() |
| # def parse_args(self): |
| # try: |
| # (opts, names) = getopt.getopt(sys.argv[1:], |
| # ''.join(self.shortops), |
| # self.longops) |
| # except getopt.GetoptError, e: |
| # self.fail(e) |
| |
| # options = self.defaults.copy() |
| # for (opt,val) in opts: |
| # if opt == '-h': |
| # self.fail('No help available') |
| # if opt not in self.option_specs: |
| # self.fail('Unknown option %s' % opt) |
| # (action, dest, const) = self.option_specs[opt] |
| # if action == 'store': |
| # options[dest] = val |
| # elif action == 'store_const': |
| # options[dest] = const |
| # elif action == 'count': |
| # options[dest] = options.get(dest,0)+1 |
| # elif action == 'append': |
| # options.setdefault(dest, []).append(val) |
| # else: |
| # self.fail('unsupported action: %s' % action) |
| # for (action,dest,const) in self.option_specs.values(): |
| # if dest not in options: |
| # if action == 'count': options[dest] = 0 |
| # elif action == 'append': options[dest] = [] |
| # else: options[dest] = None |
| # for name in names: |
| # if name.startswith('-'): |
| # self.fail('names must follow options') |
| # return _OptionVals(options), names |
| # class OptionGroup: |
| # def __init__(self, optparser, name): |
| # self.optparser = optparser |
| # self.name = name |
| |
| # def add_option(self, *args, **kwargs): |
| # action = 'store' |
| # dest = None |
| # const = None |
| # for (key,val) in kwargs.items(): |
| # if key == 'action': action = val |
| # elif key == 'dest': dest = val |
| # elif key == 'const': const = val |
| # elif key in ('help', 'metavar'): pass |
| # else: self.fail('unsupported: %s' % key) |
| |
| # if action not in ('store_const', 'store_true', 'store_false', |
| # 'store', 'count', 'append'): |
| # self.fail('unsupported action: %s' % action) |
| |
| # optparser = self.optparser |
| # for arg in args: |
| # if arg.startswith('--'): |
| # optparser.longops.append(arg[2:]) |
| # elif arg.startswith('-') and len(arg)==2: |
| # optparser.shortops += arg[1] |
| # if action in ('store', 'append'): |
| # optparser.shortops += ':' |
| # else: |
| # self.fail('bad option name %s' % arg) |
| # if action == 'store_true': |
| # (action, const) = ('store_const', True) |
| # if action == 'store_false': |
| # (action, const) = ('store_const', False) |
| # optparser.option_specs[arg] = (action, dest, const) |
| |
| # # Install a fake module. |
| # optparse = new.module('optparse') |
| # optparse.OptionParser = OptionParser |
| # optparse.OptionGroup = OptionGroup |
| # sys.modules['optparse'] = optparse |
| # # Clean up |
| # del OptionParser, OptionGroup |
| |