log21 3.0.2__tar.gz → 3.1.0__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.
- {log21-3.0.2 → log21-3.1.0}/PKG-INFO +104 -21
- {log21-3.0.2 → log21-3.1.0}/README.md +103 -20
- {log21-3.0.2 → log21-3.1.0}/pyproject.toml +1 -1
- {log21-3.0.2 → log21-3.1.0}/src/log21/__init__.py +1 -1
- {log21-3.0.2 → log21-3.1.0}/src/log21/argumentify.py +28 -14
- {log21-3.0.2 → log21-3.1.0}/src/log21/_argparse.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/_module_helper.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/argparse.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/colors.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/crash_reporter/__init__.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/crash_reporter/formatters.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/crash_reporter/reporters.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/file_handler.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/formatters.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/levels.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/logger.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/logging_window.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/manager.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/pprint.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/progress_bar.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/stream_handler.py +0 -0
- {log21-3.0.2 → log21-3.1.0}/src/log21/tree_print.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.3
|
|
2
2
|
Name: log21
|
|
3
|
-
Version: 3.0
|
|
3
|
+
Version: 3.1.0
|
|
4
4
|
Summary: A simple logging package
|
|
5
5
|
Keywords: python,log,colorize,color,logging,Python3,CodeWriter21
|
|
6
6
|
Author: CodeWriter21(Mehrad Pooryoussof)
|
|
@@ -94,57 +94,140 @@ pip install git+https://github.com/MPCodeWriter21/log21
|
|
|
94
94
|
Changelog
|
|
95
95
|
---------
|
|
96
96
|
|
|
97
|
-
### v3.0
|
|
97
|
+
### v3.1.0
|
|
98
98
|
|
|
99
|
-
Change `argumentify`
|
|
100
|
-
|
|
99
|
+
Change the way `argumentify` handles function parameters to argument-parser arguments
|
|
100
|
+
conversion.
|
|
101
101
|
|
|
102
|
-
+
|
|
102
|
+
+ `POSITIONAL_ONLY` and `VAR_POSITIONAL` parameters will be positional arguments.
|
|
103
|
+
+ `POSITIONAL_OR_KEYWORD` and `KEYWORD_ONLY` parameters have flags assigned to them.
|
|
104
|
+
+ `POSITIONAL_OR_KEYWORD` parameters will be required if at least one `KEYWORD_ONLY`
|
|
105
|
+
parameter is there, otherwise they are optional.
|
|
106
|
+
+ `VAR_KEYWORD` parameters are still not supported.
|
|
103
107
|
|
|
104
|
-
|
|
105
|
-
def main(verbose: bool = False) -> None:
|
|
106
|
-
"""This is a very useful tool and I will describe it thoroughly. It is so good that
|
|
107
|
-
we have a second line in the first part of the description.
|
|
108
|
+
#### Example 1
|
|
108
109
|
|
|
109
|
-
|
|
110
|
+
```python
|
|
111
|
+
def main(path: Path, /, output: Path, *, verbose: bool = False):
|
|
112
|
+
"""Process a file.
|
|
110
113
|
|
|
111
|
-
:param
|
|
114
|
+
:param path: The input file path
|
|
115
|
+
:param output: The output file
|
|
116
|
+
:param verbose: Write more logs to the standard output.
|
|
112
117
|
"""
|
|
118
|
+
...
|
|
113
119
|
|
|
114
|
-
|
|
120
|
+
|
|
121
|
+
if __name__ == "__main__":
|
|
122
|
+
argumentify(main)
|
|
115
123
|
```
|
|
116
124
|
|
|
117
|
-
The
|
|
125
|
+
The help looks like this:
|
|
118
126
|
|
|
119
127
|
```help
|
|
120
|
-
usage: test.py [-h] [--verbose]
|
|
128
|
+
usage: test.py [-h] --output OUTPUT [--verbose] path
|
|
129
|
+
|
|
130
|
+
Process a file.
|
|
121
131
|
|
|
122
|
-
|
|
132
|
+
positional arguments:
|
|
133
|
+
path The input file path
|
|
123
134
|
|
|
124
135
|
options:
|
|
125
136
|
-h, --help
|
|
126
137
|
show this help message and exit
|
|
138
|
+
--output OUTPUT, -o OUTPUT
|
|
139
|
+
The output file
|
|
127
140
|
--verbose, -v
|
|
128
|
-
|
|
141
|
+
Write more logs to the standard output.
|
|
142
|
+
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
_Note that `path` and `output` are required._
|
|
146
|
+
|
|
147
|
+
#### Example 2
|
|
129
148
|
|
|
149
|
+
```python
|
|
150
|
+
def main(output: Path, /, *inputs: Path):
|
|
151
|
+
"""Process multiple files into one.
|
|
152
|
+
|
|
153
|
+
:param output: The output file
|
|
154
|
+
:param inputs: The path to the input files
|
|
155
|
+
"""
|
|
156
|
+
# Since `inputs` is a VAR_POSITIONAL, while being a positional argument, it can have
|
|
157
|
+
# zero length which is in many cases not intended.
|
|
158
|
+
# You might want to add a check for its length and raise an ArgumentError if it does
|
|
159
|
+
# not match your needs
|
|
160
|
+
|
|
161
|
+
# Check if at least one input has been passed and mark the argument as required
|
|
162
|
+
# if len(inputs) < 1:
|
|
163
|
+
# raise RequiredArgumentError("inputs")
|
|
164
|
+
|
|
165
|
+
# Raise an error unless at least two inputs are present
|
|
166
|
+
if len(inputs) < 2:
|
|
167
|
+
raise ArgumentError(message="You need to pass at least two files as input.")
|
|
168
|
+
...
|
|
130
169
|
```
|
|
131
170
|
|
|
132
|
-
|
|
171
|
+
The help looks like this:
|
|
133
172
|
|
|
134
173
|
```help
|
|
135
|
-
usage: test.py [-h] [
|
|
174
|
+
usage: test.py [-h] output [inputs ...]
|
|
175
|
+
|
|
176
|
+
Process multiple files into one.
|
|
136
177
|
|
|
137
|
-
|
|
138
|
-
|
|
178
|
+
positional arguments:
|
|
179
|
+
output The output file
|
|
180
|
+
inputs The path to the input files
|
|
139
181
|
|
|
140
182
|
options:
|
|
141
183
|
-h, --help
|
|
142
184
|
show this help message and exit
|
|
185
|
+
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
#### Example 3
|
|
189
|
+
|
|
190
|
+
```python
|
|
191
|
+
def main(first_name: str, last_name: str, output: Path, verbose: bool = False):
|
|
192
|
+
"""Write a greeting message.
|
|
193
|
+
|
|
194
|
+
:param first_name: The first name of the user to greet (optional)
|
|
195
|
+
:param last_name: The last name of the user to greet (optional)
|
|
196
|
+
:param output: The output file (stdout if none is provided)
|
|
197
|
+
:param verbose: If provided, will write the debug logs to stdout
|
|
198
|
+
"""
|
|
199
|
+
...
|
|
200
|
+
|
|
201
|
+
|
|
202
|
+
if __name__ == "__main__":
|
|
203
|
+
argumentify(main)
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
The help looks like this:
|
|
207
|
+
|
|
208
|
+
```help
|
|
209
|
+
usage: test.py [-h] [--first-name FIRST_NAME] [--last-name LAST_NAME] [--output OUTPUT]
|
|
210
|
+
[--verbose]
|
|
211
|
+
|
|
212
|
+
Write a greeting message.
|
|
213
|
+
|
|
214
|
+
options:
|
|
215
|
+
-h, --help
|
|
216
|
+
show this help message and exit
|
|
217
|
+
--first-name FIRST_NAME, -f FIRST_NAME
|
|
218
|
+
The first name of the user to greet (optional)
|
|
219
|
+
--last-name LAST_NAME, -l LAST_NAME
|
|
220
|
+
The last name of the user to greet (optional)
|
|
221
|
+
--output OUTPUT, -o OUTPUT
|
|
222
|
+
The output file (stdout if none is provided)
|
|
143
223
|
--verbose, -v
|
|
144
|
-
|
|
224
|
+
If provided, will write the debug logs to stdout
|
|
145
225
|
|
|
146
226
|
```
|
|
147
227
|
|
|
228
|
+
_Note that all the options are optional and default to None. `verbose` is False by
|
|
229
|
+
default since a default value is provided for it in function definition._
|
|
230
|
+
|
|
148
231
|
[Full CHANGELOG](https://github.com/MPCodeWriter21/log21/blob/master/CHANGELOG.md)
|
|
149
232
|
|
|
150
233
|
Usage Examples
|
|
@@ -69,57 +69,140 @@ pip install git+https://github.com/MPCodeWriter21/log21
|
|
|
69
69
|
Changelog
|
|
70
70
|
---------
|
|
71
71
|
|
|
72
|
-
### v3.0
|
|
72
|
+
### v3.1.0
|
|
73
73
|
|
|
74
|
-
Change `argumentify`
|
|
75
|
-
|
|
74
|
+
Change the way `argumentify` handles function parameters to argument-parser arguments
|
|
75
|
+
conversion.
|
|
76
76
|
|
|
77
|
-
+
|
|
77
|
+
+ `POSITIONAL_ONLY` and `VAR_POSITIONAL` parameters will be positional arguments.
|
|
78
|
+
+ `POSITIONAL_OR_KEYWORD` and `KEYWORD_ONLY` parameters have flags assigned to them.
|
|
79
|
+
+ `POSITIONAL_OR_KEYWORD` parameters will be required if at least one `KEYWORD_ONLY`
|
|
80
|
+
parameter is there, otherwise they are optional.
|
|
81
|
+
+ `VAR_KEYWORD` parameters are still not supported.
|
|
78
82
|
|
|
79
|
-
|
|
80
|
-
def main(verbose: bool = False) -> None:
|
|
81
|
-
"""This is a very useful tool and I will describe it thoroughly. It is so good that
|
|
82
|
-
we have a second line in the first part of the description.
|
|
83
|
+
#### Example 1
|
|
83
84
|
|
|
84
|
-
|
|
85
|
+
```python
|
|
86
|
+
def main(path: Path, /, output: Path, *, verbose: bool = False):
|
|
87
|
+
"""Process a file.
|
|
85
88
|
|
|
86
|
-
:param
|
|
89
|
+
:param path: The input file path
|
|
90
|
+
:param output: The output file
|
|
91
|
+
:param verbose: Write more logs to the standard output.
|
|
87
92
|
"""
|
|
93
|
+
...
|
|
88
94
|
|
|
89
|
-
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
argumentify(main)
|
|
90
98
|
```
|
|
91
99
|
|
|
92
|
-
The
|
|
100
|
+
The help looks like this:
|
|
93
101
|
|
|
94
102
|
```help
|
|
95
|
-
usage: test.py [-h] [--verbose]
|
|
103
|
+
usage: test.py [-h] --output OUTPUT [--verbose] path
|
|
104
|
+
|
|
105
|
+
Process a file.
|
|
96
106
|
|
|
97
|
-
|
|
107
|
+
positional arguments:
|
|
108
|
+
path The input file path
|
|
98
109
|
|
|
99
110
|
options:
|
|
100
111
|
-h, --help
|
|
101
112
|
show this help message and exit
|
|
113
|
+
--output OUTPUT, -o OUTPUT
|
|
114
|
+
The output file
|
|
102
115
|
--verbose, -v
|
|
103
|
-
|
|
116
|
+
Write more logs to the standard output.
|
|
117
|
+
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
_Note that `path` and `output` are required._
|
|
121
|
+
|
|
122
|
+
#### Example 2
|
|
104
123
|
|
|
124
|
+
```python
|
|
125
|
+
def main(output: Path, /, *inputs: Path):
|
|
126
|
+
"""Process multiple files into one.
|
|
127
|
+
|
|
128
|
+
:param output: The output file
|
|
129
|
+
:param inputs: The path to the input files
|
|
130
|
+
"""
|
|
131
|
+
# Since `inputs` is a VAR_POSITIONAL, while being a positional argument, it can have
|
|
132
|
+
# zero length which is in many cases not intended.
|
|
133
|
+
# You might want to add a check for its length and raise an ArgumentError if it does
|
|
134
|
+
# not match your needs
|
|
135
|
+
|
|
136
|
+
# Check if at least one input has been passed and mark the argument as required
|
|
137
|
+
# if len(inputs) < 1:
|
|
138
|
+
# raise RequiredArgumentError("inputs")
|
|
139
|
+
|
|
140
|
+
# Raise an error unless at least two inputs are present
|
|
141
|
+
if len(inputs) < 2:
|
|
142
|
+
raise ArgumentError(message="You need to pass at least two files as input.")
|
|
143
|
+
...
|
|
105
144
|
```
|
|
106
145
|
|
|
107
|
-
|
|
146
|
+
The help looks like this:
|
|
108
147
|
|
|
109
148
|
```help
|
|
110
|
-
usage: test.py [-h] [
|
|
149
|
+
usage: test.py [-h] output [inputs ...]
|
|
150
|
+
|
|
151
|
+
Process multiple files into one.
|
|
111
152
|
|
|
112
|
-
|
|
113
|
-
|
|
153
|
+
positional arguments:
|
|
154
|
+
output The output file
|
|
155
|
+
inputs The path to the input files
|
|
114
156
|
|
|
115
157
|
options:
|
|
116
158
|
-h, --help
|
|
117
159
|
show this help message and exit
|
|
160
|
+
|
|
161
|
+
```
|
|
162
|
+
|
|
163
|
+
#### Example 3
|
|
164
|
+
|
|
165
|
+
```python
|
|
166
|
+
def main(first_name: str, last_name: str, output: Path, verbose: bool = False):
|
|
167
|
+
"""Write a greeting message.
|
|
168
|
+
|
|
169
|
+
:param first_name: The first name of the user to greet (optional)
|
|
170
|
+
:param last_name: The last name of the user to greet (optional)
|
|
171
|
+
:param output: The output file (stdout if none is provided)
|
|
172
|
+
:param verbose: If provided, will write the debug logs to stdout
|
|
173
|
+
"""
|
|
174
|
+
...
|
|
175
|
+
|
|
176
|
+
|
|
177
|
+
if __name__ == "__main__":
|
|
178
|
+
argumentify(main)
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
The help looks like this:
|
|
182
|
+
|
|
183
|
+
```help
|
|
184
|
+
usage: test.py [-h] [--first-name FIRST_NAME] [--last-name LAST_NAME] [--output OUTPUT]
|
|
185
|
+
[--verbose]
|
|
186
|
+
|
|
187
|
+
Write a greeting message.
|
|
188
|
+
|
|
189
|
+
options:
|
|
190
|
+
-h, --help
|
|
191
|
+
show this help message and exit
|
|
192
|
+
--first-name FIRST_NAME, -f FIRST_NAME
|
|
193
|
+
The first name of the user to greet (optional)
|
|
194
|
+
--last-name LAST_NAME, -l LAST_NAME
|
|
195
|
+
The last name of the user to greet (optional)
|
|
196
|
+
--output OUTPUT, -o OUTPUT
|
|
197
|
+
The output file (stdout if none is provided)
|
|
118
198
|
--verbose, -v
|
|
119
|
-
|
|
199
|
+
If provided, will write the debug logs to stdout
|
|
120
200
|
|
|
121
201
|
```
|
|
122
202
|
|
|
203
|
+
_Note that all the options are optional and default to None. `verbose` is False by
|
|
204
|
+
default since a default value is provided for it in function definition._
|
|
205
|
+
|
|
123
206
|
[Full CHANGELOG](https://github.com/MPCodeWriter21/log21/blob/master/CHANGELOG.md)
|
|
124
207
|
|
|
125
208
|
Usage Examples
|
|
@@ -31,7 +31,7 @@ from .stream_handler import StreamHandler, ColorizingStreamHandler
|
|
|
31
31
|
# yapf: enable
|
|
32
32
|
|
|
33
33
|
__author__ = 'CodeWriter21 (Mehrad Pooryoussof)'
|
|
34
|
-
__version__ = '3.0
|
|
34
|
+
__version__ = '3.1.0'
|
|
35
35
|
__github__ = 'https://GitHub.com/MPCodeWriter21/log21'
|
|
36
36
|
__all__ = [
|
|
37
37
|
'ColorizingStreamHandler', 'DecolorizingFileHandler', 'ColorizingFormatter',
|
|
@@ -344,6 +344,28 @@ def _add_arguments(
|
|
|
344
344
|
"""
|
|
345
345
|
if reserved_flags is None:
|
|
346
346
|
reserved_flags = RESERVED_FLAGS.copy()
|
|
347
|
+
|
|
348
|
+
keyword_only_exists = False
|
|
349
|
+
for argument in info.arguments.values():
|
|
350
|
+
# Reserve the name of POSITIONAL_ONLY and VAR_POSITIONAL arguments as flags
|
|
351
|
+
# since their flag name and their dest need to be the same
|
|
352
|
+
if argument.kind in [_inspect._ParameterKind.POSITIONAL_ONLY,
|
|
353
|
+
_inspect._ParameterKind.VAR_POSITIONAL]:
|
|
354
|
+
reserved_flags.add(argument.name)
|
|
355
|
+
# If there is at least one KEYWORD_ONLY argument, the parameters of kind
|
|
356
|
+
# POSITIONAL_OR_KEYWORD will be marked as required
|
|
357
|
+
if argument.kind == _inspect._ParameterKind.KEYWORD_ONLY:
|
|
358
|
+
keyword_only_exists = True
|
|
359
|
+
# Check if the function has a VAR_KEYWORD argument
|
|
360
|
+
# Raises a ArgumentTypeError if it does
|
|
361
|
+
# TODO: See if we can find a use-case and a way of supporting these arguments
|
|
362
|
+
if argument.kind == _inspect._ParameterKind.VAR_KEYWORD:
|
|
363
|
+
raise ArgumentTypeError(
|
|
364
|
+
f"The function has a `**{argument.name}` argument, "
|
|
365
|
+
"which is not supported.",
|
|
366
|
+
unsupported_arg=argument.name
|
|
367
|
+
)
|
|
368
|
+
|
|
347
369
|
# Add the arguments
|
|
348
370
|
for argument in info.arguments.values():
|
|
349
371
|
config: _Dict[str, _Any] = {
|
|
@@ -351,19 +373,21 @@ def _add_arguments(
|
|
|
351
373
|
'dest': argument.name,
|
|
352
374
|
'help': argument.help
|
|
353
375
|
}
|
|
376
|
+
flags = generate_flag(argument, reserved_flags=reserved_flags)
|
|
354
377
|
if argument.annotation is bool:
|
|
355
378
|
config['action'] = 'store_true'
|
|
356
379
|
elif argument.annotation:
|
|
357
380
|
config['type'] = argument.annotation
|
|
358
381
|
if argument.kind == _inspect._ParameterKind.POSITIONAL_ONLY:
|
|
359
|
-
config
|
|
382
|
+
flags = [config.pop('dest')]
|
|
360
383
|
if argument.kind == _inspect._ParameterKind.VAR_POSITIONAL:
|
|
361
384
|
config['nargs'] = '*'
|
|
385
|
+
flags = [config.pop('dest')]
|
|
386
|
+
if argument.kind == _inspect._ParameterKind.POSITIONAL_OR_KEYWORD and keyword_only_exists:
|
|
387
|
+
config['required'] = True
|
|
362
388
|
if argument.default is not None:
|
|
363
389
|
config['default'] = argument.default
|
|
364
|
-
parser.add_argument(
|
|
365
|
-
*generate_flag(argument, reserved_flags=reserved_flags), **config
|
|
366
|
-
)
|
|
390
|
+
parser.add_argument(*flags, **config)
|
|
367
391
|
|
|
368
392
|
|
|
369
393
|
def _argumentify_one(func: Callable) -> None:
|
|
@@ -373,16 +397,6 @@ def _argumentify_one(func: Callable) -> None:
|
|
|
373
397
|
"""
|
|
374
398
|
info = FunctionInfo(func)
|
|
375
399
|
|
|
376
|
-
# Check if the function has a VAR_KEYWORD argument
|
|
377
|
-
# Raises a ArgumentTypeError if it does
|
|
378
|
-
for argument in info.arguments.values():
|
|
379
|
-
if argument.kind == _inspect._ParameterKind.VAR_KEYWORD:
|
|
380
|
-
raise ArgumentTypeError(
|
|
381
|
-
f"The function has a `**{argument.name}` argument, "
|
|
382
|
-
"which is not supported.",
|
|
383
|
-
unsupported_arg=argument.name
|
|
384
|
-
)
|
|
385
|
-
|
|
386
400
|
# Create the parser
|
|
387
401
|
parser = _argparse.ColorizingArgumentParser(description=info.docstring.description)
|
|
388
402
|
# Add the arguments
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|