argparse-from-file 1.0__tar.gz → 1.2__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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: argparse-from-file
3
- Version: 1.0
3
+ Version: 1.2
4
4
  Summary: Wrapper for Python's argparse to also read arguments from a file
5
5
  Author-email: Mark Blakeney <mark.blakeney@bullet-systems.net>
6
6
  License-Expression: GPL-3.0-or-later
@@ -86,7 +86,7 @@ Example `~/.config/myprog-flags.conf`:
86
86
 
87
87
  `argparse-from-file` automatically adds an `epilog` to the help message
88
88
  indicating the configuration file path. If you instead provide a custom `epilog`
89
- (or `usage` or `description`), you can embed the `#FROM_FILE_PATH#` placeholder,
89
+ (or `usage` or `description`), you can embed a `#FROM_FILE_PATH#` placeholder,
90
90
  and it will be replaced with the actual path used.
91
91
 
92
92
  ## Example
@@ -73,7 +73,7 @@ Example `~/.config/myprog-flags.conf`:
73
73
 
74
74
  `argparse-from-file` automatically adds an `epilog` to the help message
75
75
  indicating the configuration file path. If you instead provide a custom `epilog`
76
- (or `usage` or `description`), you can embed the `#FROM_FILE_PATH#` placeholder,
76
+ (or `usage` or `description`), you can embed a `#FROM_FILE_PATH#` placeholder,
77
77
  and it will be replaced with the actual path used.
78
78
 
79
79
  ## Example
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: argparse-from-file
3
- Version: 1.0
3
+ Version: 1.2
4
4
  Summary: Wrapper for Python's argparse to also read arguments from a file
5
5
  Author-email: Mark Blakeney <mark.blakeney@bullet-systems.net>
6
6
  License-Expression: GPL-3.0-or-later
@@ -86,7 +86,7 @@ Example `~/.config/myprog-flags.conf`:
86
86
 
87
87
  `argparse-from-file` automatically adds an `epilog` to the help message
88
88
  indicating the configuration file path. If you instead provide a custom `epilog`
89
- (or `usage` or `description`), you can embed the `#FROM_FILE_PATH#` placeholder,
89
+ (or `usage` or `description`), you can embed a `#FROM_FILE_PATH#` placeholder,
90
90
  and it will be replaced with the actual path used.
91
91
 
92
92
  ## Example
@@ -0,0 +1,96 @@
1
+ """
2
+ A very light wrapper around Python's argparse module to prepend a program's
3
+ argument list with default options and arguments read from a user configuration
4
+ file.
5
+ """
6
+
7
+ import argparse
8
+ import os
9
+ import shlex
10
+ import sys
11
+
12
+ import platformdirs
13
+
14
+ PLACEHOLDER = '#FROM_FILE_PATH#'
15
+
16
+
17
+ # Get program name. This function is copied (but very modified) from argparse 3.14.0
18
+ def _prog_name():
19
+ try:
20
+ modspec = sys.modules['__main__'].__spec__
21
+ except (KeyError, AttributeError):
22
+ # possibly PYTHONSTARTUP or -X presite or other weird edge case
23
+ # no good answer here, so fall back to the default
24
+ modspec = None
25
+
26
+ if not modspec or modspec.name == '__main__':
27
+ return os.path.basename(sys.argv[0])
28
+
29
+ return modspec.name.removesuffix('.__main__')
30
+
31
+
32
+ class ArgumentParser(argparse.ArgumentParser):
33
+ _top = True
34
+
35
+ def __init__(self, *args, **kwargs):
36
+ self._argv = []
37
+
38
+ # Only set up "from file" stuff once, for the top-level
39
+ if ArgumentParser._top:
40
+ ArgumentParser._top = False
41
+
42
+ # from_file = 'path-to/file': Use this as "from file" name/path. If
43
+ # relative then wrt platform specific user config dir.
44
+ # from_file = '': Do not use a "from file".
45
+ # from_file = None: Create default "from file" path.
46
+ if (from_file := kwargs.pop('from_file', None)) is None:
47
+ from_file = _prog_name() + '-flags.conf'
48
+
49
+ if from_file:
50
+ from_file_path = platformdirs.user_config_path(from_file)
51
+ from_file_path_str = str(from_file_path)
52
+ # epilog = 'text string': Set this as epilog, replacing any
53
+ # PLACEHOLDER with the above determined "from file" path.
54
+ # epilog = '': Do not set an epilog.
55
+ # epilog = None: create default epilog with "from file" path.
56
+ if (epilog := kwargs.pop('epilog', None)) is None:
57
+ epilog = f'Note you can set default starting options in {from_file_path_str}.'
58
+ else:
59
+ epilog = epilog.replace(PLACEHOLDER, from_file_path_str)
60
+
61
+ if epilog:
62
+ kwargs['epilog'] = epilog
63
+
64
+ # Also replace PLACEHOLDER in usage and description.
65
+ for kw in 'usage', 'description':
66
+ if v := kwargs.get(kw):
67
+ kwargs[kw] = v.replace(PLACEHOLDER, from_file_path_str)
68
+
69
+ # Create list of default args from user file.
70
+ if from_file_path.is_file():
71
+ with from_file_path.open() as fp:
72
+ self._argv.extend(
73
+ ln
74
+ for line in fp
75
+ if (ln := line.strip()) and not ln.startswith('#')
76
+ )
77
+ else:
78
+ from_file_path = None
79
+
80
+ self.from_file_path = from_file_path
81
+
82
+ return super().__init__(*args, **kwargs)
83
+
84
+ def parse_args(self, args=None, namespace=None): # type: ignore[override]
85
+ if args is None and self._argv:
86
+ # Combine args from file and command line, to be parsed
87
+ argstr = ' '.join(self._argv).strip()
88
+ args = shlex.split(argstr) + sys.argv[1:]
89
+ self._argv.clear()
90
+
91
+ return super().parse_args(args, namespace)
92
+
93
+
94
+ def __getattr__(name: str):
95
+ "Proxy all other attributes from argparse module."
96
+ return getattr(argparse, name)
@@ -37,5 +37,4 @@ version_scheme = "post-release"
37
37
  quote-style = "single"
38
38
  skip-magic-trailing-comma = true
39
39
 
40
-
41
40
  # vim:se sw=2:
@@ -1,72 +0,0 @@
1
- """
2
- A very light wrapper around Python's argparse module to prepend a program's
3
- argument list with default options and arguments read from a user configuration
4
- file.
5
- """
6
-
7
- import argparse
8
- import shlex
9
- import sys
10
- from pathlib import Path
11
-
12
- import platformdirs
13
-
14
-
15
- class ArgumentParser(argparse.ArgumentParser):
16
- def __init__(self, *args, **kwargs):
17
- self._argv = []
18
-
19
- # from_file = 'path-to/file': Use this as "from file" name/path. If
20
- # relative then wrt platform specific user config dir.
21
- # from_file = '': Do not use a "from file".
22
- # from_file = None: Create default "from file" path.
23
- if (from_file := kwargs.pop('from_file', None)) is None:
24
- from_file = Path(sys.argv[0]).stem + '-flags.conf'
25
-
26
- if from_file:
27
- from_file_path = platformdirs.user_config_path(from_file)
28
- from_file_path_str = str(from_file_path)
29
- # epilog = 'text string': Set this as epilog, replacing any
30
- # '#FROM_FILE_PATH#' with the above determined "from file" path.
31
- # epilog = '': Do not set an epilog.
32
- # epilog = None: create default epilog with "from file" path.
33
- if (epilog := kwargs.pop('epilog', None)) is None:
34
- epilog = f'Note you can set default starting options in {from_file_path_str}.'
35
- else:
36
- epilog = epilog.replace('#FROM_FILE_PATH#', from_file_path_str)
37
-
38
- if epilog:
39
- kwargs['epilog'] = epilog
40
-
41
- # Also replace any '#FROM_FILE_PATH#' in usage and description.
42
- for kw in 'usage', 'description':
43
- if v := kwargs.get(kw):
44
- kwargs[kw] = v.replace('#FROM_FILE_PATH#', from_file_path_str)
45
-
46
- # Create list of default args from user file.
47
- if from_file_path.is_file():
48
- with from_file_path.open() as fp:
49
- self._argv.extend(
50
- ln
51
- for line in fp
52
- if (ln := line.strip()) and not ln.startswith('#')
53
- )
54
- else:
55
- from_file_path = None
56
-
57
- self.from_file_path = from_file_path
58
- return super().__init__(*args, **kwargs)
59
-
60
- def parse_args(self, args=None, namespace=None): # type: ignore[override]
61
- if args is None and self._argv:
62
- # Combine args from file and command line, to be parsed
63
- argstr = ' '.join(self._argv).strip()
64
- args = shlex.split(argstr) + sys.argv[1:]
65
-
66
- del self._argv
67
- return super().parse_args(args, namespace)
68
-
69
-
70
- def __getattr__(name: str):
71
- "Proxy all other attributes from argparse module."
72
- return getattr(argparse, name)