cs-sh 20260912.1__tar.gz

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.
@@ -0,0 +1,105 @@
1
+ Metadata-Version: 2.4
2
+ Name: cs-sh
3
+ Version: 20260912.1
4
+ Summary: Convenience functions for constructing shell commands.
5
+ Keywords: python2,python3
6
+ Author-email: Cameron Simpson <cs@cskk.id.au>
7
+ Description-Content-Type: text/markdown
8
+ Classifier: Programming Language :: Python
9
+ Classifier: Programming Language :: Python :: 2
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
+ Project-URL: MonoRepo Commits, https://bitbucket.org/cameron_simpson/css/commits/branch/main
17
+ Project-URL: Monorepo Git Mirror, https://github.com/cameron-simpson/css
18
+ Project-URL: Monorepo Hg/Mercurial Mirror, https://hg.sr.ht/~cameron-simpson/css
19
+ Project-URL: Source, https://github.com/cameron-simpson/css/blob/main/lib/python/cs/sh.py
20
+
21
+ Convenience functions for constructing shell commands.
22
+
23
+ *Latest release 20260912.1*:
24
+ Fix project specification.
25
+
26
+ Functions for safely constructing shell command lines from bare strings.
27
+ Somewhat like the inverse of the shlex stdlib module.
28
+
29
+ As of Python 3.3 the function `shlex.quote()` does what `quotestr()` does.
30
+
31
+ As of Python 3.8 the function `shlex.join()` does what `quoteargv()` does.
32
+
33
+
34
+
35
+ Short summary:
36
+
37
+
38
+ * `main_shqstr`: shqstr: emit shell-quoted form of the command line arguments.
39
+
40
+
41
+ * `quote`: Quote the supplied strings, return a list of the quoted strings.
42
+
43
+
44
+ * `quoteargv`: Quote strings, assemble into command string.
45
+
46
+
47
+ * `quotestr`: Quote a string for use on a shell command line.
48
+
49
+ # Functions
50
+
51
+ ## main_shqstr(argv=None)
52
+
53
+ shqstr: emit shell-quoted form of the command line arguments.
54
+
55
+ ## quote(args)
56
+
57
+ Quote the supplied strings, return a list of the quoted strings.
58
+
59
+ As of Python 3.8 the function `shlex.join()` probably does
60
+ what you would have done with the result of this function
61
+ i.e. join the resulting strings together.
62
+
63
+ ## quoteargv(argv)
64
+
65
+ Quote strings, assemble into command string.
66
+
67
+ ## quotestr(s)
68
+
69
+ Quote a string for use on a shell command line.
70
+
71
+ As of Python 3.3 the function `shlex.quote()` is available for this.
72
+
73
+ # Release Log
74
+
75
+
76
+
77
+ *Release 20260912.1*:
78
+ Fix project specification.
79
+
80
+ *Release 20260912*:
81
+ Rename quotecmd to quoteargv.
82
+
83
+ *Release 20210316*:
84
+ Minor doc update.
85
+
86
+ *Release 20180613*:
87
+ Rework quotestr significantly to provide somewhat friendlier quoting, include "," in the SAFECHARS.
88
+
89
+ *Release 20170903.2*:
90
+ bugfix __main__ boilerplate after setuptools workaround
91
+
92
+ *Release 20170903.1*:
93
+ workaround setuptool's slightly dumb console_scripts call of a "main" function
94
+
95
+ *Release 20170903*:
96
+ shqstr command; new quotecmd(argv) function
97
+
98
+ *Release 20150118*:
99
+ Extend SAFECHARS to include colon.
100
+
101
+ *Release 20150111*:
102
+ minor cleanup
103
+
104
+ *Release 20150107*:
105
+ initial standalone public release
@@ -0,0 +1,132 @@
1
+ [project]
2
+ name = "cs-sh"
3
+ description = "Convenience functions for constructing shell commands."
4
+ authors = [
5
+ { name = "Cameron Simpson", email = "cs@cskk.id.au" },
6
+ ]
7
+ keywords = [
8
+ "python2",
9
+ "python3",
10
+ ]
11
+ dependencies = []
12
+ classifiers = [
13
+ "Programming Language :: Python",
14
+ "Programming Language :: Python :: 2",
15
+ "Programming Language :: Python :: 3",
16
+ "Development Status :: 4 - Beta",
17
+ "Intended Audience :: Developers",
18
+ "Operating System :: OS Independent",
19
+ "Topic :: Software Development :: Libraries :: Python Modules",
20
+ "License :: OSI Approved :: GNU General Public License v3 or later (GPLv3+)",
21
+ ]
22
+ version = "20260912.1"
23
+
24
+ [project.license]
25
+ text = "GNU General Public License v3 or later (GPLv3+)"
26
+
27
+ [project.urls]
28
+ "Monorepo Hg/Mercurial Mirror" = "https://hg.sr.ht/~cameron-simpson/css"
29
+ "Monorepo Git Mirror" = "https://github.com/cameron-simpson/css"
30
+ "MonoRepo Commits" = "https://bitbucket.org/cameron_simpson/css/commits/branch/main"
31
+ Source = "https://github.com/cameron-simpson/css/blob/main/lib/python/cs/sh.py"
32
+
33
+ [project.scripts]
34
+ shqstr = "cs.sh:main_shqstr"
35
+
36
+ [project.readme]
37
+ text = """
38
+ Convenience functions for constructing shell commands.
39
+
40
+ *Latest release 20260912.1*:
41
+ Fix project specification.
42
+
43
+ Functions for safely constructing shell command lines from bare strings.
44
+ Somewhat like the inverse of the shlex stdlib module.
45
+
46
+ As of Python 3.3 the function `shlex.quote()` does what `quotestr()` does.
47
+
48
+ As of Python 3.8 the function `shlex.join()` does what `quoteargv()` does.
49
+
50
+
51
+
52
+ Short summary:
53
+
54
+
55
+ * `main_shqstr`: shqstr: emit shell-quoted form of the command line arguments.
56
+
57
+
58
+ * `quote`: Quote the supplied strings, return a list of the quoted strings.
59
+
60
+
61
+ * `quoteargv`: Quote strings, assemble into command string.
62
+
63
+
64
+ * `quotestr`: Quote a string for use on a shell command line.
65
+
66
+ # Functions
67
+
68
+ ## main_shqstr(argv=None)
69
+
70
+ shqstr: emit shell-quoted form of the command line arguments.
71
+
72
+ ## quote(args)
73
+
74
+ Quote the supplied strings, return a list of the quoted strings.
75
+
76
+ As of Python 3.8 the function `shlex.join()` probably does
77
+ what you would have done with the result of this function
78
+ i.e. join the resulting strings together.
79
+
80
+ ## quoteargv(argv)
81
+
82
+ Quote strings, assemble into command string.
83
+
84
+ ## quotestr(s)
85
+
86
+ Quote a string for use on a shell command line.
87
+
88
+ As of Python 3.3 the function `shlex.quote()` is available for this.
89
+
90
+ # Release Log
91
+
92
+
93
+
94
+ *Release 20260912.1*:
95
+ Fix project specification.
96
+
97
+ *Release 20260912*:
98
+ Rename quotecmd to quoteargv.
99
+
100
+ *Release 20210316*:
101
+ Minor doc update.
102
+
103
+ *Release 20180613*:
104
+ Rework quotestr significantly to provide somewhat friendlier quoting, include \",\" in the SAFECHARS.
105
+
106
+ *Release 20170903.2*:
107
+ bugfix __main__ boilerplate after setuptools workaround
108
+
109
+ *Release 20170903.1*:
110
+ workaround setuptool's slightly dumb console_scripts call of a \"main\" function
111
+
112
+ *Release 20170903*:
113
+ shqstr command; new quotecmd(argv) function
114
+
115
+ *Release 20150118*:
116
+ Extend SAFECHARS to include colon.
117
+
118
+ *Release 20150111*:
119
+ minor cleanup
120
+
121
+ *Release 20150107*:
122
+ initial standalone public release"""
123
+ content-type = "text/markdown"
124
+
125
+ [build-system]
126
+ build-backend = "flit_core.buildapi"
127
+ requires = [
128
+ "flit_core >=3.2,<4",
129
+ ]
130
+
131
+ [tool.flit.module]
132
+ name = "cs.sh"
@@ -0,0 +1,135 @@
1
+ #!/usr/bin/python
2
+ #
3
+
4
+ r'''
5
+ Convenience functions for constructing shell commands.
6
+
7
+ Functions for safely constructing shell command lines from bare strings.
8
+ Somewhat like the inverse of the shlex stdlib module.
9
+
10
+ As of Python 3.3 the function `shlex.quote()` does what `quotestr()` does.
11
+
12
+ As of Python 3.8 the function `shlex.join()` does what `quoteargv()` does.
13
+ '''
14
+
15
+ import string
16
+ import sys
17
+
18
+ __version__ = '20260912.1'
19
+
20
+ DISTINFO = {
21
+ 'description':
22
+ "Convenience functions for constructing shell commands.",
23
+ 'keywords': ["python2", "python3"],
24
+ 'classifiers': [
25
+ "Programming Language :: Python",
26
+ "Programming Language :: Python :: 2",
27
+ "Programming Language :: Python :: 3",
28
+ ],
29
+ 'install_requires': [],
30
+ 'entry_points': {
31
+ 'console_scripts': {
32
+ 'shqstr': 'cs.sh:main_shqstr'
33
+ },
34
+ },
35
+ }
36
+
37
+ # characters than do not need to be quoted
38
+ SAFECHARS = string.digits + string.ascii_letters + '-+_.,/:'
39
+
40
+ def quote(args):
41
+ ''' Quote the supplied strings, return a list of the quoted strings.
42
+
43
+ As of Python 3.8 the function `shlex.join()` probably does
44
+ what you would have done with the result of this function
45
+ i.e. join the resulting strings together.
46
+ '''
47
+ return [quotestr(s) for s in args]
48
+
49
+ def quotestr(s):
50
+ ''' Quote a string for use on a shell command line.
51
+
52
+ As of Python 3.3 the function `shlex.quote()` is available for this.
53
+ '''
54
+ # decide how to quote the string:
55
+ # - empty string: return ''
56
+ # - all safe: do not quote
57
+ # - no single quotes: just single quote the string
58
+ # - funky quoting
59
+ if not s:
60
+ return "''"
61
+ q_count = 0
62
+ unsafe_count = 0
63
+ switch_count = 0
64
+ safe = True
65
+ for c in s:
66
+ if c == "'":
67
+ q_count += 1
68
+ new_safe = False
69
+ elif c not in SAFECHARS:
70
+ unsafe_count += 1
71
+ new_safe = False
72
+ else:
73
+ new_safe = True
74
+ if safe ^ new_safe:
75
+ switch_count += 1
76
+ safe = new_safe
77
+ if q_count == 0 and unsafe_count == 0:
78
+ # all safe
79
+ return s
80
+ if q_count == 0:
81
+ # unsafe but no single quotes
82
+ return "'" + s + "'"
83
+
84
+ def flush():
85
+ ''' Output the pending characters, which are either all safe or all unsafe.
86
+ '''
87
+ if offset > start:
88
+ part = s[start:offset]
89
+ if not safe:
90
+ if len(part) == 1:
91
+ qparts.append("\\")
92
+ else:
93
+ qparts.append("'")
94
+ qparts.append(part)
95
+ if not safe:
96
+ if len(part) > 1:
97
+ qparts.append("'")
98
+
99
+ qparts = []
100
+ start = 0
101
+ safe = True # not in quotes
102
+ for offset, c in enumerate(s):
103
+ if c == "'" or (safe and c == '\\'):
104
+ flush()
105
+ qparts.append('\\')
106
+ qparts.append(c)
107
+ start = offset + 1 # do not include this character in the flushable set
108
+ new_safe = False
109
+ else:
110
+ new_safe = c in SAFECHARS
111
+ if safe ^ new_safe:
112
+ # mode change
113
+ flush()
114
+ start = offset
115
+ safe = new_safe
116
+ # advance past final position
117
+ offset += 1
118
+ flush()
119
+ return ''.join(qparts)
120
+
121
+ def quoteargv(argv):
122
+ ''' Quote strings, assemble into command string.
123
+ '''
124
+ return ' '.join(quote(argv))
125
+
126
+ def main_shqstr(argv=None):
127
+ ''' shqstr: emit shell-quoted form of the command line arguments.
128
+ '''
129
+ if argv is None:
130
+ argv = sys.argv
131
+ argv.pop(0)
132
+ print(quoteargv(argv))
133
+
134
+ if __name__ == '__main__':
135
+ sys.exit(main_shqstr())