d8s-timer 0.5.0__tar.gz → 0.6.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.
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/.coveragerc +0 -1
- d8s_timer-0.6.0/.github/dependabot.yml +8 -0
- d8s_timer-0.5.0/.github/workflows/pytest.yml → d8s_timer-0.6.0/.github/workflows/ci.yml +33 -17
- d8s_timer-0.6.0/.github/workflows/dependabot-auto-merge.yml +67 -0
- d8s_timer-0.6.0/.github/workflows/lint.yml +32 -0
- d8s_timer-0.6.0/.github/workflows/release-please.yml +51 -0
- d8s_timer-0.6.0/.release-please-manifest.json +3 -0
- d8s_timer-0.6.0/AGENTS.md +38 -0
- d8s_timer-0.6.0/CHANGELOG.md +8 -0
- d8s_timer-0.6.0/CLAUDE.md +1 -0
- d8s_timer-0.6.0/PKG-INFO +94 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/README.md +1 -1
- d8s_timer-0.6.0/d8s_timer/__init__.py +5 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/d8s_timer/timer.py +4 -3
- d8s_timer-0.6.0/docker/lint.sh +19 -0
- d8s_timer-0.6.0/pyproject.toml +67 -0
- d8s_timer-0.6.0/release-please-config.json +24 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/tests/test_timer.py +5 -5
- d8s_timer-0.6.0/uv.lock +1621 -0
- d8s_timer-0.5.0/.github/dependabot.yml +0 -9
- d8s_timer-0.5.0/.github/workflows/lint.yaml +0 -26
- d8s_timer-0.5.0/.github/workflows/pypi-publish.yml +0 -34
- d8s_timer-0.5.0/Dockerfile +0 -9
- d8s_timer-0.5.0/PKG-INFO +0 -91
- d8s_timer-0.5.0/bumpversion.dockerfile +0 -9
- d8s_timer-0.5.0/d8s_timer/__init__.py +0 -5
- d8s_timer-0.5.0/d8s_timer.egg-info/PKG-INFO +0 -91
- d8s_timer-0.5.0/d8s_timer.egg-info/SOURCES.txt +0 -33
- d8s_timer-0.5.0/d8s_timer.egg-info/dependency_links.txt +0 -1
- d8s_timer-0.5.0/d8s_timer.egg-info/requires.txt +0 -5
- d8s_timer-0.5.0/d8s_timer.egg-info/top_level.txt +0 -2
- d8s_timer-0.5.0/d8s_timer.egg-info/zip-safe +0 -1
- d8s_timer-0.5.0/docker/lint.sh +0 -20
- d8s_timer-0.5.0/docker-compose.yml +0 -46
- d8s_timer-0.5.0/mypy.ini +0 -2
- d8s_timer-0.5.0/pyproject.toml +0 -20
- d8s_timer-0.5.0/requirements.txt +0 -3
- d8s_timer-0.5.0/requirements_dev.txt +0 -14
- d8s_timer-0.5.0/setup.cfg +0 -22
- d8s_timer-0.5.0/setup.py +0 -45
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/.editorconfig +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/.github/workflows/new-issues-to-backlog-project.yml +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/.gitignore +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/COPYING +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/COPYING.LESSER +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/conftest.py +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/d8s_timer/timer_temp_utils.py +0 -0
- {d8s_timer-0.5.0 → d8s_timer-0.6.0}/tests/__init__.py +0 -0
|
@@ -9,48 +9,64 @@ on:
|
|
|
9
9
|
pull_request:
|
|
10
10
|
branches: [ main ]
|
|
11
11
|
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
12
16
|
jobs:
|
|
13
|
-
|
|
17
|
+
build_smoke:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Set up Python 3.14
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.14'
|
|
25
|
+
- name: Set up uv
|
|
26
|
+
uses: astral-sh/setup-uv@v6
|
|
27
|
+
- name: Build package
|
|
28
|
+
run: uv build
|
|
14
29
|
|
|
30
|
+
build_multi_os:
|
|
15
31
|
runs-on: ${{ matrix.os }}
|
|
16
32
|
strategy:
|
|
17
33
|
matrix:
|
|
18
34
|
os: [macos-latest, windows-latest, ubuntu-latest]
|
|
19
|
-
python-version: [3.
|
|
35
|
+
python-version: ['3.14']
|
|
20
36
|
|
|
21
37
|
steps:
|
|
22
|
-
- uses: actions/checkout@
|
|
38
|
+
- uses: actions/checkout@v4
|
|
23
39
|
- name: Set up Python ${{ matrix.python-version }}
|
|
24
|
-
uses: actions/setup-python@
|
|
40
|
+
uses: actions/setup-python@v5
|
|
25
41
|
with:
|
|
26
42
|
python-version: ${{ matrix.python-version }}
|
|
43
|
+
- name: Set up uv
|
|
44
|
+
uses: astral-sh/setup-uv@v6
|
|
27
45
|
- name: Install dependencies
|
|
28
|
-
run:
|
|
29
|
-
python -m pip install -r requirements.txt
|
|
30
|
-
python -m pip install -r requirements_dev.txt
|
|
46
|
+
run: uv sync --locked --group dev
|
|
31
47
|
- name: Run pytest
|
|
32
48
|
run: |
|
|
33
|
-
pytest
|
|
34
|
-
codecov
|
|
49
|
+
uv run pytest
|
|
50
|
+
uv run codecov
|
|
35
51
|
|
|
36
52
|
build_multi_py_versions:
|
|
37
53
|
runs-on: ${{ matrix.os }}
|
|
38
54
|
strategy:
|
|
39
55
|
matrix:
|
|
40
56
|
os: [ubuntu-latest]
|
|
41
|
-
python-version: [3.
|
|
57
|
+
python-version: ['3.10', '3.11', '3.12', '3.13', '3.14']
|
|
42
58
|
|
|
43
59
|
steps:
|
|
44
|
-
- uses: actions/checkout@
|
|
60
|
+
- uses: actions/checkout@v4
|
|
45
61
|
- name: Set up Python ${{ matrix.python-version }}
|
|
46
|
-
uses: actions/setup-python@
|
|
62
|
+
uses: actions/setup-python@v5
|
|
47
63
|
with:
|
|
48
64
|
python-version: ${{ matrix.python-version }}
|
|
65
|
+
- name: Set up uv
|
|
66
|
+
uses: astral-sh/setup-uv@v6
|
|
49
67
|
- name: Install dependencies
|
|
50
|
-
run:
|
|
51
|
-
python -m pip install -r requirements.txt
|
|
52
|
-
python -m pip install -r requirements_dev.txt
|
|
68
|
+
run: uv sync --locked --group dev
|
|
53
69
|
- name: Run pytest
|
|
54
70
|
run: |
|
|
55
|
-
pytest
|
|
56
|
-
codecov
|
|
71
|
+
uv run pytest
|
|
72
|
+
uv run codecov
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
name: Dependabot auto-merge
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
pull_request_target:
|
|
5
|
+
schedule:
|
|
6
|
+
- cron: "11 11 * * *"
|
|
7
|
+
workflow_dispatch:
|
|
8
|
+
|
|
9
|
+
permissions:
|
|
10
|
+
contents: write
|
|
11
|
+
pull-requests: write
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
label:
|
|
15
|
+
if: github.event_name == 'pull_request_target' && github.actor == 'dependabot[bot]'
|
|
16
|
+
runs-on: ubuntu-latest
|
|
17
|
+
steps:
|
|
18
|
+
- name: Fetch Dependabot metadata
|
|
19
|
+
id: meta
|
|
20
|
+
uses: dependabot/fetch-metadata@v2
|
|
21
|
+
|
|
22
|
+
- name: Ensure labels exist
|
|
23
|
+
env:
|
|
24
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
25
|
+
run: |
|
|
26
|
+
gh label create auto-merge-candidate --color ededed --description "Dependabot dev-dep PR eligible for auto-merge after soak" --force --repo "$GITHUB_REPOSITORY"
|
|
27
|
+
gh label create needs-manual-merge --color d93f0b --description "Dependabot PR not eligible for auto-merge; needs manual review" --force --repo "$GITHUB_REPOSITORY"
|
|
28
|
+
|
|
29
|
+
- name: Label auto-merge candidates
|
|
30
|
+
if: steps.meta.outputs.dependency-type == 'direct:development' && (steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor')
|
|
31
|
+
env:
|
|
32
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
33
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
34
|
+
run: gh pr edit "$PR_URL" --add-label auto-merge-candidate
|
|
35
|
+
|
|
36
|
+
- name: Label PRs needing manual review
|
|
37
|
+
if: ${{ !(steps.meta.outputs.dependency-type == 'direct:development' && (steps.meta.outputs.update-type == 'version-update:semver-patch' || steps.meta.outputs.update-type == 'version-update:semver-minor')) }}
|
|
38
|
+
env:
|
|
39
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
40
|
+
PR_URL: ${{ github.event.pull_request.html_url }}
|
|
41
|
+
run: gh pr edit "$PR_URL" --add-label needs-manual-merge
|
|
42
|
+
|
|
43
|
+
soak-and-merge:
|
|
44
|
+
if: github.event_name == 'schedule' || github.event_name == 'workflow_dispatch'
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
env:
|
|
47
|
+
SOAK_DAYS: 3
|
|
48
|
+
steps:
|
|
49
|
+
- name: Enable auto-merge on soaked PRs
|
|
50
|
+
env:
|
|
51
|
+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
52
|
+
run: |
|
|
53
|
+
cutoff=$(date -u -d "${SOAK_DAYS} days ago" +%Y-%m-%dT%H:%M:%SZ)
|
|
54
|
+
gh pr list \
|
|
55
|
+
--repo "$GITHUB_REPOSITORY" \
|
|
56
|
+
--author "app/dependabot" \
|
|
57
|
+
--label auto-merge-candidate \
|
|
58
|
+
--state open \
|
|
59
|
+
--json number,createdAt,autoMergeRequest \
|
|
60
|
+
--jq ".[] | select(.createdAt < \"$cutoff\") | .number" \
|
|
61
|
+
| while read -r pr; do
|
|
62
|
+
auto=$(gh pr view "$pr" --repo "$GITHUB_REPOSITORY" --json autoMergeRequest --jq .autoMergeRequest)
|
|
63
|
+
if [ "$auto" = "null" ] || [ -z "$auto" ]; then
|
|
64
|
+
echo "Enabling auto-merge on PR #$pr"
|
|
65
|
+
gh pr merge "$pr" --auto --squash --repo "$GITHUB_REPOSITORY" || echo "Failed to enable auto-merge on PR #$pr"
|
|
66
|
+
fi
|
|
67
|
+
done
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# This workflow will install Python dependencies and lint the code with ruff and mypy
|
|
2
|
+
# For more information see: https://help.github.com/actions/language-and-framework-guides/using-python-with-github-actions
|
|
3
|
+
|
|
4
|
+
name: Lint
|
|
5
|
+
|
|
6
|
+
on:
|
|
7
|
+
push:
|
|
8
|
+
branches: [ main ]
|
|
9
|
+
pull_request:
|
|
10
|
+
branches: [ main ]
|
|
11
|
+
|
|
12
|
+
concurrency:
|
|
13
|
+
group: ${{ github.workflow }}-${{ github.ref }}
|
|
14
|
+
cancel-in-progress: true
|
|
15
|
+
|
|
16
|
+
jobs:
|
|
17
|
+
build:
|
|
18
|
+
runs-on: ubuntu-latest
|
|
19
|
+
steps:
|
|
20
|
+
- uses: actions/checkout@v4
|
|
21
|
+
- name: Set up Python
|
|
22
|
+
uses: actions/setup-python@v5
|
|
23
|
+
with:
|
|
24
|
+
python-version: '3.14'
|
|
25
|
+
- name: Set up uv
|
|
26
|
+
uses: astral-sh/setup-uv@v6
|
|
27
|
+
- name: Install dependencies
|
|
28
|
+
run: uv sync --locked --group dev
|
|
29
|
+
- name: Lint
|
|
30
|
+
env:
|
|
31
|
+
CONTEXT: ci
|
|
32
|
+
run: ./docker/lint.sh
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
# Conventional-commit release automation.
|
|
2
|
+
# On every push to main, release-please maintains a release PR (CHANGELOG +
|
|
3
|
+
# version bump in pyproject.toml + d8s_lists/__init__.py). Merging that PR
|
|
4
|
+
# tags vX.Y.Z and creates the GitHub Release; this same run then builds and
|
|
5
|
+
# publishes to PyPI via OIDC.
|
|
6
|
+
#
|
|
7
|
+
# Publish is folded into THIS workflow on purpose: a tag pushed by
|
|
8
|
+
# release-please uses GITHUB_TOKEN, which does NOT trigger a separate
|
|
9
|
+
# tag-triggered workflow. Gating on release_created keeps OIDC (no PAT/secrets).
|
|
10
|
+
|
|
11
|
+
name: release-please
|
|
12
|
+
|
|
13
|
+
on:
|
|
14
|
+
push:
|
|
15
|
+
branches:
|
|
16
|
+
- main
|
|
17
|
+
|
|
18
|
+
permissions:
|
|
19
|
+
contents: write # create release PR, tag, and GitHub Release
|
|
20
|
+
pull-requests: write # open/update the release PR
|
|
21
|
+
|
|
22
|
+
jobs:
|
|
23
|
+
release-please:
|
|
24
|
+
runs-on: ubuntu-latest
|
|
25
|
+
outputs:
|
|
26
|
+
release_created: ${{ steps.release.outputs.release_created }}
|
|
27
|
+
tag_name: ${{ steps.release.outputs.tag_name }}
|
|
28
|
+
steps:
|
|
29
|
+
- uses: googleapis/release-please-action@v4
|
|
30
|
+
id: release
|
|
31
|
+
with:
|
|
32
|
+
config-file: release-please-config.json
|
|
33
|
+
manifest-file: .release-please-manifest.json
|
|
34
|
+
|
|
35
|
+
publish:
|
|
36
|
+
needs: release-please
|
|
37
|
+
if: needs.release-please.outputs.release_created == 'true'
|
|
38
|
+
runs-on: ubuntu-latest
|
|
39
|
+
permissions:
|
|
40
|
+
id-token: write # required for OIDC trusted publishing
|
|
41
|
+
contents: read
|
|
42
|
+
steps:
|
|
43
|
+
- uses: actions/checkout@v4
|
|
44
|
+
with:
|
|
45
|
+
ref: ${{ needs.release-please.outputs.tag_name }}
|
|
46
|
+
- name: Set up uv
|
|
47
|
+
uses: astral-sh/setup-uv@v6
|
|
48
|
+
- name: Build
|
|
49
|
+
run: uv build
|
|
50
|
+
- name: Publish to PyPI
|
|
51
|
+
uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
# AGENTS.md
|
|
2
|
+
|
|
3
|
+
## Commit messages: use Conventional Commits
|
|
4
|
+
|
|
5
|
+
Releases are automated by [release-please](https://github.com/googleapis/release-please).
|
|
6
|
+
It reads commit messages to bump the version, write `CHANGELOG.md`, tag, and publish to
|
|
7
|
+
PyPI. **Non-conventional commits are silently ignored** — no version bump, absent from the
|
|
8
|
+
changelog.
|
|
9
|
+
|
|
10
|
+
Format: `type: description` (optionally `type(scope): description`).
|
|
11
|
+
|
|
12
|
+
Common types and their effect on the release:
|
|
13
|
+
|
|
14
|
+
| Type | Effect | Changelog section |
|
|
15
|
+
|------|--------|-------------------|
|
|
16
|
+
| `feat:` | minor bump (0.8.0 → 0.9.0) | Features |
|
|
17
|
+
| `fix:` | patch bump (0.8.0 → 0.8.1) | Bug Fixes |
|
|
18
|
+
| `perf:` | patch bump | Performance Improvements |
|
|
19
|
+
| `deps:` | no bump (rides next release) | Dependencies |
|
|
20
|
+
| `docs:` `refactor:` `test:` `chore:` `ci:` `build:` `style:` | no bump | hidden |
|
|
21
|
+
|
|
22
|
+
Breaking change: append `!` (`feat!: ...`) or add a `BREAKING CHANGE:` footer → major bump.
|
|
23
|
+
|
|
24
|
+
Examples:
|
|
25
|
+
|
|
26
|
+
```
|
|
27
|
+
feat: add iterable_chunk
|
|
28
|
+
fix: cycle() returns empty when length is 0
|
|
29
|
+
feat!: rename list_flatten to iterable_flatten
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
Prefer squash-merging PRs so the PR title becomes the single conventional commit.
|
|
33
|
+
|
|
34
|
+
## Releasing
|
|
35
|
+
|
|
36
|
+
Don't bump versions, edit `CHANGELOG.md`, or create tags by hand — release-please owns all
|
|
37
|
+
three. To cut a release, merge the open `chore: release X.Y.Z` PR; that tags the version,
|
|
38
|
+
creates the GitHub Release, and publishes to PyPI via OIDC.
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.6.0](https://github.com/democritus-project/d8s-timer/compare/v0.5.0...v0.6.0) (2026-07-01)
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
### Features
|
|
7
|
+
|
|
8
|
+
* modernize tooling and release automation ([6020b86](https://github.com/democritus-project/d8s-timer/commit/6020b860d7e64a169542727a9eb4bd30ea4056bd))
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
Read AGENTS.md in the repository root and follow it.
|
d8s_timer-0.6.0/PKG-INFO
ADDED
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: d8s_timer
|
|
3
|
+
Version: 0.6.0
|
|
4
|
+
Summary: Democritus functions for working with timers.
|
|
5
|
+
Project-URL: Source, https://github.com/democritus-project/d8s-timer
|
|
6
|
+
Project-URL: Issues, https://github.com/democritus-project/d8s-timer/issues
|
|
7
|
+
Author: Floyd Hightower
|
|
8
|
+
License: GNU Lesser General Public License v3
|
|
9
|
+
License-File: COPYING
|
|
10
|
+
License-File: COPYING.LESSER
|
|
11
|
+
Keywords: clock,democritus,python,time,timers,timers-utility,utility
|
|
12
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
13
|
+
Classifier: Intended Audience :: Developers
|
|
14
|
+
Classifier: License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)
|
|
15
|
+
Classifier: Natural Language :: English
|
|
16
|
+
Classifier: Programming Language :: Python :: 3
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
22
|
+
Requires-Python: >=3.10
|
|
23
|
+
Requires-Dist: d8s-dates<1.0,>=0.7.0
|
|
24
|
+
Requires-Dist: d8s-uuids<1.0,>=0.6.0
|
|
25
|
+
Description-Content-Type: text/markdown
|
|
26
|
+
|
|
27
|
+
# Democritus Timer
|
|
28
|
+
|
|
29
|
+
[](https://pypi.python.org/pypi/d8s-timer)
|
|
30
|
+
[](https://github.com/democritus-project/d8s-timer/actions)
|
|
31
|
+
[](https://github.com/democritus-project/d8s-timer/actions)
|
|
32
|
+
[](https://codecov.io/gh/democritus-project/d8s-timer)
|
|
33
|
+
[](https://semver.org/spec/v2.0.0.html)
|
|
34
|
+
[](https://github.com/astral-sh/ruff)
|
|
35
|
+
[](https://choosealicense.com/licenses/lgpl-3.0/)
|
|
36
|
+
|
|
37
|
+
Democritus functions<sup>[1]</sup> for working with timers.
|
|
38
|
+
|
|
39
|
+
[1] Democritus functions are <i>simple, effective, modular, well-tested, and well-documented</i> Python functions.
|
|
40
|
+
|
|
41
|
+
We use `d8s` (pronounced "dee-eights") as an abbreviation for `democritus` (you can read more about this [here](https://github.com/democritus-project/roadmap#what-is-d8s)).
|
|
42
|
+
|
|
43
|
+
## Installation
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
pip install d8s-timer
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Usage
|
|
50
|
+
|
|
51
|
+
You import the library like:
|
|
52
|
+
|
|
53
|
+
```python
|
|
54
|
+
from d8s_timer import *
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
Once imported, you can use any of the functions listed below.
|
|
58
|
+
|
|
59
|
+
## Functions
|
|
60
|
+
|
|
61
|
+
- ```python
|
|
62
|
+
def timer_start(name: str = None) -> str:
|
|
63
|
+
"""Start a timer with the given name. Timers can be stopped with the `timer_stop` function."""
|
|
64
|
+
```
|
|
65
|
+
- ```python
|
|
66
|
+
def timer_get_time(name: str) -> float:
|
|
67
|
+
"""Get the current time for the timer with the given name."""
|
|
68
|
+
```
|
|
69
|
+
- ```python
|
|
70
|
+
def timer_stop(name: str) -> float:
|
|
71
|
+
"""Stop a timer (you can start a timer with the `timer_start` function)."""
|
|
72
|
+
```
|
|
73
|
+
- ```python
|
|
74
|
+
def time_it(func):
|
|
75
|
+
"""Return the time it takes func to execute."""
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
## Development
|
|
79
|
+
|
|
80
|
+
👋 If you want to get involved in this project, we have some short, helpful guides below:
|
|
81
|
+
|
|
82
|
+
- [contribute to this project 🥇][contributing]
|
|
83
|
+
- [test it 🧪][local-dev]
|
|
84
|
+
- [lint it 🧹][local-dev]
|
|
85
|
+
- [explore it 🔭][local-dev]
|
|
86
|
+
|
|
87
|
+
If you have any questions or there is anything we did not cover, please raise an issue and we'll be happy to help.
|
|
88
|
+
|
|
89
|
+
## Credits
|
|
90
|
+
|
|
91
|
+
This package was created with [Cookiecutter](https://github.com/audreyr/cookiecutter) and Floyd Hightower's [Python project template](https://github.com/fhightower-templates/python-project-template).
|
|
92
|
+
|
|
93
|
+
[contributing]: https://github.com/democritus-project/.github/blob/main/CONTRIBUTING.md#contributing-a-pr-
|
|
94
|
+
[local-dev]: https://github.com/democritus-project/.github/blob/main/CONTRIBUTING.md#local-development-
|
|
@@ -5,7 +5,7 @@
|
|
|
5
5
|
[](https://github.com/democritus-project/d8s-timer/actions)
|
|
6
6
|
[](https://codecov.io/gh/democritus-project/d8s-timer)
|
|
7
7
|
[](https://semver.org/spec/v2.0.0.html)
|
|
8
|
-
[](https://github.com/astral-sh/ruff)
|
|
9
9
|
[](https://choosealicense.com/licenses/lgpl-3.0/)
|
|
10
10
|
|
|
11
11
|
Democritus functions<sup>[1]</sup> for working with timers.
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import functools
|
|
2
|
+
from typing import Optional
|
|
2
3
|
|
|
3
4
|
from d8s_dates import time_now
|
|
4
5
|
from d8s_uuids import uuid4
|
|
@@ -26,7 +27,7 @@ class Timer:
|
|
|
26
27
|
_timer_object = Timer()
|
|
27
28
|
|
|
28
29
|
|
|
29
|
-
def timer_start(name: str = None) -> str:
|
|
30
|
+
def timer_start(name: Optional[str] = None) -> str:
|
|
30
31
|
"""Start a timer with the given name. Timers can be stopped with the `timer_stop` function."""
|
|
31
32
|
# if there is no name given, use a generic name
|
|
32
33
|
if name is None:
|
|
@@ -54,7 +55,7 @@ def _get_time_difference(timer_time: int) -> float:
|
|
|
54
55
|
def timer_get_time(name: str) -> float:
|
|
55
56
|
"""Get the current time for the timer with the given name."""
|
|
56
57
|
if not _timer_object.has_timer(name, print_errors=True):
|
|
57
|
-
message = f
|
|
58
|
+
message = f"There is no timer with the name {name}"
|
|
58
59
|
raise ValueError(message)
|
|
59
60
|
|
|
60
61
|
time_difference = _get_time_difference(_timer_object.timers[name])
|
|
@@ -64,7 +65,7 @@ def timer_get_time(name: str) -> float:
|
|
|
64
65
|
def timer_stop(name: str) -> float:
|
|
65
66
|
"""Stop a timer (you can start a timer with the `timer_start` function)."""
|
|
66
67
|
if not _timer_object.has_timer(name, print_errors=True):
|
|
67
|
-
message = f
|
|
68
|
+
message = f"There is no timer with the name {name}"
|
|
68
69
|
raise ValueError(message)
|
|
69
70
|
|
|
70
71
|
time_difference = _get_time_difference(_timer_object.timers[name])
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
#!/usr/bin/env bash
|
|
2
|
+
|
|
3
|
+
set -euxo pipefail
|
|
4
|
+
|
|
5
|
+
echo "Running linters and formatters..."
|
|
6
|
+
|
|
7
|
+
uv run ruff check --fix d8s_timer/ tests/
|
|
8
|
+
uv run ruff format d8s_timer/ tests/
|
|
9
|
+
|
|
10
|
+
# if the CONTEXT env var is "ci" (which is set in .github/workflows/lint.yml), validate that none of the files
|
|
11
|
+
# have been changed by the previous lint steps
|
|
12
|
+
if [ "${CONTEXT:-local}" = "ci" ]; then
|
|
13
|
+
(git status | grep "nothing to commit") || { echo "Lint steps have changed files"; exit 1; };
|
|
14
|
+
fi
|
|
15
|
+
|
|
16
|
+
uv run mypy d8s_timer/ tests/
|
|
17
|
+
uv run ruff check d8s_timer/ tests/
|
|
18
|
+
|
|
19
|
+
echo "Done ✨ 🎉 ✨"
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "d8s_timer"
|
|
7
|
+
version = "0.6.0"
|
|
8
|
+
description = "Democritus functions for working with timers."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = { text = "GNU Lesser General Public License v3" }
|
|
12
|
+
authors = [{ name = "Floyd Hightower" }]
|
|
13
|
+
keywords = ["democritus", "utility", "python", "timers", "timers-utility", "time", "clock"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 2 - Pre-Alpha",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: GNU Lesser General Public License v3 or later (LGPLv3+)",
|
|
18
|
+
"Natural Language :: English",
|
|
19
|
+
"Programming Language :: Python :: 3",
|
|
20
|
+
"Programming Language :: Python :: 3.10",
|
|
21
|
+
"Programming Language :: Python :: 3.11",
|
|
22
|
+
"Programming Language :: Python :: 3.12",
|
|
23
|
+
"Programming Language :: Python :: 3.13",
|
|
24
|
+
"Programming Language :: Python :: 3.14",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"d8s-dates>=0.7.0,<1.0",
|
|
28
|
+
"d8s-uuids>=0.6.0,<1.0",
|
|
29
|
+
]
|
|
30
|
+
|
|
31
|
+
[project.urls]
|
|
32
|
+
Source = "https://github.com/democritus-project/d8s-timer"
|
|
33
|
+
Issues = "https://github.com/democritus-project/d8s-timer/issues"
|
|
34
|
+
|
|
35
|
+
[dependency-groups]
|
|
36
|
+
dev = [
|
|
37
|
+
"codecov>=2.1.13,<3.0",
|
|
38
|
+
"d8s-file-system>=0.10.0,<1.0",
|
|
39
|
+
"d8s-python>=0.9.0,<1.0",
|
|
40
|
+
"d8s-strings>=0.5.0,<1.0",
|
|
41
|
+
"ipython>=8.18.0,<10.0",
|
|
42
|
+
"mypy>=2.0,<3.0",
|
|
43
|
+
"pytest>=9.0,<10.0",
|
|
44
|
+
"pytest-cov>=7.0,<8.0",
|
|
45
|
+
"ruff>=0.15.0,<0.16.0",
|
|
46
|
+
]
|
|
47
|
+
|
|
48
|
+
[tool.hatch.build.targets.wheel]
|
|
49
|
+
packages = ["d8s_timer"]
|
|
50
|
+
|
|
51
|
+
[tool.ruff]
|
|
52
|
+
line-length = 120
|
|
53
|
+
target-version = "py310"
|
|
54
|
+
|
|
55
|
+
[tool.ruff.lint]
|
|
56
|
+
select = ["E", "F", "I"]
|
|
57
|
+
|
|
58
|
+
[tool.ruff.lint.per-file-ignores]
|
|
59
|
+
"d8s_timer/__init__.py" = ["F401", "F403"]
|
|
60
|
+
"tests/*" = ["E501"]
|
|
61
|
+
|
|
62
|
+
[tool.mypy]
|
|
63
|
+
ignore_missing_imports = true
|
|
64
|
+
|
|
65
|
+
[tool.pytest.ini_options]
|
|
66
|
+
addopts = "-v --cov=. --cov-report term-missing --cov-fail-under 90"
|
|
67
|
+
python_files = "tests/test_*.py"
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
|
|
3
|
+
"packages": {
|
|
4
|
+
".": {
|
|
5
|
+
"release-type": "python",
|
|
6
|
+
"package-name": "d8s_timer",
|
|
7
|
+
"include-component-in-tag": false,
|
|
8
|
+
"changelog-sections": [
|
|
9
|
+
{ "type": "feat", "section": "Features" },
|
|
10
|
+
{ "type": "fix", "section": "Bug Fixes" },
|
|
11
|
+
{ "type": "perf", "section": "Performance Improvements" },
|
|
12
|
+
{ "type": "deps", "section": "Dependencies" },
|
|
13
|
+
{ "type": "revert", "section": "Reverts" },
|
|
14
|
+
{ "type": "docs", "section": "Documentation", "hidden": true },
|
|
15
|
+
{ "type": "chore", "section": "Miscellaneous", "hidden": true },
|
|
16
|
+
{ "type": "refactor", "section": "Code Refactoring", "hidden": true },
|
|
17
|
+
{ "type": "style", "section": "Styles", "hidden": true },
|
|
18
|
+
{ "type": "test", "section": "Tests", "hidden": true },
|
|
19
|
+
{ "type": "build", "section": "Build System", "hidden": true },
|
|
20
|
+
{ "type": "ci", "section": "Continuous Integration", "hidden": true }
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
}
|
|
@@ -6,7 +6,7 @@ from d8s_timer import time_it, timer_get_time, timer_start, timer_stop
|
|
|
6
6
|
|
|
7
7
|
|
|
8
8
|
def test_timer_get_time_1():
|
|
9
|
-
timer_name =
|
|
9
|
+
timer_name = "foo"
|
|
10
10
|
timer_start(timer_name)
|
|
11
11
|
time.sleep(2)
|
|
12
12
|
current_time = timer_get_time(timer_name)
|
|
@@ -16,7 +16,7 @@ def test_timer_get_time_1():
|
|
|
16
16
|
|
|
17
17
|
def test_timer_get_time__invalid_name():
|
|
18
18
|
with pytest.raises(ValueError):
|
|
19
|
-
timer_get_time(
|
|
19
|
+
timer_get_time("foo")
|
|
20
20
|
|
|
21
21
|
|
|
22
22
|
def test_generic_timer_1():
|
|
@@ -31,7 +31,7 @@ def test_generic_timer__invalid_name():
|
|
|
31
31
|
timer_name = timer_start()
|
|
32
32
|
|
|
33
33
|
with pytest.raises(ValueError):
|
|
34
|
-
timer_stop(
|
|
34
|
+
timer_stop("foo")
|
|
35
35
|
|
|
36
36
|
timer_stop(timer_name)
|
|
37
37
|
|
|
@@ -42,7 +42,7 @@ def test_named_timer_1():
|
|
|
42
42
|
with pytest.raises(RuntimeError):
|
|
43
43
|
timer_start(timer_name)
|
|
44
44
|
|
|
45
|
-
timer_start(
|
|
45
|
+
timer_start("bar")
|
|
46
46
|
|
|
47
47
|
time.sleep(2)
|
|
48
48
|
|
|
@@ -51,7 +51,7 @@ def test_named_timer_1():
|
|
|
51
51
|
|
|
52
52
|
time.sleep(2)
|
|
53
53
|
|
|
54
|
-
bar_elapsed_time = timer_stop(
|
|
54
|
+
bar_elapsed_time = timer_stop("bar")
|
|
55
55
|
assert 4 < bar_elapsed_time < 5
|
|
56
56
|
|
|
57
57
|
|