Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
mikf
GitHub Repository: mikf/gallery-dl
Path: blob/master/scripts/pyprint.py
8764 views
1
#!/usr/bin/env python3
2
# -*- coding: utf-8 -*-
3
4
# Copyright 2024-2025 Mike Fährmann
5
#
6
# This program is free software; you can redistribute it and/or modify
7
# it under the terms of the GNU General Public License version 2 as
8
# published by the Free Software Foundation.
9
10
11
def pyprint(obj, indent=0, sort=None, oneline=True, lmin=0, lmax=16):
12
13
if isinstance(obj, str):
14
if obj.startswith("lit:"):
15
return f'''{obj[4:]}'''
16
17
if "\\" in obj or obj.startswith("re:"):
18
prefix = "r"
19
else:
20
prefix = ""
21
22
quote_beg = quote_end = '"'
23
if "\n" in obj:
24
quote_beg = '"""\\\n'
25
quote_end = '\\\n"""'
26
elif '"' in obj:
27
quote_beg = quote_end = \
28
"'''" if obj[0] == '"' or obj[-1] == '"' else '"""'
29
30
return f'''{prefix}{quote_beg}{obj}{quote_end}'''
31
32
if isinstance(obj, bytes):
33
return f'''b"{str(obj)[2:-1]}"'''
34
35
if isinstance(obj, type):
36
if obj.__module__ == "builtins":
37
return f'''{obj.__name__}'''
38
39
name = obj.__module__.rpartition(".")[2]
40
if name[0].isdecimal():
41
name = f"_{name}"
42
return f'''{name}.{obj.__name__}'''
43
44
if isinstance(obj, dict):
45
if not obj:
46
return "{}"
47
if len(obj) == 1 and oneline:
48
key, value = next(iter(obj.items()))
49
return f'''{{"{key}": {pyprint(value, indent, sort)}}}'''
50
51
if sort:
52
if callable(sort):
53
lst = [(sort(key, value), key, value)
54
for key, value in obj.items()]
55
lst.sort()
56
obj = {key: value for _, key, value in lst}
57
else:
58
keys = list(obj)
59
keys.sort()
60
obj = {key: obj[key] for key in keys}
61
62
try:
63
keylen = max(kl for kl in map(len, obj) if kl <= lmax)
64
except Exception:
65
keylen = lmin
66
if keylen < lmin:
67
keylen = lmin
68
ws = " " * indent
69
70
lines = ["{"]
71
for key, value in obj.items():
72
if key.startswith("#blank-"):
73
lines.append("")
74
else:
75
lines.append(
76
f'''{ws} "{key}"'''
77
f'''{' '*(keylen - len(key))}: '''
78
f'''{pyprint(value, indent+4, sort)},'''
79
)
80
lines.append(f'''{ws}}}''')
81
return "\n".join(lines)
82
83
if isinstance(obj, list):
84
if not obj:
85
return "[]"
86
if len(obj) == 1 and oneline:
87
return f'''[{pyprint(obj[0], indent, sort)}]'''
88
89
ws = " " * indent
90
lines = ["["]
91
for value in obj:
92
lines.append(f'''{ws} {pyprint(value, indent+4, sort)},''')
93
lines.append(f'''{ws}]''')
94
return "\n".join(lines)
95
96
if isinstance(obj, tuple):
97
if not obj:
98
return "()"
99
if len(obj) == 1:
100
return f'''({pyprint(obj[0], indent, sort)},)'''
101
102
result = f'''({", ".join(pyprint(v, indent+4, sort) for v in obj)})'''
103
if len(result) < 80:
104
return result
105
106
ws = " " * indent
107
lines = ["("]
108
for value in obj:
109
lines.append(f'''{ws} {pyprint(value, indent+4, sort)},''')
110
lines.append(f'''{ws})''')
111
return "\n".join(lines)
112
113
if isinstance(obj, set):
114
if not obj:
115
return "set()"
116
return f'''{{{", ".join(pyprint(v, indent+4, sort) for v in obj)}}}'''
117
118
if obj.__class__.__name__ == "datetime":
119
if (off := obj.utcoffset()) is not None:
120
obj = obj.replace(tzinfo=None, microsecond=0) - off
121
elif obj.microsecond:
122
obj = obj.replace(microsecond=0)
123
return f'''"dt:{obj}"'''
124
125
return f'''{obj}'''
126
127