1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
|
# -*- coding: UTF-8 -*-
# Copyright 2014 Red Hat, Inc.
# Part of clufter project
# Licensed under GPLv2+ (a copy included | http://gnu.org/licenses/gpl-2.0.txt)
"""Various little+independent helpers"""
__author__ = "Jan Pokorný <jpokorny @at@ Red Hat .dot. com>"
# inspired by http://stackoverflow.com/a/4374075
immutable = lambda x: isinstance(x, (basestring, int, long, bool, float, tuple))
tuplist = lambda x: isinstance(x, (tuple, list))
# turn args into tuple unless single tuplist arg
args2sgpl = \
lambda x=(), *y: x if not y and tuplist(x) else (x, ) + y
args2combsgpl = arg2wrapped = \
lambda x=(), *y: x if not y and tuplist(x) and len(x) > 1 else (x, ) + y
args2unwrapped = \
lambda x=None, *y: x if not y else (x, ) + y
# turn args into tuple unconditionally
args2tuple = lambda *args: tuple(args)
any2iter = \
lambda x: \
x if hasattr(x, 'next') and hasattr(x.next, '__call__') \
else iter(args2sgpl(x, None))
head_tail = \
lambda x=None, *y, **kwargs: \
(x, args2sgpl(*y)) if not tuplist(x) or kwargs.get('stop', 0) \
else (head_tail(stop=1, *tuple(x) + y))
nonetype = type(None)
filterdict_keep = \
lambda src, *which, **kw: \
dict((x, src[x]) for x in which if x in src, **kw)
filterdict_invkeep = \
lambda src, *which, **kw: \
dict((x, src[x]) for x in src.iterkeys() if x not in which, **kw)
filterdict_pop = \
lambda src, *which, **kw: \
dict((x, src.pop(x)) for x in which if x in src, **kw)
filterdict_invpop = \
lambda src, *which, **kw: \
dict((x, src.pop(x)) for x in src if x in which, **kw)
#
# introspection related
#
def isinstanceexcept(subj, obj, exc=()):
return isinstance(subj, obj) and not isinstance(subj, exc)
def func_defaults_varnames(func, skip=0):
"""Using introspection, get arg defaults (dict) + all arg names (tuple)
Parameters:
skip how many initial arguments to skip
"""
code = func.func_code
func_varnames = code.co_varnames[skip:code.co_argcount]
func_defaults = dict(zip(
reversed(func_varnames),
reversed(func.func_defaults)
))
return func_defaults, func_varnames
#
# decorators
#
def selfaware(func):
"""Decorator suitable for recursive staticmethod"""
def selfaware_inner(*args, **kwargs):
return func(selfaware(func), *args, **kwargs)
map(lambda a: setattr(selfaware_inner, a, getattr(func, a)),
('__doc__', '__name__'))
return selfaware_inner
# Inspired by http://stackoverflow.com/a/1383402
class classproperty(property):
def __init__(self, fnc):
property.__init__(self, classmethod(fnc))
def __get__(self, this, owner):
return self.fget.__get__(None, owner)()
class hybridproperty(property):
def __init__(self, fnc):
property.__init__(self, classmethod(fnc))
def __get__(self, this, owner):
return self.fget.__get__(None, this if this else owner)()
|