python-clu 0.12.2__py3-none-any.whl → 0.12.4__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.
clu/__init__.py CHANGED
File without changes
clu/__version__.py CHANGED
@@ -1 +1 @@
1
- __version__ = '0.12.2'
1
+ __version__ = '0.12.4'
File without changes
@@ -15,7 +15,7 @@ def version_string():
15
15
  semantic = f"{version.major}.{version.minor}.{version.patch}"
16
16
 
17
17
  if version.pre:
18
- semantic += f"-{version.pre}"
18
+ semantic += f":pre{version.pre}"
19
19
  if version.build:
20
20
  semantic += f"+{version.build}"
21
21
  semantic += " [SNAPSHOT]"
@@ -29,13 +29,22 @@ def print_version_command():
29
29
  in ancilliary human-readable copyright information
30
30
  """
31
31
  semantic = version_string()
32
- copyright = f"CLU version {semantic} © 2010-2032 Alexander Böhn"
32
+ flags = ('--version-only', '-V')
33
+
34
+ # check if we just want the version number:
35
+ for flag in flags:
36
+ if flag in sys.argv:
37
+ # Just print the number and return OK:
38
+ print(semantic)
39
+ return os.EX_OK
33
40
 
34
- # print it:
41
+ # print the whole schpiel:
42
+ copyright = f"CLU version {semantic} © 2010-2032 Alexander Böhn"
35
43
  print(copyright)
36
44
 
37
45
  # Return nice-nice for my POSI(X)ES:
38
46
  return os.EX_OK
39
47
 
40
48
  if __name__ == '__main__':
49
+ # sys.argv += ['--version-only']
41
50
  sys.exit(print_version_command())
File without changes
clu/scripts/dictroast.py CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
clu/scripts/repl.py CHANGED
@@ -83,9 +83,10 @@ starmods = ('clu.repl.ansi',
83
83
  'clu.config.env',
84
84
  'clu.config.keymap',
85
85
  'clu.config.proxy',
86
- 'clu.dicts', 'clu.enums', 'clu.exporting', 'clu.extending', 'clu.shelving.redat',
87
- 'clu.importing', 'clu.mathematics', 'clu.naming', 'clu.predicates', 'clu.typology',
88
- 'clu.fs.abc', 'clu.fs.filesystem', 'clu.fs.misc', 'clu.repr', 'clu.scripts.treeline', 'clu.stdio',
86
+ 'clu.dicts', 'clu.enums', 'clu.exporting',
87
+ 'clu.importing', 'clu.naming', 'clu.predicates', 'clu.typology',
88
+ 'clu.fs.abc', 'clu.fs.filesystem', 'clu.fs.misc', 'clu.repr',
89
+ 'clu.scripts.treeline',
89
90
  'clu.typespace.namespace',
90
91
  'clu.testing.utils')
91
92
 
@@ -101,9 +102,12 @@ mods = ('clu',
101
102
  'clu.csv',
102
103
  'clu.fs.appdirectories',
103
104
  'clu.keyvalue',
105
+ 'clu.mathematics',
104
106
  'clu.dispatch', 'clu.sanitizer', 'clu.fs.pypath',
107
+ 'clu.extending', 'clu.shelving.redat',
105
108
  'clu.scripts.ansicolors',
106
109
  'clu.scripts.treeline',
110
+ 'clu.stdio',
107
111
  'clu.typespace.types', # not technically a module!
108
112
  'clu.version', 'clu.version.git_version',
109
113
  'sys', 'os', 'io', 're', 'abc',
@@ -111,9 +115,8 @@ mods = ('clu',
111
115
  'datetime', 'functools', 'importlib', 'inspect',
112
116
  'itertools', 'math', 'operator', 'pathlib',
113
117
  'pickle', 'six', 'shutil', 'sysconfig', 'weakref',
114
- 'numpy', 'more_itertools', 'colorama', 'termcolor',
115
- 'xerox', 'zict', 'pytz', 'dateutil',
116
- 'termplotlib', 'termtables')
118
+ 'numpy', 'more_itertools', 'colorama',
119
+ 'xerox', 'zict')
117
120
 
118
121
  # “Star-import” all starmods – this is equivalent to doing:
119
122
  #
@@ -219,6 +222,8 @@ if 'user:script' in cluenv:
219
222
 
220
223
  # Adjust __all__ again:
221
224
  __all__ += ['_explain', 'explain', 'cluenv']
225
+ # __all__ = tuple(__all__)
226
+ __dir__ = lambda: __all__
222
227
 
223
228
  # Remove duplicate and invalid sys.paths:
224
229
  pypath.remove_invalid_paths()
@@ -0,0 +1,516 @@
1
+ Metadata-Version: 2.4
2
+ Name: python-clu
3
+ Version: 0.12.4
4
+ Summary: Python-CLU: Common Lightweight Utilities
5
+ Home-page: https://github.com/fish2000/clu
6
+ Download-URL: https://github.com/fish2000/clu/zipball/master
7
+ Author: Alexander Böhn
8
+ Author-email: Alexander Böhn <fish2000@gmail.com>
9
+ Project-URL: homepage, https://github.com/fish2000/CLU
10
+ Project-URL: repository, https://github.com/fish2000/CLU
11
+ Project-URL: documentation, https://github.com/fish2000/CLU/blob/master/README.md
12
+ Project-URL: source, https://github.com/fish2000/CLU
13
+ Project-URL: tracker, https://github.com/fish2000/CLU/issues
14
+ Project-URL: changelog, https://github.com/fish2000/CLU/blob/master/CHANGELOG.md
15
+ Project-URL: download, https://pypi.org/project/python-clu/
16
+ Keywords: testing,command,command-line,utilities,modules,REPL,tools
17
+ Platform: any
18
+ Classifier: Development Status :: 5 - Production/Stable
19
+ Classifier: Framework :: Pytest
20
+ Classifier: Intended Audience :: Developers
21
+ Classifier: Topic :: Software Development
22
+ Classifier: Topic :: Software Development :: Testing
23
+ Classifier: Topic :: Utilities
24
+ Classifier: Operating System :: MacOS
25
+ Classifier: Operating System :: Microsoft :: Windows
26
+ Classifier: Operating System :: OS Independent
27
+ Classifier: Operating System :: POSIX
28
+ Classifier: Operating System :: Unix
29
+ Classifier: Programming Language :: Python
30
+ Classifier: Programming Language :: Python :: 3
31
+ Classifier: Programming Language :: Python :: 3.10
32
+ Classifier: Programming Language :: Python :: Implementation :: CPython
33
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
34
+ Description-Content-Type: text/markdown
35
+ License-File: LICENSE.txt
36
+ Requires-Dist: build
37
+ Requires-Dist: Click>=7.0
38
+ Requires-Dist: colorama>=0.4.0
39
+ Requires-Dist: dataclasses>=0.6; python_version < "3.7"
40
+ Requires-Dist: dbx-stopwatch>=1.6
41
+ Requires-Dist: enum34>=1.1.0; python_version < "3.4"
42
+ Requires-Dist: humanize>=1.0.0
43
+ Requires-Dist: importlib-metadata>=1.4.0; python_version < "3.8"
44
+ Requires-Dist: mock>=4.0.0
45
+ Requires-Dist: more_itertools>=8.0.0
46
+ Requires-Dist: multidict>=4.7.0
47
+ Requires-Dist: packaging
48
+ Requires-Dist: pout>=0.8.13
49
+ Requires-Dist: pygments>=2.0.0
50
+ Requires-Dist: PyYAML>=5.3.0
51
+ Requires-Dist: redis>=3.4.0
52
+ Requires-Dist: setuptools>=30.0.0
53
+ Requires-Dist: six>=1.10.0
54
+ Requires-Dist: toml>=0.10.0
55
+ Requires-Dist: wheel>=0.34.0
56
+ Requires-Dist: zict>=0.1.2
57
+ Provides-Extra: all
58
+ Requires-Dist: more_itertools>=8.0.0; extra == "all"
59
+ Requires-Dist: numpy>=1.17.0; extra == "all"
60
+ Requires-Dist: Pillow>=7.1.0; extra == "all"
61
+ Requires-Dist: pytest>=5.4.0; extra == "all"
62
+ Requires-Dist: zipp>=2.0.0; extra == "all"
63
+ Dynamic: author
64
+ Dynamic: download-url
65
+ Dynamic: home-page
66
+ Dynamic: license-file
67
+ Dynamic: platform
68
+
69
+ [Python-CLU][clu] – Common Lightweight Utilities
70
+ ========================================================
71
+
72
+ [![codecov](https://codecov.io/gh/fish2000/CLU/branch/master/graph/badge.svg)](https://codecov.io/gh/fish2000/CLU/)
73
+
74
+ Install it right now! [Download][download-link] or type: `$ pip install -U python-clu`
75
+ ------------------------------------------------------------------------------
76
+
77
+ The deal with CLU is, it is a bunch of stuff. Like, a junk drawer… but a junk drawer
78
+ full of building sets: [Legos][lego-link], [Robotix][robotix-link], [Capsela][capsela-link]
79
+ – and also magic interfaces that let somehow you plug Legos into Capselas and all
80
+ that. It’s a la carte: you can use one part of CLU (say the [inline testing stuff][clu.testing.utils])
81
+ and ignore the rest. Or just the [`exporter`][clu.exporting], or just the [`predicates`][clu.predicates]
82
+ collection. Naturally, these things taste great and also taste great together, too.
83
+
84
+ [![Construx and Capsela](scratch/images/construx-and-capsela-small.jpg)](https://www.reddit.com/r/Xennials/comments/1aixaq7/construx_and_capsela_anyone_else_have_any/)
85
+
86
+ CLU started out as a packaged-up and sanely written version of
87
+ [the Python tools I wrote for my REPLs][homage-replutilities-link], divided up into
88
+ a bunch of subordinate packages. It’s grown magnificently since then (if I do say so myself).
89
+ And if you are wondering if “CLU” is a Tron reference, [you are correct][clu-tron-link].
90
+ “CLU” stands for “Common Lightweight Utilities” – it started out as an acronym for
91
+ “Command-Line Utilities” but it has grown useful beyond that scope, indeed.
92
+
93
+ The subordinate packages are pretty well-divided: [`clu.config`][clu.config] contains
94
+ things to help with configuration, like [config-file loading and saving][clu.config.filebase],
95
+ and data structures like [our famous namespaced keymaps][clu.config.keymap].
96
+ [`clu.exporting`][clu.exporting] has the `@export` decorator, a utility to easily label module
97
+ members for export by adding them to a modules’ `__all__` and `__dir__` members,
98
+ plus other stuff like real-name determination. Which, speaking of which, [`clu.naming`][clu.naming]
99
+ has additional easy functions for dealing with the names of your things and other peoples’,
100
+ and [`clu.repr`][clu.repr] has stuff for easily printing, getting, and specifying an objects’
101
+ string representation.
102
+
103
+ You’ll like [`clu.abstract`][clu.abstract] if you like building class towers – we have ABCs
104
+ for all types of things. If you like [`dict`s][dicts], check out the aforementioned [`clu.config.keymap`][clu.config.keymap]
105
+ and [`clu.dicts`][clu.dicts] modules – you’ll find things to build dictionary types, represent
106
+ them, and deal with them later. [`clu.dispatch`][clu.dispatch] will help you manage
107
+ subprocesses easily, [`clu.version`][clu.version] is better then [`semver`][semver-link]
108
+ (I promise), [`clu.testing`][clu.testing] is great for inlining some quick unit tests, and
109
+ [`clu.scripts`][clu.scripts] and [`clu.repl`][clu.repl] are what you want for whatever your
110
+ REPL environment may be… [`bpython`][bpython-link], [`ipython`][ipython-link],
111
+ [`ptpython`][ptpython-link], and many others I am sure!
112
+
113
+ So do have a look around. Here’s an abridged breakdown of some things within:
114
+
115
+ * [`config`][clu.config]: Tons of useful things for dealing with your app’s configuration. These are centered
116
+ around lexically namespaced dictionaries called “KeyMaps”, which basic examples of which can be
117
+ found in [`clu.config.keymap`][clu.config.keymap]. If your nested data looks like:
118
+
119
+ data = {
120
+ 'yo' : {
121
+ 'dogg' : {
122
+ 'i-heard' : {
123
+ 'you-like' : "nested data"
124
+ }
125
+ }
126
+ }
127
+ }
128
+
129
+ … and you assign it to a keymap, like e.g. `keyed = keymap.Nested(data).flatten()`, then you can
130
+ use `keyed` like so:
131
+
132
+ assert keyed["yo:dogg:i-heard:you-like"] == "nested data"
133
+
134
+ … The `Flat` and `Nested` classes are cheap to construct and lightweight, and generally act like most
135
+ [`dict`][dicts] instances in most of the expected ways. There is also an environment-variable [`keymap`][clu.config.keymap]
136
+ adapter in [`clu.config.env`][clu.config.env], which if your app uses environment variables that look like like
137
+ `MYAPP_CONFIG_THINGY`, they can be accessed through `env.FrozenEnviron(appname='myapp')` or
138
+ `env.Environ(appname='myapp')` like so:
139
+
140
+ appenv = Environ(appname='myapp')
141
+ assert appenv['config:thingy'] == "some value"
142
+ appenv['config:doohickey'] = "a different value" # sets MYAPP_CONFIG_DOOHICKEY
143
+ # in the current env
144
+
145
+ … and there are plenty of tools for rolling your own `KeyMap`s in [`clu.config`][clu.config]: the
146
+ [`proxy`][clu.config.proxy] subpackage has a `KeyMap` proxy class, [`ns`][clu.config.ns] has utility functions
147
+ for manipulating namespace strings, [`keymapview`][clu.config.keymapview] has a class tower for
148
+ [`KeyMap`][clu.config.keymap] key/value/item views, and [`abc`][clu.config.abc] has, as you’d expect, all
149
+ the abstract base classes upon which our [`KeyMap`s][clu.config.keymap] are built, for your perusal and
150
+ eventual enjoyment.
151
+
152
+ * [`constants`][clu.constants]: Definitions of [useful constants][clu.constants.consts], as well as
153
+ [polyfills][clu.constants.polyfills] to allow certain dependencies from the Python standard library to work even
154
+ when some of their moving parts are missing (i.e. Ye Olde Pythone 2.7, various PyPy implementations, etc).
155
+
156
+ * [`fs`][clu.fs]: Filesystem-related things. Submodules include:
157
+
158
+ * [`fs.filesystem`][clu.fs.filesystem]: classes representing filesystem primitives like `Directory`,
159
+ `TemporaryDirectory`, `TemporaryName`; a version of [`tempfile.NamedTemporaryFile`][tempfile.NamedTemporaryFile]
160
+ that works with or without the leading dot in the provided suffix (a peeve of mine); functions
161
+ for common filesystem operations like `which(…)`, `back_ticks(…)`, `rm_rf(…)` (be careful
162
+ with that one), and so forth.
163
+
164
+ * The `Directory` class is particularly extensive, with methods for [Zipfile][zipfile] archiving, searching
165
+ for importable Python files and others, file-suffix histograms, context-managed working-directory
166
+ management, walking and reverse-walking, and much more.
167
+
168
+ * [`fs.appdirectories`][clu.fs.appdirectories]: Started out as a pretty much wholesale duplication of the popular
169
+ [`appdirs`][appdirs-link] package[<sup>†</sup>](#dagger) – but it’s been kitted out with many CLUish things, e.g.
170
+ [`clu.fs.filesystem.Directory`][clu.fs.filesystem] instances. A solid upgrade in my opinion!
171
+
172
+ * [`fs.misc`][clu.fs.misc]: a bunch of useful miscellany – noteworthy standouts include regex utility functions for
173
+ constructing filename regex match or exclusion tests.
174
+
175
+ * [`fs.pypath`][clu.fs.pypath]: functions for safe manipulation of [`sys.path`][sys.path] – `enhance(…)`,
176
+ `remove_paths(…)`, `remove_invalid_paths()`, &c.
177
+
178
+ * [`importing`][clu.importing]: a whole class-based-module system! Basically you can do this:
179
+
180
+ class Derived(clu.importing.base.Module):
181
+
182
+ """ I heard you like docstrings """
183
+
184
+ yo = 'dogg'
185
+
186
+ @export
187
+ def yodogg(self):
188
+ return "I heard you like"
189
+
190
+ @export
191
+ def nodogg(self):
192
+ return None
193
+
194
+ export(yo, name='yo')
195
+
196
+ from clu.app import Derived as derived # TAKE NOTE!!!
197
+
198
+ assert isinstance(derived, Module)
199
+ assert derived.yo == 'dogg'
200
+ assert derived.yodogg() == "I heard you like"
201
+ assert derived.nodogg() is None
202
+
203
+ … see that? just by subclassing [`clu.importing.base.Module`][clu.importing.base] you can create something
204
+ instantly importable. Awesome, wouldn’t you say? I would say. We’re working out the best way to create the
205
+ base `Module` for your own project (the machinery is there but the semantics are not yet perfect) but do feel
206
+ free to play around with the stuff in [`clu.importing.base`][clu.importing.base], and have a look at the
207
+ implementation in [`clu.importing.proxy`][clu.importing.proxy] of the “parameterized” `ProxyModule` (there’s a
208
+ `ChainModuleMap` container available in the [`proxy`][clu.importing.proxy] submodule, too).
209
+
210
+ * [`repl`][clu.repl] and [`scripts`][clu.scripts]: Tools useful in Python REPL environments. In [`clu.repl`][clu.repl],
211
+ there’s a while module full of ANSI printing and formatting utilities, many of them as classes, a [`columnize`][clu.repl.columnize]
212
+ function for, uh, printing things in columns[<sup>†</sup>](#dagger), and a [`modules`][clu.repl.modules] submodule
213
+ focused on printing things about your project’s modules and submodules.
214
+
215
+ [`clu.scripts`][clu.scripts] contains a [“repl.py”][clu.scripts.repl] file, which is meant to be loaded into an interactive interpreter like e.g.:
216
+
217
+ $ bpython -i «PATH_TO_CLU»/clu/scripts/repl.py
218
+
219
+ … which will set all of CLU up for you to use interactively. N.B. if you have your own script you want to include
220
+ but stil want to use CLU, you can set the `CLU_USER_SCRIPT` environment variable to the path to your own script,
221
+ and our “repl.py” script will pick it up.
222
+
223
+ [`clu.scripts`][clu.scripts] also contains [`treeline`][clu.scripts.treeline] and [`dictroast`][clu.scripts.dictroast], which
224
+ are CLU’s nascent command-line parsing utilities. They make use of the CLU `KeyMap` idiom (q.v. note _supra_)
225
+ and are being worked on right this very µsecond!
226
+
227
+ * [`typespace`][clu.typespace]: Contains a submodule `typespace.namespace` defining `SimpleNamespace` (á la Python 3’s
228
+ [`types.SimpleNamespace`][types.SimpleNamespace]) and a slightly more useful `Namespace` ancestor class;
229
+ these are used to furnish a `typespace.types` namespace that contains everything in the standard-library
230
+ [`types`][types] module, but with all the typenames shortened so they no longer gratuitously end in “Type”. Like e.g.
231
+ [`types.ModuleType`][types.ModuleType] is to be found in `typespace.types.Module`, [`types.FunctionType`][types.FunctionType]
232
+ is `typespace.types.Function`, et cetera, ad nauseum, so you can just do `from clu.typespace import types`
233
+ to lose the redundant “Type” naming suffix – which I don’t know about you but that annoys me, I mean we all know
234
+ that these things are types because they are in the fucking [`types`][types] module and don’t need those overly verbose extra four characters
235
+ there at the end. ALSO, there are additional useful types, from Python’s standard library and common packages,
236
+ in the [`types` namespace][clu.typespace.namespace]. YOU’RE WELCOME!!
237
+
238
+ * [`dicts`][clu.dicts]: Functions and classes for wrangling [`dict`s][dicts] (and actually [`Mapping`][collections.abc.Mapping]
239
+ and [`MutableMapping`][collections.abc.MutableMapping] descendants in general). There are ABCs for
240
+ key/value/item views for your own mappings, a much better `ChainMap`, written from scratch and improving
241
+ on [`collections.ChainMap`][collections.ChainMap], plus a `ChainRepr` based on [`reprlib.Repr`][reprlib.Repr],
242
+ and a whole bunch of fast dict-merging functions.
243
+
244
+ * [`exporting`][clu.exporting]: This is kind of the heart of CLU. At the beginning of all internal CLU modules, you’ll find something
245
+ using the `Exporter`, like this:
246
+
247
+ from clu.exporting import Exporter
248
+
249
+ exporter = Exporter(path=__file__)
250
+ export = exporter.decorator()
251
+
252
+ … which I know, I know, the use of `__file__` there is kind of irritating. But that `exporter` instance is now
253
+ registered with CLU, and whenever there’s a class or function you want made available outside the module,
254
+ you can specify it like:
255
+
256
+ @export
257
+ def public_function():
258
+ print("I’m so public")
259
+
260
+ class PrivateAncestor:
261
+ """ I’m more private, don’t play with me """
262
+
263
+ @export
264
+ class PublicThing(PrivateAncestor):
265
+ """ I’m very public, indeed, and available """
266
+
267
+ At the end of the module (but before your CLU tests, q.v. note _sub_.) you put:
268
+
269
+ __all__, __dir__ = exporter.all_and_dir()
270
+
271
+ … which makes things clear what is public and what is private to consumers of your code, without messing
272
+ around with underscore prefixes, which I find coarse, and vulgar. You’re not just labeling things for export,
273
+ though: [`clu.exporting`][clu.exporting] has tons of machinery for finding out the **“true name”** of a thing,
274
+ be it a class (easy), a function (trickier but still easy), an instance (trickier still), and a module variable (totally
275
+ very tricky indeed).
276
+
277
+ For your own project, at some part in your code, all you have to do is: `from clu.exporting import ExporterBase`,
278
+ and then subclass `ExporterBase` with your app’s name and base path. Like so:
279
+
280
+ class Exporter(ExporterBase, basepath="/your/project", appname="MyProject"):
281
+ pass
282
+
283
+ … then import your own importer (or call it whatever you want) at the top of your own CLUish modules and
284
+ instantiate per the example _supra_. See also [`clu.scripts.dictroast`][clu.scripts.dictroast] for other tricks your
285
+ `Exporter` instances can perform.
286
+
287
+ * [`testing`][clu.testing]: a handy inline unit-test writing setup. It works fine with [`coverage`][coverage-link] and
288
+ [`pytest`][pytest-link] – all you have to do is, after your line assigning `__all__` and `__dir__` at the end
289
+ of the module proper, something like:
290
+
291
+ def test():
292
+ from clu.testing.utils import inline
293
+
294
+ @inline.precheck
295
+ def before_everything_else():
296
+ """ This function runs once before testing """
297
+ # ...
298
+
299
+ @inline
300
+ def first_test():
301
+ """ This test does one thing """
302
+ # ...
303
+
304
+ @inline
305
+ def second_test():
306
+ """ This test does another thing """
307
+ # ...
308
+
309
+ @inline.runif(something == something_else)
310
+ def test_conditionally_run():
311
+ """ This test only does something if `something` == `something_else` """
312
+ # ...
313
+
314
+ @inline.diagnostic
315
+ def apres_testing():
316
+ """ This function runs once after testing """
317
+ # ...
318
+
319
+ return inline.test(100)
320
+
321
+ if __name__ == '__main__':
322
+ sys.exit(test())
323
+
324
+ … running the module (with either `python -m yourapp.yourmodule` or, say, [Nox][nox-link]) will show
325
+ you each tests’ output. But see that `return inline.test(100)` line? That integer argument tells
326
+ the CLU testrunner how many times to run each test (we here like to go a hundred times). You’ll get a
327
+ report – each test function only prints its output on the first run, the other 99 in this case are muted –
328
+ that shows you the time totals, which will look like this:
329
+
330
+ [![CLU testrunner time totals](scratch/images/clu-testing-time-totals-example-small.jpg)](https://github.com/fish2000/CLU/tree/master/scratch/images/clu-testing-time-totals-example.jpg)
331
+
332
+ … which the astute will note is the output from a non-CLU module. [`clu.testing.utils`][clu.testing.utils]
333
+ is very easy to integrate, as it doesn’t require any other part of CLU. Look over [our noxfile][clu-noxfile] for
334
+ examples of how to run your inline tests as part of a larger suite.
335
+
336
+ … there are other testing support tools in[ `clu.testing.utils`][clu.testing.utils], have a look. There’s
337
+ also a [`clu.testing.pytest`][clu.testing.pytest] submodule, with some currently-under-development
338
+ [`pytest`][pytest-link] plugins.
339
+
340
+ * [`mathematics`][clu.mathematics]: the future home for math-related stuff. All there is right now is a `clamp(…)` function that works with
341
+ [`numpy`][numpy-link] [dtypes][numpy-dtype-link].
342
+
343
+ * [`naming`][clu.naming]: functions for determining the names of things (even module constants and other random things
344
+ that generally lack things like `__name__` attributes) and for the importing and exporting of things by
345
+ “qualified names” – for instance, you can use `naming.qualified_import(…)` to import a class [`CurveSet`][instakit.processors.curves.CurveSet]
346
+ from its package [`instakit.processors.curves`][instakit.processors.curves] by doing:
347
+
348
+ CurveSet = qualified_import('instakit.processors.curves.CurveSet')
349
+
350
+ … which that may be handier for you than composing and hard-coding an `import` statement. See also the
351
+ `nameof(…)` and `moduleof(…)` functions, and the utility functions (e.g. `qualified_name(…)`) and
352
+ predicates (e.g. `isnative(…)`). Most of these functions take literally anything for their argument.
353
+
354
+ * [`predicates`][clu.predicates]: If [`clu.exporting`][clu.exporting] is the heart, [`clu.predicates`][clu.predicates] is
355
+ all of the eyes, ears, fingers and toes of CLU.
356
+
357
+ * Do you want to know if a class is a metaclass? We have an `ismetaclass(…)` predicate for it, for example.
358
+ * Do you want to get an attribute from something you have, but not sure which attributes this _something_
359
+ may have (due to versioning or being passed around, or whatever)? `attr(thing, 'one', 'two', default=None)`
360
+ will give you `thing.one` if that exists, `thing.two`, if `thing.one` doesn’t, and `None` if neither of them
361
+ are there.
362
+ * But… would you maybe like to get a tuple with all of the `one` attributes across multiple things?
363
+ `attr_across('one', *things)` will do exactly that.
364
+ * Similar to the above, `pyattr(…)` does like `attr(…)` except `one` will be expanded to `__one__`, and
365
+ `item(…)` searches over mapping keys rather than attribute names.
366
+
367
+ Sweet, right? These functions, and others in the [`predicates`][clu.predicates] module, are based on `accessor`,
368
+ `aquirer`, `searcher`, and `collator` – abstract functions that can themselves be used. In fact most of
369
+ [`clu.predicates`][clu.predicates] is written in the functional style – that is to say they are built successively
370
+ out of multiple `lambda` statements. If this is not your taste, everything there has been documented thoroughly
371
+ for your use and you shouldn’t have to program in this style. But… if you _do_ enjoy a spot of FP, the primitives
372
+ in the module perhaps will interest you more than the more utilitarian contents.
373
+
374
+ * [`sanitizer`][clu.sanitizer]: functions for cleaning up unicode. Right now there is just a list-based `sanitize(…)`
375
+ function that tones down anything with high-value code points to the point where it can be safely `ascii`-ified.
376
+
377
+ * [`typology`][clu.typology]: This is like [`clu.predicates`][clu.predicates] but with more predicates, many of which are
378
+ based on typelists. The module is full of typelists and it uses them extensively in its predicates, via `isinstance(…)`,
379
+ `issubclass(…)` and a custom version of same called `subclasscheck(…)` which tries very hard to work with
380
+ what you give it (instead of just crapping out with a `False` return value). You will want to explore this one!
381
+
382
+ * [`version`][clu.version]: This is basically my take on the [`semver`][semver-link] package, only with improvements.
383
+ I originally developed it for internal use in some of my Python projects, but it stands on its own. You can
384
+ construct [`clu.version.VersionInfo`][clu.version.VersionInfo] instances using [`semver`][semver-link]
385
+ primitives amongst other things. The (skeletal) [`git_version`][clu.version.git_version] subpackage has a
386
+ couple of [Git-related][git-link] functions, but what you really want is in [`read_version`][clu.version.read_version]
387
+ – therein you’ll find a `read_version_file(…)` function that uses the `ast` module to read one of those
388
+ `__version__.py` files I know you have lying around. Yes![<sup>†</sup>](#dagger)
389
+
390
+ * [The `pytest` testsuite][clu-testsuite]: CLU has a full set of [`pytest`][pytest-link]-compatible unit tests.
391
+ In addition to copious module-specific [CLU inline tests][clu.testing], you can run this test suite using
392
+ [`pytest`][pytest-link] – or, if you’d like to run *all* the tests, use the fantastic [Nox][nox-link] testrunner
393
+ (which we use) along with [our included noxfile][clu-noxfile].
394
+
395
+ … AND MORE!!! There really are a ton of useful things in here and one day I will list them (but not today).
396
+ Have fun with it!! [Download][download-link] CLU today and explore – if you want a full list of everything CLU
397
+ exports, install it and list them all in your terminal:
398
+
399
+ $ pip install -U python-clu
400
+ $ python -m clu
401
+
402
+ … which will give you a giant list that looks like this:
403
+
404
+ [![CLU module list](scratch/images/clu-module-list-example-small.jpg)](https://pypi.org/project/python-clu/)
405
+
406
+ <a name="dagger" style="text-decoration: none;">†</a> – the original code for some modules in CLU (e.g.
407
+ [`clu.fs.appdirectories`][clu.fs.appdirectories], [`clu.repl.columnize`][clu.repl.columnize],
408
+ [`clu.version.read_version`][clu.version.read_version]) was vendored in from third-party code.
409
+ This has all been appropriately licensed and credits are inlined where due. Thanks to all CLU
410
+ contributors, big and small!
411
+
412
+ <!--- LINKS! LINKS! LINKS! -->
413
+ [pypi-link]: https://pypi.org/project/python-clu/
414
+ [download-link]: https://files.pythonhosted.org/packages/3e/af/4b0dfabe816cee7802cf6981f7f79770c4f05f8df4ac64fc6984789baaaa/python_clu-0.12.3.tar.gz
415
+ [homage-replutilities-link]: https://github.com/fish2000/homage/blob/master/.script-bin/replutilities.py
416
+ [clu-tron-link]: https://tron.fandom.com/wiki/Clu
417
+
418
+ [appdirs-link]: https://github.com/ActiveState/appdirs
419
+ [coverage-link]: https://coverage.readthedocs.io/en/latest/
420
+ [git-link]: https://git-scm.com
421
+ [numpy-link]: https://numpy.org
422
+ [numpy-dtype-link]: https://numpy.org/doc/stable/user/basics.types.html
423
+ [bpython-link]: https://bpython-interpreter.org
424
+ [ipython-link]: https://ipython.org
425
+ [ptpython-link]: https://github.com/prompt-toolkit/ptpython
426
+ [semver-link]: https://pypi.org/project/semver/
427
+ [pytest-link]: https://docs.pytest.org/en/stable/
428
+ [nox-link]: https://nox.thea.codes/en/stable/
429
+ [lego-link]: https://www.lego.com/
430
+ [capsela-link]: https://hackaday.com/2017/09/15/retrotectactular-capsela-is-dead-long-live-capsela/
431
+ [robotix-link]: https://en.wikipedia.org/wiki/Robotix
432
+
433
+ [clu.config]: https://github.com/fish2000/CLU/tree/master/clu/config
434
+ [clu.config.abc]: https://github.com/fish2000/CLU/tree/master/clu/config/abc.py
435
+ [clu.config.env]: https://github.com/fish2000/CLU/tree/master/clu/config/env.py
436
+ [clu.config.filebase]: https://github.com/fish2000/CLU/tree/master/clu/config/filebase.py
437
+ [clu.config.keymap]: https://github.com/fish2000/CLU/tree/master/clu/config/keymap.py
438
+ [clu.config.keymapview]: https://github.com/fish2000/CLU/tree/master/clu/config/keymapview.py
439
+ [clu.config.ns]: https://github.com/fish2000/CLU/tree/master/clu/config/ns.py
440
+ [clu.config.proxy]: https://github.com/fish2000/CLU/tree/master/clu/config/proxy.py
441
+
442
+ [clu.constants]: https://github.com/fish2000/CLU/tree/master/clu/constants
443
+ [clu.constants.consts]: https://github.com/fish2000/CLU/tree/master/clu/constants/consts.py
444
+ [clu.constants.polyfills]: https://github.com/fish2000/CLU/tree/master/clu/constants/polyfills.py
445
+
446
+ [clu.fs]: https://github.com/fish2000/CLU/tree/master/clu/fs
447
+ [clu.fs.abc]: https://github.com/fish2000/CLU/tree/master/clu/fs/abc.py
448
+ [clu.fs.appdirectories]: https://github.com/fish2000/CLU/tree/master/clu/fs/appdirectories.py
449
+ [clu.fs.filesystem]: https://github.com/fish2000/CLU/tree/master/clu/fs/filesystem.py
450
+ [clu.fs.misc]: https://github.com/fish2000/CLU/tree/master/clu/fs/misc.py
451
+ [clu.fs.pypath]: https://github.com/fish2000/CLU/tree/master/clu/fs/pypath.py
452
+
453
+ [clu.importing]: https://github.com/fish2000/CLU/tree/master/clu/importing
454
+ [clu.importing.base]: https://github.com/fish2000/CLU/tree/master/clu/importing/base.py
455
+ [clu.importing.proxy]: https://github.com/fish2000/CLU/tree/master/clu/importing/proxy.py
456
+
457
+ [clu.repl]: https://github.com/fish2000/CLU/tree/master/clu/repl
458
+ [clu.repl.ansi]: https://github.com/fish2000/CLU/tree/master/clu/repl/ansi.py
459
+ [clu.repl.banners]: https://github.com/fish2000/CLU/tree/master/clu/repl/banners.py
460
+ [clu.repl.columnize]: https://github.com/fish2000/CLU/tree/master/clu/repl/columnize.py
461
+ [clu.repl.modules]: https://github.com/fish2000/CLU/tree/master/clu/repl/modules.py
462
+
463
+ [clu.scripts]: https://github.com/fish2000/CLU/tree/master/clu/scripts
464
+ [clu.scripts.dictroast]: https://github.com/fish2000/CLU/tree/master/clu/scripts/dictroast.py
465
+ [clu.scripts.repl]: https://github.com/fish2000/CLU/tree/master/clu/scripts/repl.py
466
+ [clu.scripts.treeline]: https://github.com/fish2000/CLU/tree/master/clu/scripts/treeline.py
467
+
468
+ [clu.testing]: https://github.com/fish2000/CLU/tree/master/clu/testing
469
+ [clu.testing.pytest]: https://github.com/fish2000/CLU/tree/master/clu/testing/pytest.py
470
+ [clu.testing.utils]: https://github.com/fish2000/CLU/tree/master/clu/testing/utils.py
471
+
472
+ [clu.typespace]: https://github.com/fish2000/CLU/tree/master/clu/typespace
473
+ [clu.typespace.namespace]: https://github.com/fish2000/CLU/tree/master/clu/typespace/namespace.py
474
+
475
+ [clu.version]: https://github.com/fish2000/CLU/tree/master/clu/version
476
+ [clu.version.git_version]: https://github.com/fish2000/CLU/tree/master/clu/version/git_version.py
477
+ [clu.version.read_version]: https://github.com/fish2000/CLU/tree/master/clu/version/read_version.py
478
+ [clu.version.VersionInfo]: https://github.com/fish2000/CLU/blob/9f64200a947dbdcbf7eca44b87d0d9efeb4c6de7/clu/version/__init__.py#L100-L248
479
+
480
+ [clu]: https://github.com/fish2000/CLU
481
+ [clu-testsuite]: https://github.com/fish2000/CLU/tree/master/tests
482
+ [clu-noxfile]: https://github.com/fish2000/CLU/blob/master/noxfile.py
483
+
484
+ [clu.abstract]: https://github.com/fish2000/CLU/tree/master/clu/abstract.py
485
+ [clu.all]: https://github.com/fish2000/CLU/tree/master/clu/all.py
486
+ [clu.application]: https://github.com/fish2000/CLU/tree/master/clu/application.py
487
+ [clu.csv]: https://github.com/fish2000/CLU/tree/master/clu/csv.py
488
+ [clu.dicts]: https://github.com/fish2000/CLU/tree/master/clu/dicts.py
489
+ [clu.dispatch]: https://github.com/fish2000/CLU/tree/master/clu/dispatch.py
490
+ [clu.enums]: https://github.com/fish2000/CLU/tree/master/clu/enums.py
491
+ [clu.exporting]: https://github.com/fish2000/CLU/tree/master/clu/exporting.py
492
+ [clu.extending]: https://github.com/fish2000/CLU/tree/master/clu/extending.py
493
+ [clu.keyvalue]: https://github.com/fish2000/CLU/tree/master/clu/keyvalue.py
494
+ [clu.mathematics]: https://github.com/fish2000/CLU/tree/master/clu/mathematics.py
495
+ [clu.naming]: https://github.com/fish2000/CLU/tree/master/clu/naming.py
496
+ [clu.predicates]: https://github.com/fish2000/CLU/tree/master/clu/predicates.py
497
+ [clu.repr]: https://github.com/fish2000/CLU/tree/master/clu/repr.py
498
+ [clu.sanitizer]: https://github.com/fish2000/CLU/tree/master/clu/sanitizer.py
499
+ [clu.stdio]: https://github.com/fish2000/CLU/tree/master/clu/stdio.py
500
+ [clu.typology]: https://github.com/fish2000/CLU/tree/master/clu/typology.py
501
+
502
+ [instakit]: https://github.com/fish2000/instakit
503
+ [instakit.processors.curves]: https://github.com/fish2000/instakit/blob/master/instakit/processors/curves.py
504
+ [instakit.processors.curves.CurveSet]: https://github.com/fish2000/instakit/blob/ad5591c88176c2c997d86833b93dde017545277f/instakit/processors/curves.py#L109-L240
505
+ [collections.abc.Mapping]: https://docs.python.org/3/library/collections.abc.html#collections.abc.Mapping
506
+ [collections.abc.MutableMapping]: https://docs.python.org/3/library/collections.abc.html#collections.abc.MutableMapping
507
+ [collections.ChainMap]: https://docs.python.org/3/library/collections.html#chainmap-objects
508
+ [reprlib.Repr]: https://docs.python.org/3/library/reprlib.html#reprlib.Repr
509
+ [sys.path]: https://docs.python.org/3/library/sys_path_init.html
510
+ [tempfile.NamedTemporaryFIle]: https://docs.python.org/3/library/tempfile.html#tempfile.NamedTemporaryFile
511
+ [types]: https://docs.python.org/3/library/types.html
512
+ [types.ModuleType]: https://docs.python.org/3/library/types.html#types.ModuleType
513
+ [types.FunctionType]: https://docs.python.org/3/library/types.html#types.FunctionType
514
+ [types.SimpleNamespace]: https://docs.python.org/3/library/types.html#additional-utility-classes-and-functions
515
+ [zipfile]: https://docs.python.org/3/library/zipfile.html
516
+ [dicts]: https://docs.python.org/3/tutorial/datastructures.html#dictionaries
@@ -1,6 +1,6 @@
1
1
  clu/__init__.py,sha256=b8oH0ccvPZhHj6Hx9KmvQJu-Ic5MWj2PqUNyWgHPxsg,2106
2
2
  clu/__main__.py,sha256=ZLTfX6fCcimhzwZZVKaTk1LiLUtq2edMWAicGxWtKQA,4170
3
- clu/__version__.py,sha256=2NS09cZ7_4NXnNX87YIgda5W5KLDZGMrD7Y6C05_Uog,22
3
+ clu/__version__.py,sha256=7oJgOfmJcDNgC_fv9LP8UOoCR1zHDvn7WlirBOozdzQ,22
4
4
  clu/abstract.py,sha256=ZDn2zOug6S-CoVp5W3uruwbMvFfvtcvJ4iQpjivBBbo,14157
5
5
  clu/all.py,sha256=1Dhdufjubi4elC8x95lhevRUdwL_YsOdJC5Q2U5B-j0,3102
6
6
  clu/application.py,sha256=EqgTw2wMlvSx-dmSOcgJVPqu4jwzsP06egmvuzuyEmo,6062
@@ -66,7 +66,7 @@ clu/repl/modules.py,sha256=w2Cc-sN7Cjes7wO1resV03W-5gTmIgagYpwIPqShZRM,9424
66
66
  clu/repl/cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
67
67
  clu/repl/cli/boilerplate.py,sha256=eDBQhDuymS74KY8zDyCeuxcef1k1mOnS4r3Rs7lN95c,1081
68
68
  clu/repl/cli/boilerplate_copy.py,sha256=qDfjUq47vPfnf7LZv7gQ7jWZXJXo1jNY6ckZdrUILOw,521
69
- clu/repl/cli/print_version.py,sha256=ONS_LKfnQcrV37KDgK4WSxAZsSNow1WKf4bMliCMn-A,1181
69
+ clu/repl/cli/print_version.py,sha256=Bw2BQdeqx-vak0msTSU64rbrmTgFw6ZpGHD5DMesjbA,1485
70
70
  clu/scripts/.gitignore,sha256=EfdiMQTYFRqAtsEvRIS6N5FzZ0cYQ1TR-PXSOxHETFQ,23
71
71
  clu/scripts/README.md,sha256=g7DVn99jcVart0gjymIdXtdfI0_kHI371IpD_o8sHSs,1753
72
72
  clu/scripts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -74,7 +74,7 @@ clu/scripts/ansicolors.py,sha256=u0nJhEC1cHnjYihkxAlfs80drbyAa7YxdvDvl9mcG4E,262
74
74
  clu/scripts/boilerplate.py,sha256=sAn9LaCh0mZqRvI_lsSK8eDoRhHigR3MU87HLDStR2Q,727
75
75
  clu/scripts/dictroast.py,sha256=E4qNwTPLrbj2914NediV7LHzia9IM2flsCGtaLSTXg0,5583
76
76
  clu/scripts/prediversus.py,sha256=063qT-A7I4po_N9GpafQLAJxglphaJatQIDG2t6jw0s,5173
77
- clu/scripts/repl.py,sha256=YggHIw_tZPJxuR81hqYu8aH5mhq0ndJryWidBCZUkYQ,7666
77
+ clu/scripts/repl.py,sha256=7BeFXMDaQw1woGK3bl54fdgFV_E8ag0uH1_s7eIjcro,7685
78
78
  clu/scripts/treeline.py,sha256=kv7yvsNgO0GVY8gLRrbg4bTB1owXinwrV4otx-MGaYY,31427
79
79
  clu/scripts/legacy/forkumask.py,sha256=Q4atVqiX8ERNoe4rfv6qCU8RMlxbvAvsHn4p0g8uG5I,1847
80
80
  clu/scripts/legacy/repl-bpython.py,sha256=FqDi_3VL27qX8FK4pF2cI1i_9AsbYsIosJ2K8hOoPlQ,21120
@@ -97,11 +97,10 @@ clu/version/__init__.py,sha256=JPM3y55fTL5D9l0AzJ_2esPgLRWHSKqvV4NYwkGzbKE,8775
97
97
  clu/version/__main__.py,sha256=pFWGzpcVNQegMhB_I6xO3hvR3xIhlVnHYVJ54wvxSH8,268
98
98
  clu/version/git_version.py,sha256=snh4lHsY4EoFRH0bh--Htequw9eJSfRI2zueUG573gY,1745
99
99
  clu/version/read_version.py,sha256=_bBVNy48o5DWmvcDOawINeux2oSIQMFXBZJ9SQ5p4WQ,3879
100
- python_clu-0.12.2.dist-info/licenses/COPYING.md,sha256=llYAasj2CkLS5mcJ7eRisHzPx_EUig0iG-awvVW-gLg,1719
101
- python_clu-0.12.2.dist-info/licenses/LICENSE.txt,sha256=xxq-ZV5xvCrohv6DMqkvl9NCaMtFRtVqeOSMelulhdE,1828
102
- python_clu-0.12.2.dist-info/METADATA,sha256=0V2fJVKANrLxtfTLulDolsmbA6NAOGY70djjl0E3gWE,2690
103
- python_clu-0.12.2.dist-info/WHEEL,sha256=CmyFI0kx5cdEMTLiONQRbGQwjIoR1aIYB7eCAQ4KPJ0,91
104
- python_clu-0.12.2.dist-info/entry_points.txt,sha256=gHmvIG1rglS0xjrB9O1AC6SspAL8Vl5NTet-2oyce40,256
105
- python_clu-0.12.2.dist-info/top_level.txt,sha256=OKMcaFrtzEJat-RA3KEqUOiemjFjZRhBFOr6_QqL7gQ,4
106
- python_clu-0.12.2.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
107
- python_clu-0.12.2.dist-info/RECORD,,
100
+ python_clu-0.12.4.dist-info/licenses/LICENSE.txt,sha256=xxq-ZV5xvCrohv6DMqkvl9NCaMtFRtVqeOSMelulhdE,1828
101
+ python_clu-0.12.4.dist-info/METADATA,sha256=6qx1Hc8XWm9qTPNkG7RXx4WJYQxN0tmYNDq-yuxEdpk,31689
102
+ python_clu-0.12.4.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
103
+ python_clu-0.12.4.dist-info/entry_points.txt,sha256=gHmvIG1rglS0xjrB9O1AC6SspAL8Vl5NTet-2oyce40,256
104
+ python_clu-0.12.4.dist-info/top_level.txt,sha256=OKMcaFrtzEJat-RA3KEqUOiemjFjZRhBFOr6_QqL7gQ,4
105
+ python_clu-0.12.4.dist-info/zip-safe,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
106
+ python_clu-0.12.4.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (78.1.0)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -1,73 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: python-clu
3
- Version: 0.12.2
4
- Summary: CLU - Common Lightweight Utilities, or Command-Line Utilities (your pick)
5
- Home-page: https://github.com/fish2000/clu
6
- Download-URL: https://github.com/fish2000/clu/zipball/master
7
- Author: Alexander Böhn
8
- Author-email: fish2000@gmail.com
9
- License: MIT
10
- Keywords: command utilities clu fish2000 command-line modules predicates REPL tools
11
- Platform: any
12
- Classifier: Development Status :: 5 - Production/Stable
13
- Classifier: Framework :: Pytest
14
- Classifier: Intended Audience :: Developers
15
- Classifier: Topic :: Software Development
16
- Classifier: Topic :: Software Development :: Testing
17
- Classifier: Topic :: Utilities
18
- Classifier: Operating System :: MacOS
19
- Classifier: Operating System :: Microsoft :: Windows
20
- Classifier: Operating System :: OS Independent
21
- Classifier: Operating System :: POSIX
22
- Classifier: Operating System :: Unix
23
- Classifier: Programming Language :: Python
24
- Classifier: Programming Language :: Python :: 3
25
- Classifier: Programming Language :: Python :: 3.10
26
- Classifier: Programming Language :: Python :: Implementation :: CPython
27
- Classifier: Programming Language :: Python :: Implementation :: PyPy
28
- Description-Content-Type: text/markdown
29
- License-File: LICENSE.txt
30
- License-File: COPYING.md
31
- Requires-Dist: Click>=7.0
32
- Requires-Dist: colorama>=0.4.0
33
- Requires-Dist: dataclasses>=0.6; python_version < "3.7"
34
- Requires-Dist: dbx-stopwatch>=1.6
35
- Requires-Dist: enum34>=1.1.0; python_version < "3.4"
36
- Requires-Dist: heapdict>=1.0.0
37
- Requires-Dist: humanize>=1.0.0
38
- Requires-Dist: importlib-metadata>=1.4.0; python_version < "3.8"
39
- Requires-Dist: mock>=4.0.0
40
- Requires-Dist: multidict>=4.7.0
41
- Requires-Dist: packaging
42
- Requires-Dist: pout>=0.8.13
43
- Requires-Dist: pygments>=2.0.0
44
- Requires-Dist: PyYAML>=5.3.0
45
- Requires-Dist: redis>=3.4.0
46
- Requires-Dist: setuptools>=30.0.0
47
- Requires-Dist: six>=1.10.0
48
- Requires-Dist: termcolor>=1.1.0
49
- Requires-Dist: toml>=0.10.0
50
- Requires-Dist: wheel>=0.34.0
51
- Requires-Dist: zict>=0.1.2
52
- Requires-Dist: zipp>=2.0.0
53
- Dynamic: author
54
- Dynamic: author-email
55
- Dynamic: classifier
56
- Dynamic: description
57
- Dynamic: description-content-type
58
- Dynamic: download-url
59
- Dynamic: home-page
60
- Dynamic: keywords
61
- Dynamic: license
62
- Dynamic: license-file
63
- Dynamic: platform
64
- Dynamic: requires-dist
65
- Dynamic: summary
66
-
67
- CLU – Common Lightweight Utilities (née Command-Line Utilities)
68
- ==================================================
69
-
70
- This is a packaged-up and sanely version-controlled version of [the Python tools I wrote for my REPLs](https://github.com/fish2000/homage/blob/master/.script-bin/replutilities.py), divided up into
71
- a bunch of subordinate packages.
72
-
73
- If you assumed that the project name was a Tron reference, you are in fact correct.
@@ -1,20 +0,0 @@
1
- Copyright © 2012-2019 Alexander Böhn <fish2000@gmail.com>; All rights reserved.
2
-
3
- Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
4
-
5
- 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
6
- 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
7
- 3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
8
- 4. All stipulations and conditions enumerated in the software license (q.v. “LICENSE.txt” file enclosure sub.) are additionally acknowleged and summarily reproduced verbatim according to Condition §2 supra.
9
-
10
- THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
11
- AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
12
- IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
13
- ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
14
- LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
15
- CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
16
- SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
17
- INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
18
- CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
19
- ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
20
- POSSIBILITY OF SUCH DAMAGE.