Skip to content

Commit 7ea0b1f

Browse files
authored
Merge branch 'main' into fix-fractional-whole-rounding
2 parents 1b879cc + 7c98e00 commit 7ea0b1f

6 files changed

Lines changed: 186 additions & 11 deletions

File tree

Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
# Run gh-profiler against the author of each new issue.
2+
# Delete the profile output when the issue is closed.
3+
# PR authors are profiled by the unprivileged profile-pr-authors.yml instead,
4+
# so no dangerous trigger is needed for PRs from forks.
5+
6+
name: Profile issue authors
7+
8+
on:
9+
issues:
10+
types: [opened, closed]
11+
12+
jobs:
13+
profile-author:
14+
if: github.event.action == 'opened'
15+
16+
permissions:
17+
issues: write
18+
19+
runs-on: ubuntu-latest
20+
21+
steps:
22+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
23+
with:
24+
enable-cache: false
25+
ignore-empty-workdir: true
26+
27+
- name: Run gh-profiler (=== Expand this to see full profile output ===)
28+
env:
29+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
30+
LOGIN: ${{ github.event.issue.user.login }}
31+
run: |
32+
uvx gh-profiler@latest "$LOGIN" --concise > profiler.txt
33+
echo
34+
echo "======================== Full profile ========================="
35+
echo
36+
uvx gh-profiler@latest "$LOGIN"
37+
echo
38+
echo "==============================================================="
39+
40+
- name: Comment on issue
41+
env:
42+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
43+
SERVER_URL: ${{ github.server_url }}
44+
REPOSITORY: ${{ github.repository }}
45+
RUN_ID: ${{ github.run_id }}
46+
CHECK_RUN_ID: ${{ job.check_run_id }}
47+
NUMBER: ${{ github.event.issue.number }}
48+
run: |
49+
{
50+
echo "<!-- gh-profiler:profile-link run-id=$RUN_ID -->"
51+
echo "Profile summary:"
52+
echo
53+
echo '```text'
54+
cat profiler.txt
55+
echo '```'
56+
echo
57+
echo "<a href=\"$SERVER_URL/$REPOSITORY/actions/runs/$RUN_ID/job/$CHECK_RUN_ID\">Full profile</a>"
58+
echo
59+
echo "(This comment and the linked profile output will auto-delete when this issue is closed.)"
60+
} > body.txt
61+
62+
jq -Rs '{body: .}' body.txt > payload.json
63+
64+
gh api \
65+
"repos/$REPOSITORY/issues/$NUMBER/comments" \
66+
--input payload.json
67+
68+
delete-profile:
69+
if: github.event.action == 'closed'
70+
71+
permissions:
72+
actions: write
73+
issues: write
74+
75+
runs-on: ubuntu-latest
76+
77+
steps:
78+
- name: Delete profile comment
79+
env:
80+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
81+
REPOSITORY: ${{ github.repository }}
82+
NUMBER: ${{ github.event.issue.number }}
83+
run: |
84+
gh api --paginate \
85+
"repos/$REPOSITORY/issues/$NUMBER/comments" \
86+
--jq '
87+
.[]
88+
| select(.user.login == "github-actions[bot]")
89+
| select(.body | startswith("<!-- gh-profiler:profile-link run-id="))
90+
| [.id, (.body | capture("gh-profiler:profile-link run-id=(?<id>[0-9]+)").id)]
91+
| @tsv
92+
' |
93+
while IFS=$'\t' read -r comment_id run_id; do
94+
echo "Deleting logs from workflow run $run_id."
95+
gh api --method DELETE \
96+
"repos/$REPOSITORY/actions/runs/$run_id/logs"
97+
98+
echo "Deleting profile comment $comment_id."
99+
gh api --method DELETE \
100+
"repos/$REPOSITORY/issues/comments/$comment_id"
101+
done
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
# Run gh-profiler against the author of each new PR and show the output in
2+
# the job log and step summary, reachable via the PR's checks.
3+
#
4+
# This runs unprivileged (read-only token, safe for PRs from forks), so it
5+
# cannot post a comment like profile-issue-authors.yml does for issues.
6+
# There is also nothing to delete when the PR is closed: the output expires
7+
# with the run logs.
8+
9+
name: Profile PR authors
10+
11+
on:
12+
pull_request:
13+
types: [opened]
14+
15+
permissions:
16+
contents: read
17+
18+
jobs:
19+
profile-author:
20+
runs-on: ubuntu-latest
21+
22+
steps:
23+
- uses: astral-sh/setup-uv@20cfd1bf945f4377ade1205e4dbc17946fc9a30d # v10.0.1
24+
with:
25+
enable-cache: false
26+
ignore-empty-workdir: true
27+
28+
- name: Run gh-profiler (=== Expand this to see full profile output ===)
29+
env:
30+
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
31+
LOGIN: ${{ github.event.pull_request.user.login }}
32+
run: |
33+
uvx gh-profiler@latest "$LOGIN" > profiler.txt
34+
cat profiler.txt
35+
{
36+
echo '```text'
37+
cat profiler.txt
38+
echo '```'
39+
} >> "$GITHUB_STEP_SUMMARY"

.github/workflows/release.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
run: |
3737
scripts/generate-translation-binaries.sh
3838
39-
- uses: hynek/build-and-inspect-python-package@d44ca7d91762de7a7d5436ddae667c6da6d1c3df # v2.18.0
39+
- uses: hynek/build-and-inspect-python-package@2abe76da66d0a6a4a227101f9348ee855797cfa5 # v3.0.1
4040

4141
# Upload to Test PyPI on every commit on main.
4242
release-test-pypi:
@@ -59,7 +59,7 @@ jobs:
5959
path: dist
6060

6161
- name: Upload package to Test PyPI
62-
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
62+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2
6363
with:
6464
repository-url: https://test.pypi.org/legacy/
6565

@@ -83,4 +83,4 @@ jobs:
8383
path: dist
8484

8585
- name: Upload package to PyPI
86-
uses: pypa/gh-action-pypi-publish@ba38be9e461d3875417946c167d0b5f3d385a247 # v1.14.1
86+
uses: pypa/gh-action-pypi-publish@dc37677b2e1c63e2034f94d8a5b11f265b73ba33 # v1.14.2

.pre-commit-config.yaml

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,78 +1,109 @@
1+
priorities:
2+
fix: 0
3+
fix-py: 10
4+
fix-eol: 20
5+
fix-whitespace: 30
6+
check: 40
7+
18
repos:
29
- repo: https://github.com/astral-sh/ruff-pre-commit
3-
rev: v0.15.20
10+
rev: v0.16.5
411
hooks:
512
- id: ruff-check
613
args: [--exit-non-zero-on-fix]
14+
priority: fix
715

816
- repo: https://github.com/psf/black-pre-commit-mirror
917
rev: 26.5.1
1018
hooks:
1119
- id: black
20+
priority: fix-py
1221

1322
- repo: https://github.com/pre-commit/pre-commit-hooks
1423
rev: v6.0.0
1524
hooks:
1625
- id: check-added-large-files
26+
priority: check
1727
- id: check-case-conflict
28+
priority: check
1829
- id: check-merge-conflict
30+
priority: check
1931
- id: check-json
32+
priority: check
2033
- id: check-toml
34+
priority: check
2135
- id: check-yaml
36+
priority: check
2237
- id: debug-statements
38+
priority: check
2339
- id: end-of-file-fixer
40+
priority: fix-eol
2441
- id: forbid-submodules
42+
priority: check
2543
- id: requirements-txt-fixer
44+
priority: fix
2645
- id: trailing-whitespace
2746
exclude: \.github/ISSUE_TEMPLATE\.md|\.github/PULL_REQUEST_TEMPLATE\.md
47+
priority: fix-whitespace
2848

2949
- repo: https://github.com/python-jsonschema/check-jsonschema
30-
rev: 0.37.4
50+
rev: 0.38.0
3151
hooks:
3252
- id: check-github-workflows
53+
priority: check
3354
- id: check-renovate
55+
priority: check
3456

3557
- repo: https://github.com/rhysd/actionlint
3658
rev: v1.7.12
3759
hooks:
3860
- id: actionlint
61+
priority: check
3962

4063
- repo: https://github.com/zizmorcore/zizmor-pre-commit
41-
rev: v1.26.1
64+
rev: v1.29.0
4265
hooks:
4366
- id: zizmor
67+
priority: check
4468

4569
- repo: https://github.com/tox-dev/pyproject-fmt
46-
rev: v2.25.1
70+
rev: v2.28.2
4771
hooks:
4872
- id: pyproject-fmt
73+
priority: fix
4974

5075
- repo: https://github.com/abravalheri/validate-pyproject
51-
rev: v0.25
76+
rev: "0.26"
5277
hooks:
5378
- id: validate-pyproject
79+
priority: check
5480

5581
- repo: https://github.com/tox-dev/tox-ini-fmt
56-
rev: 1.7.1
82+
rev: 1.9.0
5783
hooks:
5884
- id: tox-ini-fmt
85+
priority: fix
5986

6087
- repo: https://github.com/google/yamlfmt
6188
rev: v0.21.0
6289
hooks:
6390
- id: yamlfmt
91+
priority: fix
6492

6593
- repo: https://github.com/rbubley/mirrors-prettier
66-
rev: v3.9.4
94+
rev: v3.9.6
6795
hooks:
6896
- id: prettier
6997
args: [--prose-wrap=always, --print-width=88]
7098
exclude: \.github/ISSUE_TEMPLATE\.md|\.github/PULL_REQUEST_TEMPLATE\.md
99+
priority: fix
71100

72101
- repo: meta
73102
hooks:
74103
- id: check-hooks-apply
104+
priority: check
75105
- id: check-useless-excludes
106+
priority: check
76107

77108
ci:
78109
autoupdate_schedule: quarterly

pyproject.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,9 @@ lint.select = [
7373
"PT", # flake8-pytest-style
7474
"PYI", # flake8-pyi
7575
"RUF022", # unsorted-dunder-all
76+
"RUF046", # unnecessary-cast-to-int
7677
"RUF100", # unused noqa (yesqa)
78+
"TID251", # flake8-tidy-imports: banned-api
7779
"UP", # pyupgrade
7880
"W", # pycodestyle warnings
7981
"YTT", # flake8-2020
@@ -91,6 +93,7 @@ lint.per-file-ignores."tests/*" = [
9193
lint.flake8-import-conventions.aliases.datetime = "dt"
9294
lint.flake8-import-conventions.banned-from = [ "datetime" ]
9395
lint.flake8-pytest-style.parametrize-names-type = "csv"
96+
lint.flake8-tidy-imports.banned-api."typing.TYPE_CHECKING".msg = "Use TYPE_CHECKING = False instead"
9497
lint.isort.known-first-party = [ "humanize" ]
9598
lint.isort.required-imports = [ "from __future__ import annotations" ]
9699
lint.pydocstyle.convention = "google"
@@ -102,6 +105,7 @@ max_supported_python = "3.15"
102105
[tool.mypy]
103106
strict = true
104107
pretty = true
108+
num_workers = 4
105109
show_error_codes = true
106110

107111
[tool.pytest]

src/humanize/number.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -542,7 +542,7 @@ def metric(value: float, unit: str = "", precision: int = 3) -> str:
542542

543543
if not math.isfinite(value):
544544
return _format_not_finite(value)
545-
exponent = int(math.floor(math.log10(abs(value)))) if value != 0 else 0
545+
exponent = math.floor(math.log10(abs(value))) if value != 0 else 0
546546

547547
if exponent >= 33 or exponent < -30:
548548
return scientific(value, precision - 1) + unit

0 commit comments

Comments
 (0)