cs-x 20261016__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
cs/x.py ADDED
@@ -0,0 +1,182 @@
1
+ #!/usr/bin/python
2
+ #
3
+ # Just my X debugging function.
4
+ # - Cameron Simpson <cs@cskk.id.au>
5
+ #
6
+
7
+ '''
8
+ X(), for low level debugging.
9
+
10
+ X() is my function for low level ad hoc debug messages.
11
+ It takes a message and optional format arguments for use with `%`.
12
+ It is presented here in its own module for reuse:
13
+
14
+ from cs.x import X
15
+ ...
16
+ X("foo: x=%s, a=%r", x, a)
17
+
18
+ It normally writes directly to `sys.stderr` but accepts an optional
19
+ keyword argument `file` to specify a different filelike object.
20
+
21
+ The following globals further tune its behaviour,
22
+ absent the `file=` parameter:
23
+ * `X_default_colour`: if set, messages will be ANSI coloured using
24
+ `cs.ansi_colour.colourise`
25
+ * `X_discard`: if true then discard the message.
26
+ Otherwise write the message to `sys.stderr`.
27
+ `X_discard`'s default value is `not sys.stderr.isatty()`.
28
+ * `X_logger`: if not `None` then log a warning to that logger.
29
+ * `X_via_tty`: if true then a pathname to which to append messages.
30
+
31
+ The following environment variables affect the initial values of the globals:
32
+ * `$CS_X_COLOUR`: this sets `X_default_colour`.
33
+ * `$CS_X_LOGGER`:
34
+ if present, an empty value sets `X_logger` to the root logger
35
+ and a nonempty value names a logger.
36
+ * `$CS_X_VIA_TTY`: if missing or empty, `X_via_tty` will be false.
37
+ Otherwise,
38
+ if `$CS_X_VIA_TTY` has a nonempty value which is a full path
39
+ to an existing filesystem object (typically a tty)
40
+ then is will be used for `X_via_tty`,
41
+ otherwise `X_via_tty` will be set to `'/dev/tty'`.
42
+ This is handy for getting debugging out of test suites,
43
+ which often divert `sys.stderr`.
44
+ '''
45
+
46
+ import logging
47
+ import os
48
+ import os.path
49
+ import sys
50
+
51
+ from cs.ansi_colour import colourise
52
+ from cs.gimmicks import open_append
53
+
54
+ __version__ = '20261016'
55
+
56
+ DISTINFO = {
57
+ 'keywords': ["python2", "python3"],
58
+ 'classifiers': [
59
+ "Programming Language :: Python",
60
+ "Programming Language :: Python :: 3",
61
+ ],
62
+ 'install_requires': [
63
+ 'cs.ansi_colour',
64
+ 'cs.gimmicks',
65
+ ],
66
+ 'python_requires':
67
+ '>=3',
68
+ }
69
+
70
+ # discard output? the default if sys.stderr is not a tty
71
+ try:
72
+ isatty = sys.stderr.isatty
73
+ except AttributeError:
74
+ X_discard = True
75
+ else:
76
+ X_discard = not isatty()
77
+ # set to a logger to log as a warning
78
+ X_logger = os.environ.get('CS_X_LOGGER')
79
+ if X_logger is not None:
80
+ X_Logger = logging.getLogger(X_logger or None)
81
+ # colouring
82
+ X_default_colour = os.environ.get('CS_X_COLOUR')
83
+
84
+ # pylint: disable=too-many-branches
85
+ def X(msg, *args, file=None, colour=None): # noqa: N802
86
+ ''' Unconditionally write the message `msg`.
87
+
88
+ If there are positional arguments after `msg`,
89
+ format `msg` using %-expansion with those arguments.
90
+
91
+ Keyword arguments:
92
+ * `file`: optional keyword argument specifying the output file.
93
+ * `colour`: optional text colour.
94
+ If specified, surround the message with ANSI escape sequences
95
+ to render the text in that colour.
96
+
97
+ If `file` is not `None`, write to it unconditionally.
98
+ Otherwise, the following globals are consulted in order:
99
+ * `X_logger`: if not `None` then log a warning to that logger
100
+ * `X_via_tty`: if true then append the message to the path it contains
101
+ * `X_discard`: if true then discard the message
102
+ Otherwise write the message to `sys.stderr`.
103
+
104
+ `X_logger` is `None` by default.
105
+ `X_via_tty` is initialised from the environment variable `$CS_X_VIA_TTY`.
106
+ `X_discard` is true unless `sys.stderr.isatty()` is true.
107
+ '''
108
+ if colour is None:
109
+ colour = X_default_colour
110
+ if args:
111
+ try:
112
+ msg = msg % args
113
+ except TypeError as e:
114
+ X("X(%r, *%r): %s", msg, args, e, colour='red', file=file)
115
+ msg = f'{msg} % {args!r}'
116
+ else:
117
+ msg = str(msg)
118
+ if colour:
119
+ msg = colourise(msg, colour=colour)
120
+ close_fp = None
121
+ if file is None:
122
+ if X_logger:
123
+ # NB: ignores any kwargs
124
+ X_logger.warning(msg)
125
+ return
126
+ if X_via_tty:
127
+ # NB: ignores any kwargs
128
+ try:
129
+ f = open_append(X_via_tty)
130
+ except (IOError, OSError) as e: # noqa: UP024
131
+ X(
132
+ "X: cannot append to %r: %s:%s",
133
+ X_via_tty,
134
+ type(e),
135
+ e,
136
+ file=sys.stderr,
137
+ )
138
+ X(msg, file=sys.stderr)
139
+ return
140
+ close_fp = f
141
+ if X_discard:
142
+ return
143
+ file = sys.stderr
144
+ print(msg, file=file)
145
+ if close_fp is not None:
146
+ close_fp.close()
147
+
148
+ # init X_via_tty (after X() because we use X() for messaging)
149
+ env_via_tty = os.environ.get('CS_X_VIA_TTY', '')
150
+ if not env_via_tty:
151
+ X_via_tty = False
152
+ else:
153
+ X_via_tty = '/dev/tty'
154
+ if env_via_tty.startswith('/'):
155
+ try:
156
+ xfd = os.open(env_via_tty, os.O_RDONLY)
157
+ except OSError as e:
158
+ X("%s: open(%r): %s, using %r", __file__, env_via_tty, e, X_via_tty)
159
+ else:
160
+ if not os.isatty(xfd):
161
+ X(
162
+ "%s: open(%r): not a tty, using %r",
163
+ __file__,
164
+ env_via_tty,
165
+ X_via_tty,
166
+ )
167
+ else:
168
+ X_via_tty = env_via_tty
169
+ os.close(xfd)
170
+
171
+ if os.environ.get('CS_X_BUILTIN', ''):
172
+ try:
173
+ import builtins
174
+ except ImportError:
175
+ pass
176
+ else:
177
+ builtins.X = X
178
+
179
+ def Y(msg, *a, **kw): # noqa: N802
180
+ ''' Wrapper for `X()` rendering in yellow.
181
+ '''
182
+ X(msg, *a, colour='yellow', **kw)
@@ -0,0 +1,98 @@
1
+ Metadata-Version: 2.4
2
+ Name: cs-x
3
+ Version: 20261016
4
+ Summary: X(), for low level debugging.
5
+ Keywords: python2,python3
6
+ Author-email: Cameron Simpson <cs@cskk.id.au>
7
+ Requires-Python: >=3
8
+ Description-Content-Type: text/markdown
9
+ Classifier: Programming Language :: Python
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Development Status :: 4 - Beta
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: Operating System :: OS Independent
14
+ Classifier: Topic :: Software Development :: Libraries :: Python Modules
15
+ Classifier: License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)
16
+ Requires-Dist: cs.ansi_colour>=20260531
17
+ Requires-Dist: cs.gimmicks>=20260311
18
+ Project-URL: MonoRepo Commits, https://bitbucket.org/cameron_simpson/css/commits/branch/main
19
+ Project-URL: Monorepo Git Mirror, https://github.com/cameron-simpson/css
20
+ Project-URL: Monorepo Hg/Mercurial Mirror, https://hg.sr.ht/~cameron-simpson/css
21
+ Project-URL: Source, https://github.com/cameron-simpson/css/blob/main/lib/python/cs/x.py
22
+
23
+ X(), for low level debugging.
24
+
25
+ X() is my function for low level ad hoc debug messages.
26
+ It takes a message and optional format arguments for use with `%`.
27
+ It is presented here in its own module for reuse:
28
+
29
+ from cs.x import X
30
+ ...
31
+ X("foo: x=%s, a=%r", x, a)
32
+
33
+ It normally writes directly to `sys.stderr` but accepts an optional
34
+ keyword argument `file` to specify a different filelike object.
35
+
36
+ The following globals further tune its behaviour,
37
+ absent the `file=` parameter:
38
+ * `X_default_colour`: if set, messages will be ANSI coloured using
39
+ `cs.ansi_colour.colourise`
40
+ * `X_discard`: if true then discard the message.
41
+ Otherwise write the message to `sys.stderr`.
42
+ `X_discard`'s default value is `not sys.stderr.isatty()`.
43
+ * `X_logger`: if not `None` then log a warning to that logger.
44
+ * `X_via_tty`: if true then a pathname to which to append messages.
45
+
46
+ The following environment variables affect the initial values of the globals:
47
+ * `$CS_X_COLOUR`: this sets `X_default_colour`.
48
+ * `$CS_X_LOGGER`:
49
+ if present, an empty value sets `X_logger` to the root logger
50
+ and a nonempty value names a logger.
51
+ * `$CS_X_VIA_TTY`: if missing or empty, `X_via_tty` will be false.
52
+ Otherwise,
53
+ if `$CS_X_VIA_TTY` has a nonempty value which is a full path
54
+ to an existing filesystem object (typically a tty)
55
+ then is will be used for `X_via_tty`,
56
+ otherwise `X_via_tty` will be set to `'/dev/tty'`.
57
+ This is handy for getting debugging out of test suites,
58
+ which often divert `sys.stderr`.
59
+
60
+
61
+
62
+ Short summary:
63
+
64
+
65
+ * `X`: Unconditionally write the message `msg`.
66
+
67
+
68
+ * `Y`: Wrapper for `X()` rendering in yellow.
69
+
70
+ # Functions
71
+
72
+ ## X(msg, *args, file=None, colour=None)
73
+
74
+ Unconditionally write the message `msg`.
75
+
76
+ If there are positional arguments after `msg`,
77
+ format `msg` using %-expansion with those arguments.
78
+
79
+ Keyword arguments:
80
+ * `file`: optional keyword argument specifying the output file.
81
+ * `colour`: optional text colour.
82
+ If specified, surround the message with ANSI escape sequences
83
+ to render the text in that colour.
84
+
85
+ If `file` is not `None`, write to it unconditionally.
86
+ Otherwise, the following globals are consulted in order:
87
+ * `X_logger`: if not `None` then log a warning to that logger
88
+ * `X_via_tty`: if true then append the message to the path it contains
89
+ * `X_discard`: if true then discard the message
90
+ Otherwise write the message to `sys.stderr`.
91
+
92
+ `X_logger` is `None` by default.
93
+ `X_via_tty` is initialised from the environment variable `$CS_X_VIA_TTY`.
94
+ `X_discard` is true unless `sys.stderr.isatty()` is true.
95
+
96
+ ## Y(msg, *a, **kw)
97
+
98
+ Wrapper for `X()` rendering in yellow.
@@ -0,0 +1,4 @@
1
+ cs/x.py,sha256=nWeTzPT1sZPQqoWrpFYrY7c9V_8fPVCagigif-FhJak,5265
2
+ cs_x-20261016.dist-info/WHEEL,sha256=G2gURzTEtmeR8nrdXUJfNiB3VYVxigPQ-bEQujpNiNs,82
3
+ cs_x-20261016.dist-info/METADATA,sha256=vZg5PrBkMUlPKoT_k9LSnCQW4LGV2GyiPnG94w4rfTw,3614
4
+ cs_x-20261016.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: flit 3.12.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any