blob: 327d8b42d877ad92681e2da3be15146a170151c1 [file] [log] [blame]
# epydoc -- Backwards compatibility
#
# Copyright (C) 2005 Edward Loper
# Author: Edward Loper <edloper@loper.org>
# 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