You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
130 lines
3.8 KiB
Python
130 lines
3.8 KiB
Python
#!/usr/bin/python
|
|
#
|
|
# Urwid split_repr helper functions
|
|
# Copyright (C) 2004-2008 Ian Ward
|
|
#
|
|
# This library is free software; you can redistribute it and/or
|
|
# modify it under the terms of the GNU Lesser General Public
|
|
# License as published by the Free Software Foundation; either
|
|
# version 2.1 of the License, or (at your option) any later version.
|
|
#
|
|
# This library is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
# Lesser General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Lesser General Public
|
|
# License along with this library; if not, write to the Free Software
|
|
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
#
|
|
# Urwid web site: http://excess.org/urwid/
|
|
|
|
from inspect import getargspec
|
|
|
|
def split_repr(self):
|
|
"""
|
|
Return a helpful description of the object using
|
|
self._repr_words() and self._repr_attrs() to add
|
|
to the description. This function may be used by
|
|
adding code to your class like this:
|
|
|
|
>>> class Foo(object):
|
|
... __repr__ = split_repr
|
|
... def _repr_words(self):
|
|
... return ["words", "here"]
|
|
... def _repr_attrs(self):
|
|
... return {'attrs': "appear too"}
|
|
>>> Foo()
|
|
<Foo words here attrs='appear too'>
|
|
>>> class Bar(Foo):
|
|
... def _repr_words(self):
|
|
... return Foo._repr_words(self) + ["too"]
|
|
... def _repr_attrs(self):
|
|
... return dict(Foo._repr_attrs(self), barttr=42)
|
|
>>> Bar()
|
|
<Bar words here too attrs='appear too' barttr=42>
|
|
"""
|
|
alist = self._repr_attrs().items()
|
|
alist.sort()
|
|
words = self._repr_words()
|
|
if not words and not alist:
|
|
# if we're just going to print the classname fall back
|
|
# to the previous __repr__ implementation instead
|
|
return super(self.__class__, self).__repr__()
|
|
if words and alist: words.append("")
|
|
return "<%s %s>" % (self.__class__.__name__,
|
|
" ".join(words) +
|
|
" ".join(["%s=%s" % (k,normalize_repr(v)) for k,v in alist]))
|
|
|
|
def normalize_repr(v):
|
|
"""
|
|
Return dictionary repr sorted by keys, leave others unchanged
|
|
|
|
>>> normalize_repr({1:2,3:4,5:6,7:8})
|
|
'{1: 2, 3: 4, 5: 6, 7: 8}'
|
|
>>> normalize_repr('foo')
|
|
"'foo'"
|
|
"""
|
|
if isinstance(v, dict):
|
|
items = v.items()
|
|
items.sort()
|
|
return "{" + ", ".join([
|
|
repr(k) + ": " + repr(v) for k, v in items]) + "}"
|
|
|
|
return repr(v)
|
|
|
|
|
|
def remove_defaults(d, fn):
|
|
"""
|
|
Remove keys in d that are set to the default values from
|
|
fn. This method is used to unclutter the _repr_attrs()
|
|
return value.
|
|
|
|
d will be modified by this function.
|
|
|
|
Returns d.
|
|
|
|
>>> class Foo(object):
|
|
... def __init__(self, a=1, b=2):
|
|
... self.values = a, b
|
|
... __repr__ = split_repr
|
|
... def _repr_words(self):
|
|
... return ["object"]
|
|
... def _repr_attrs(self):
|
|
... d = dict(a=self.values[0], b=self.values[1])
|
|
... return remove_defaults(d, Foo.__init__)
|
|
>>> Foo(42, 100)
|
|
<Foo object a=42 b=100>
|
|
>>> Foo(10, 2)
|
|
<Foo object a=10>
|
|
>>> Foo()
|
|
<Foo object>
|
|
"""
|
|
args, varargs, varkw, defaults = getargspec(fn)
|
|
|
|
# ignore *varargs and **kwargs
|
|
if varkw:
|
|
del args[-1]
|
|
if varargs:
|
|
del args[-1]
|
|
|
|
# create adictionary of args with default values
|
|
ddict = dict(zip(args[len(args) - len(defaults):], defaults))
|
|
|
|
for k, v in d.items():
|
|
if k in ddict:
|
|
# remove values that match their defaults
|
|
if ddict[k] == v:
|
|
del d[k]
|
|
|
|
return d
|
|
|
|
|
|
|
|
def _test():
|
|
import doctest
|
|
doctest.testmod()
|
|
|
|
if __name__=='__main__':
|
|
_test()
|