humanlog 0.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.
- humanlog-0.1.0/LICENSE +21 -0
- humanlog-0.1.0/PKG-INFO +263 -0
- humanlog-0.1.0/README.md +229 -0
- humanlog-0.1.0/pyproject.toml +52 -0
- humanlog-0.1.0/setup.cfg +4 -0
- humanlog-0.1.0/src/humanlog/__init__.py +7 -0
- humanlog-0.1.0/src/humanlog/core.py +146 -0
- humanlog-0.1.0/src/humanlog/detect.py +79 -0
- humanlog-0.1.0/src/humanlog/render.py +37 -0
- humanlog-0.1.0/src/humanlog.egg-info/PKG-INFO +263 -0
- humanlog-0.1.0/src/humanlog.egg-info/SOURCES.txt +15 -0
- humanlog-0.1.0/src/humanlog.egg-info/dependency_links.txt +1 -0
- humanlog-0.1.0/src/humanlog.egg-info/requires.txt +8 -0
- humanlog-0.1.0/src/humanlog.egg-info/top_level.txt +1 -0
- humanlog-0.1.0/tests/test_core.py +162 -0
- humanlog-0.1.0/tests/test_detect.py +120 -0
- humanlog-0.1.0/tests/test_render.py +27 -0
humanlog-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 srichs
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
humanlog-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: humanlog
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: One-line progress + logging for humans.
|
|
5
|
+
Author-email: srichs <srichs@pm.me>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/srichs/humanlog
|
|
8
|
+
Project-URL: Repository, https://github.com/srichs/humanlog
|
|
9
|
+
Project-URL: Issues, https://github.com/srichs/humanlog/issues
|
|
10
|
+
Project-URL: Changelog, https://github.com/srichs/humanlog/blob/main/CHANGELOG.md
|
|
11
|
+
Keywords: logging,cli,progress,terminal,developer-tools
|
|
12
|
+
Classifier: Development Status :: 4 - Beta
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
22
|
+
Classifier: Topic :: System :: Logging
|
|
23
|
+
Requires-Python: >=3.9
|
|
24
|
+
Description-Content-Type: text/markdown
|
|
25
|
+
License-File: LICENSE
|
|
26
|
+
Provides-Extra: dev
|
|
27
|
+
Requires-Dist: black>=24.0; extra == "dev"
|
|
28
|
+
Requires-Dist: mypy>=1.0; extra == "dev"
|
|
29
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
30
|
+
Requires-Dist: pytest-cov>=5.0; extra == "dev"
|
|
31
|
+
Requires-Dist: ruff>=0.5; extra == "dev"
|
|
32
|
+
Requires-Dist: sphinx>=7.0; extra == "dev"
|
|
33
|
+
Dynamic: license-file
|
|
34
|
+
|
|
35
|
+
# humanlog
|
|
36
|
+
|
|
37
|
+
[](https://github.com/srichs/humanlog/actions/workflows/ci.yml)
|
|
38
|
+
[](https://pypi.org/project/humanlog/)
|
|
39
|
+
|
|
40
|
+
One-line logging + progress for humans.
|
|
41
|
+
Works in terminals, CI, and Jupyter — no setup, no configuration.
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
from humanlog import log
|
|
45
|
+
|
|
46
|
+
log.step("Downloading data")
|
|
47
|
+
...
|
|
48
|
+
log.done(rows=120_000)
|
|
49
|
+
|
|
50
|
+
log.info("Cleaning finished")
|
|
51
|
+
log.warn("Missing values detected", cols=3)
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Why humanlog?
|
|
55
|
+
|
|
56
|
+
Most logging tools are either:
|
|
57
|
+
|
|
58
|
+
- too low-level (stdlib logging),
|
|
59
|
+
- too heavy (structured logging frameworks),
|
|
60
|
+
- or great at one thing (progress bars) but awkward for everything else.
|
|
61
|
+
|
|
62
|
+
`humanlog` is opinionated and small:
|
|
63
|
+
|
|
64
|
+
- readable output
|
|
65
|
+
- automatic timing
|
|
66
|
+
- graceful behavior everywhere
|
|
67
|
+
- zero configuration
|
|
68
|
+
|
|
69
|
+
It’s for applications, scripts, CLIs, and data workflows.
|
|
70
|
+
|
|
71
|
+
## Install
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
pip install humanlog
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
Python 3.9+ (no dependencies).
|
|
78
|
+
|
|
79
|
+
## The core idea
|
|
80
|
+
|
|
81
|
+
### Steps feel like steps
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
log.step("Training model")
|
|
85
|
+
train()
|
|
86
|
+
log.done(loss=0.031)
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
Output (terminal):
|
|
90
|
+
|
|
91
|
+
```text
|
|
92
|
+
→ Training model …
|
|
93
|
+
✓ Training model (loss=0.031, time=2.41s)
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
No manual timers. No formatting. No state.
|
|
97
|
+
|
|
98
|
+
### Informational messages
|
|
99
|
+
|
|
100
|
+
```python
|
|
101
|
+
log.info("Loading dataset", rows=120_000)
|
|
102
|
+
log.warn("Missing values detected", cols=3)
|
|
103
|
+
log.error("Failed to connect to database")
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
Output:
|
|
107
|
+
|
|
108
|
+
```text
|
|
109
|
+
[12:40:03] ℹ Loading dataset (rows=120000)
|
|
110
|
+
[12:40:04] ⚠ Missing values detected (cols=3)
|
|
111
|
+
[12:40:05] ✖ Failed to connect to database
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## Works everywhere
|
|
115
|
+
|
|
116
|
+
### Terminal (TTY)
|
|
117
|
+
|
|
118
|
+
- Animated steps
|
|
119
|
+
- Clean overwrite
|
|
120
|
+
- Human-friendly symbols
|
|
121
|
+
|
|
122
|
+
### CI (GitHub Actions, GitLab, etc.)
|
|
123
|
+
|
|
124
|
+
- No carriage-return garbage
|
|
125
|
+
- Timestamped, line-by-line logs
|
|
126
|
+
|
|
127
|
+
### Jupyter notebooks
|
|
128
|
+
|
|
129
|
+
- No broken progress bars
|
|
130
|
+
- Clean output cells
|
|
131
|
+
|
|
132
|
+
`humanlog` automatically detects where it’s running and adapts.
|
|
133
|
+
|
|
134
|
+
Set `HUMANLOG_NO_ANIMATE=1` (or `NO_COLOR=1`) to force non-animated output.
|
|
135
|
+
|
|
136
|
+
## Zero configuration
|
|
137
|
+
|
|
138
|
+
No handlers.
|
|
139
|
+
No log levels to wire up.
|
|
140
|
+
No global logging side effects.
|
|
141
|
+
|
|
142
|
+
Just import and go.
|
|
143
|
+
|
|
144
|
+
## API
|
|
145
|
+
|
|
146
|
+
### `log.step(message: str)`
|
|
147
|
+
|
|
148
|
+
Start a timed step.
|
|
149
|
+
|
|
150
|
+
If another step is already active, `humanlog` automatically finishes it first so
|
|
151
|
+
you never end up with overlapping step state.
|
|
152
|
+
|
|
153
|
+
You can also use it as a context manager to auto-complete the step:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
with log.step("Training model"):
|
|
157
|
+
train()
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
If an exception escapes the block, the step is automatically closed as failed:
|
|
161
|
+
|
|
162
|
+
```text
|
|
163
|
+
[12:40:05] ✖ Training model (error=RuntimeError, time=0.73s)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
### `log.done(**info)`
|
|
167
|
+
|
|
168
|
+
Finish the current step and print timing + optional key/value info.
|
|
169
|
+
|
|
170
|
+
### `log.info(message: str, **info)`
|
|
171
|
+
|
|
172
|
+
Print an informational message.
|
|
173
|
+
|
|
174
|
+
If a step is active, it is automatically completed before the info line is
|
|
175
|
+
printed.
|
|
176
|
+
|
|
177
|
+
### `log.warn(message: str, **info)`
|
|
178
|
+
|
|
179
|
+
Print a warning (to stderr).
|
|
180
|
+
|
|
181
|
+
If a step is active, it is automatically completed before the warning is
|
|
182
|
+
printed.
|
|
183
|
+
|
|
184
|
+
### `log.error(message: str, **info)`
|
|
185
|
+
|
|
186
|
+
Print an error (to stderr).
|
|
187
|
+
|
|
188
|
+
If a step is active, it is automatically completed before the error is printed.
|
|
189
|
+
|
|
190
|
+
Key/value info is always optional and rendered inline:
|
|
191
|
+
|
|
192
|
+
```python
|
|
193
|
+
log.info("Loaded batch", batch=3, rows=1024)
|
|
194
|
+
```
|
|
195
|
+
|
|
196
|
+
## Example: a real script
|
|
197
|
+
|
|
198
|
+
```python
|
|
199
|
+
from humanlog import log
|
|
200
|
+
|
|
201
|
+
log.step("Downloading data")
|
|
202
|
+
download()
|
|
203
|
+
log.done(rows=120_000)
|
|
204
|
+
|
|
205
|
+
log.step("Cleaning data")
|
|
206
|
+
clean()
|
|
207
|
+
log.done(dropped=341)
|
|
208
|
+
|
|
209
|
+
log.step("Training model")
|
|
210
|
+
train()
|
|
211
|
+
log.done(epochs=10, loss=0.031)
|
|
212
|
+
|
|
213
|
+
log.info("All done")
|
|
214
|
+
```
|
|
215
|
+
|
|
216
|
+
Readable. Intentional. Calm.
|
|
217
|
+
|
|
218
|
+
## Non-goals (by design)
|
|
219
|
+
|
|
220
|
+
`humanlog` is not:
|
|
221
|
+
|
|
222
|
+
- a replacement for structured logging
|
|
223
|
+
- a metrics system
|
|
224
|
+
- a tracing framework
|
|
225
|
+
- a progress-bar DSL
|
|
226
|
+
|
|
227
|
+
If you need JSON logs or OpenTelemetry, use those tools.
|
|
228
|
+
|
|
229
|
+
If you want pleasant, readable output, use `humanlog`.
|
|
230
|
+
|
|
231
|
+
## Roadmap (likely, but optional)
|
|
232
|
+
|
|
233
|
+
- `log.track(iterable, label="Processing")`
|
|
234
|
+
- optional Rich-powered rendering
|
|
235
|
+
- stdlib logging bridge (opt-in)
|
|
236
|
+
|
|
237
|
+
The core will stay small.
|
|
238
|
+
|
|
239
|
+
## Philosophy
|
|
240
|
+
|
|
241
|
+
`humanlog` optimizes for:
|
|
242
|
+
|
|
243
|
+
- clarity over flexibility
|
|
244
|
+
- defaults over configuration
|
|
245
|
+
- humans over machines
|
|
246
|
+
|
|
247
|
+
Logs are for people first.
|
|
248
|
+
|
|
249
|
+
## Contributing
|
|
250
|
+
|
|
251
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup and quality checks.
|
|
252
|
+
|
|
253
|
+
## Changelog
|
|
254
|
+
|
|
255
|
+
Release history is tracked in [CHANGELOG.md](CHANGELOG.md).
|
|
256
|
+
|
|
257
|
+
## Releasing
|
|
258
|
+
|
|
259
|
+
Maintainers can follow [RELEASE.md](RELEASE.md) for packaging, verification, and publish steps.
|
|
260
|
+
|
|
261
|
+
## License
|
|
262
|
+
|
|
263
|
+
MIT
|
humanlog-0.1.0/README.md
ADDED
|
@@ -0,0 +1,229 @@
|
|
|
1
|
+
# humanlog
|
|
2
|
+
|
|
3
|
+
[](https://github.com/srichs/humanlog/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/humanlog/)
|
|
5
|
+
|
|
6
|
+
One-line logging + progress for humans.
|
|
7
|
+
Works in terminals, CI, and Jupyter — no setup, no configuration.
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from humanlog import log
|
|
11
|
+
|
|
12
|
+
log.step("Downloading data")
|
|
13
|
+
...
|
|
14
|
+
log.done(rows=120_000)
|
|
15
|
+
|
|
16
|
+
log.info("Cleaning finished")
|
|
17
|
+
log.warn("Missing values detected", cols=3)
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
## Why humanlog?
|
|
21
|
+
|
|
22
|
+
Most logging tools are either:
|
|
23
|
+
|
|
24
|
+
- too low-level (stdlib logging),
|
|
25
|
+
- too heavy (structured logging frameworks),
|
|
26
|
+
- or great at one thing (progress bars) but awkward for everything else.
|
|
27
|
+
|
|
28
|
+
`humanlog` is opinionated and small:
|
|
29
|
+
|
|
30
|
+
- readable output
|
|
31
|
+
- automatic timing
|
|
32
|
+
- graceful behavior everywhere
|
|
33
|
+
- zero configuration
|
|
34
|
+
|
|
35
|
+
It’s for applications, scripts, CLIs, and data workflows.
|
|
36
|
+
|
|
37
|
+
## Install
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
pip install humanlog
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Python 3.9+ (no dependencies).
|
|
44
|
+
|
|
45
|
+
## The core idea
|
|
46
|
+
|
|
47
|
+
### Steps feel like steps
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
log.step("Training model")
|
|
51
|
+
train()
|
|
52
|
+
log.done(loss=0.031)
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Output (terminal):
|
|
56
|
+
|
|
57
|
+
```text
|
|
58
|
+
→ Training model …
|
|
59
|
+
✓ Training model (loss=0.031, time=2.41s)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
No manual timers. No formatting. No state.
|
|
63
|
+
|
|
64
|
+
### Informational messages
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
log.info("Loading dataset", rows=120_000)
|
|
68
|
+
log.warn("Missing values detected", cols=3)
|
|
69
|
+
log.error("Failed to connect to database")
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
Output:
|
|
73
|
+
|
|
74
|
+
```text
|
|
75
|
+
[12:40:03] ℹ Loading dataset (rows=120000)
|
|
76
|
+
[12:40:04] ⚠ Missing values detected (cols=3)
|
|
77
|
+
[12:40:05] ✖ Failed to connect to database
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Works everywhere
|
|
81
|
+
|
|
82
|
+
### Terminal (TTY)
|
|
83
|
+
|
|
84
|
+
- Animated steps
|
|
85
|
+
- Clean overwrite
|
|
86
|
+
- Human-friendly symbols
|
|
87
|
+
|
|
88
|
+
### CI (GitHub Actions, GitLab, etc.)
|
|
89
|
+
|
|
90
|
+
- No carriage-return garbage
|
|
91
|
+
- Timestamped, line-by-line logs
|
|
92
|
+
|
|
93
|
+
### Jupyter notebooks
|
|
94
|
+
|
|
95
|
+
- No broken progress bars
|
|
96
|
+
- Clean output cells
|
|
97
|
+
|
|
98
|
+
`humanlog` automatically detects where it’s running and adapts.
|
|
99
|
+
|
|
100
|
+
Set `HUMANLOG_NO_ANIMATE=1` (or `NO_COLOR=1`) to force non-animated output.
|
|
101
|
+
|
|
102
|
+
## Zero configuration
|
|
103
|
+
|
|
104
|
+
No handlers.
|
|
105
|
+
No log levels to wire up.
|
|
106
|
+
No global logging side effects.
|
|
107
|
+
|
|
108
|
+
Just import and go.
|
|
109
|
+
|
|
110
|
+
## API
|
|
111
|
+
|
|
112
|
+
### `log.step(message: str)`
|
|
113
|
+
|
|
114
|
+
Start a timed step.
|
|
115
|
+
|
|
116
|
+
If another step is already active, `humanlog` automatically finishes it first so
|
|
117
|
+
you never end up with overlapping step state.
|
|
118
|
+
|
|
119
|
+
You can also use it as a context manager to auto-complete the step:
|
|
120
|
+
|
|
121
|
+
```python
|
|
122
|
+
with log.step("Training model"):
|
|
123
|
+
train()
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
If an exception escapes the block, the step is automatically closed as failed:
|
|
127
|
+
|
|
128
|
+
```text
|
|
129
|
+
[12:40:05] ✖ Training model (error=RuntimeError, time=0.73s)
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
### `log.done(**info)`
|
|
133
|
+
|
|
134
|
+
Finish the current step and print timing + optional key/value info.
|
|
135
|
+
|
|
136
|
+
### `log.info(message: str, **info)`
|
|
137
|
+
|
|
138
|
+
Print an informational message.
|
|
139
|
+
|
|
140
|
+
If a step is active, it is automatically completed before the info line is
|
|
141
|
+
printed.
|
|
142
|
+
|
|
143
|
+
### `log.warn(message: str, **info)`
|
|
144
|
+
|
|
145
|
+
Print a warning (to stderr).
|
|
146
|
+
|
|
147
|
+
If a step is active, it is automatically completed before the warning is
|
|
148
|
+
printed.
|
|
149
|
+
|
|
150
|
+
### `log.error(message: str, **info)`
|
|
151
|
+
|
|
152
|
+
Print an error (to stderr).
|
|
153
|
+
|
|
154
|
+
If a step is active, it is automatically completed before the error is printed.
|
|
155
|
+
|
|
156
|
+
Key/value info is always optional and rendered inline:
|
|
157
|
+
|
|
158
|
+
```python
|
|
159
|
+
log.info("Loaded batch", batch=3, rows=1024)
|
|
160
|
+
```
|
|
161
|
+
|
|
162
|
+
## Example: a real script
|
|
163
|
+
|
|
164
|
+
```python
|
|
165
|
+
from humanlog import log
|
|
166
|
+
|
|
167
|
+
log.step("Downloading data")
|
|
168
|
+
download()
|
|
169
|
+
log.done(rows=120_000)
|
|
170
|
+
|
|
171
|
+
log.step("Cleaning data")
|
|
172
|
+
clean()
|
|
173
|
+
log.done(dropped=341)
|
|
174
|
+
|
|
175
|
+
log.step("Training model")
|
|
176
|
+
train()
|
|
177
|
+
log.done(epochs=10, loss=0.031)
|
|
178
|
+
|
|
179
|
+
log.info("All done")
|
|
180
|
+
```
|
|
181
|
+
|
|
182
|
+
Readable. Intentional. Calm.
|
|
183
|
+
|
|
184
|
+
## Non-goals (by design)
|
|
185
|
+
|
|
186
|
+
`humanlog` is not:
|
|
187
|
+
|
|
188
|
+
- a replacement for structured logging
|
|
189
|
+
- a metrics system
|
|
190
|
+
- a tracing framework
|
|
191
|
+
- a progress-bar DSL
|
|
192
|
+
|
|
193
|
+
If you need JSON logs or OpenTelemetry, use those tools.
|
|
194
|
+
|
|
195
|
+
If you want pleasant, readable output, use `humanlog`.
|
|
196
|
+
|
|
197
|
+
## Roadmap (likely, but optional)
|
|
198
|
+
|
|
199
|
+
- `log.track(iterable, label="Processing")`
|
|
200
|
+
- optional Rich-powered rendering
|
|
201
|
+
- stdlib logging bridge (opt-in)
|
|
202
|
+
|
|
203
|
+
The core will stay small.
|
|
204
|
+
|
|
205
|
+
## Philosophy
|
|
206
|
+
|
|
207
|
+
`humanlog` optimizes for:
|
|
208
|
+
|
|
209
|
+
- clarity over flexibility
|
|
210
|
+
- defaults over configuration
|
|
211
|
+
- humans over machines
|
|
212
|
+
|
|
213
|
+
Logs are for people first.
|
|
214
|
+
|
|
215
|
+
## Contributing
|
|
216
|
+
|
|
217
|
+
Contributions are welcome. See [CONTRIBUTING.md](CONTRIBUTING.md) for local setup and quality checks.
|
|
218
|
+
|
|
219
|
+
## Changelog
|
|
220
|
+
|
|
221
|
+
Release history is tracked in [CHANGELOG.md](CHANGELOG.md).
|
|
222
|
+
|
|
223
|
+
## Releasing
|
|
224
|
+
|
|
225
|
+
Maintainers can follow [RELEASE.md](RELEASE.md) for packaging, verification, and publish steps.
|
|
226
|
+
|
|
227
|
+
## License
|
|
228
|
+
|
|
229
|
+
MIT
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "humanlog"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "One-line progress + logging for humans."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.9"
|
|
11
|
+
authors = [
|
|
12
|
+
{name = "srichs", email = "srichs@pm.me"},
|
|
13
|
+
]
|
|
14
|
+
license = {text = "MIT"}
|
|
15
|
+
keywords = ["logging", "cli", "progress", "terminal", "developer-tools"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: MIT License",
|
|
20
|
+
"Operating System :: OS Independent",
|
|
21
|
+
"Programming Language :: Python :: 3",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
27
|
+
"Topic :: System :: Logging",
|
|
28
|
+
]
|
|
29
|
+
|
|
30
|
+
[project.urls]
|
|
31
|
+
Homepage = "https://github.com/srichs/humanlog"
|
|
32
|
+
Repository = "https://github.com/srichs/humanlog"
|
|
33
|
+
Issues = "https://github.com/srichs/humanlog/issues"
|
|
34
|
+
Changelog = "https://github.com/srichs/humanlog/blob/main/CHANGELOG.md"
|
|
35
|
+
|
|
36
|
+
[tool.setuptools]
|
|
37
|
+
package-dir = {"" = "src"}
|
|
38
|
+
packages = ["humanlog"]
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
[project.optional-dependencies]
|
|
42
|
+
dev = [
|
|
43
|
+
"black>=24.0",
|
|
44
|
+
"mypy>=1.0",
|
|
45
|
+
"pytest>=8.0",
|
|
46
|
+
"pytest-cov>=5.0",
|
|
47
|
+
"ruff>=0.5",
|
|
48
|
+
"sphinx>=7.0",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[tool.pytest.ini_options]
|
|
52
|
+
testpaths = ["tests"]
|
humanlog-0.1.0/setup.cfg
ADDED