-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathstr.py
93 lines (82 loc) · 2.71 KB
/
str.py
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
#!/usr/bin/env python
# -*- coding: utf-8 -*-
#sdobrev 2003-8
from __future__ import print_function #,unicode_literals
'hierarchical str()/print; notSetYet singleton'
#######
class NotSetYet( object):
def __str__(me): return '<not-set-yet>'
__repr__ = __str__
def __new__( klas): #singleton PLEASE - needs pickle.protocol >=2
try:
return notSetYet
except NameError as e:
return object.__new__( klas)
# def __getnewargs__( me): return (True,) #something non empty to distinguish pickling
notSetYet = NotSetYet()
def test_NotSetYet():
i = NotSetYet()
assert i is notSetYet
import pickle
p = pickle.dumps( i, pickle.HIGHEST_PROTOCOL)
print( repr(p))
z = pickle.loads(p)
assert type(z) is type(a)
assert z is i, ( z,i, id(z), id(i) )
from .attr import get_attrib
_level = 0
_stack = []
_make_str_delimiter = '\n'
_make_str_tab = 4*' '
def make_str( me, order, name_name ='name',
kv_format ='%s = %r',
attr_filter =lambda a: a.startswith('__') and a.endswith('__'),
notSetYet =notSetYet,
**kargs #getattr =getattr,
):
""" Warning: this may recurse forever if a property calls here,
AND is listed in the order...
"""
delimiter = kargs.pop( 'delimiter', _make_str_delimiter)
tab = kargs.pop( 'tab', _make_str_tab)
global _level, _stack
#print id(me), type(me), _stack
#if id(me) in _stack: print '*'
a = ''
klas_name = me.__class__.__name__
name = name_name and getattr( me, name_name, None)
if name and name != klas_name:
a = name + ': '
a += klas_name + '('
if id(me) in _stack:
return a+'*)' #round-cycle
_stack.append( id(me))
_level+=1
try:
r = (delimiter + tab * _level).join( [a]+
[ kv_format % (k, get_attrib( me, k, notSetYet, **kargs ))
for k in order if not attr_filter( k)
] )
finally:
_level-=1
r+= delimiter + tab * _level + ')'
_stack.pop()
return r
####################
_delimiter = ', '
def str_args_kargs( *args,**kargs):
delimiter = kargs.pop( '_delimiter', _delimiter)
repr = kargs.pop( '_repr', str)
filter = kargs.pop( '_filter', lambda *a: True)
return delimiter.join(
[ repr(a) for a in args ]
+ [ '%s=%s' % (k,repr(v)) for k,v in kargs.items() if filter( k,v) ])
####### debug/log
class printdbg:
debug =''
@classmethod
def callfunc( klas, func, *args,**kargs):
if 'call' in klas.debug:
print( func, '(\n ', args, '\n '+ '\n '.join( '%s=%s' % kv for kv in kargs.items()), '\n)')
return func( *args, **kargs)
# vim:ts=4:sw=4:expandtab