Skip to content

Commit 54e0b60

Browse files
hugovkezio-melotti
andauthored
Add more linting (#109)
Co-authored-by: Ezio Melotti <[email protected]>
1 parent 0fa6d0a commit 54e0b60

File tree

9 files changed

+111
-86
lines changed

9 files changed

+111
-86
lines changed

.pre-commit-config.yaml

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,17 @@
11
repos:
2+
- repo: https://github.com/astral-sh/ruff-pre-commit
3+
rev: v0.3.5
4+
hooks:
5+
- id: ruff
6+
args: [--exit-non-zero-on-fix]
7+
28
- repo: https://github.com/pre-commit/pre-commit-hooks
3-
rev: v4.5.0
9+
rev: v4.6.0
410
hooks:
511
- id: check-added-large-files
612
- id: check-case-conflict
713
- id: check-merge-conflict
14+
- id: check-toml
815
- id: check-yaml
916
exclude: windows-release/azure-pipelines.yml
1017
- id: debug-statements

.ruff.toml

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
fix = true
2+
3+
[lint]
4+
select = [
5+
"C4", # flake8-comprehensions
6+
"E", # pycodestyle errors
7+
"F", # pyflakes errors
8+
"I", # isort
9+
"ISC", # flake8-implicit-str-concat
10+
"LOG", # flake8-logging
11+
"PGH", # pygrep-hooks
12+
"RUF100", # unused noqa (yesqa)
13+
"UP", # pyupgrade
14+
"W", # pycodestyle warnings
15+
"YTT", # flake8-2020
16+
]
17+
ignore = [
18+
"E203", # Whitespace before ':'
19+
"E221", # Multiple spaces before operator
20+
"E226", # Missing whitespace around arithmetic operator
21+
"E241", # Multiple spaces after ','
22+
"E501", # Line too long
23+
]

add-to-pydotorg.py

Lines changed: 35 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -22,19 +22,18 @@
2222
2323
Georg Brandl, March 2014.
2424
"""
25-
from __future__ import print_function
2625

2726
import hashlib
2827
import json
2928
import os
30-
from os import path
3129
import re
32-
import sys
33-
import time
3430
import subprocess
31+
import sys
32+
from os import path
3533

3634
import requests
3735

36+
3837
# Copied from release.py
3938
def error(*msgs):
4039
print('**ERROR**', file=sys.stderr)
@@ -138,7 +137,7 @@ def slug_for(release):
138137
('-' + release[len(base_version(release)):] if release[len(base_version(release)):] else '')
139138

140139
def sigfile_for(release, rfile):
141-
return download_root + '%s/%s.asc' % (release, rfile)
140+
return download_root + f'{release}/{rfile}.asc'
142141

143142
def md5sum_for(release, rfile):
144143
return hashlib.md5(open(ftp_root + base_version(release) + '/' + rfile, 'rb').read()).hexdigest()
@@ -164,33 +163,33 @@ def minor_version_tuple(release):
164163
def build_file_dict(release, rfile, rel_pk, file_desc, os_pk,
165164
add_download, add_desc):
166165
"""Return a dictionary with all needed fields for a ReleaseFile object."""
167-
d = dict(
168-
name = file_desc,
169-
slug = slug_for(release) + '-' + make_slug(file_desc)[:40],
170-
os = '/api/v1/downloads/os/%s/' % os_pk,
171-
release = '/api/v1/downloads/release/%s/' % rel_pk,
172-
description = add_desc,
173-
is_source = os_pk == 3,
174-
url = download_root + '%s/%s' % (base_version(release), rfile),
175-
md5_sum = md5sum_for(release, rfile),
176-
filesize = filesize_for(release, rfile),
177-
download_button = add_download,
178-
)
166+
d = {
167+
'name': file_desc,
168+
'slug': slug_for(release) + '-' + make_slug(file_desc)[:40],
169+
'os': '/api/v1/downloads/os/%s/' % os_pk,
170+
'release': '/api/v1/downloads/release/%s/' % rel_pk,
171+
'description': add_desc,
172+
'is_source': os_pk == 3,
173+
'url': download_root + f'{base_version(release)}/{rfile}',
174+
'md5_sum': md5sum_for(release, rfile),
175+
'filesize': filesize_for(release, rfile),
176+
'download_button': add_download,
177+
}
179178
# Upload GPG signature
180-
if os.path.exists(ftp_root + "%s/%s.asc" % (base_version(release), rfile)):
179+
if os.path.exists(ftp_root + f"{base_version(release)}/{rfile}.asc"):
181180
d["gpg_signature_file"] = sigfile_for(base_version(release), rfile)
182181
# Upload Sigstore signature
183-
if os.path.exists(ftp_root + "%s/%s.sig" % (base_version(release), rfile)):
184-
d["sigstore_signature_file"] = download_root + '%s/%s.sig' % (base_version(release), rfile)
182+
if os.path.exists(ftp_root + f"{base_version(release)}/{rfile}.sig"):
183+
d["sigstore_signature_file"] = download_root + f'{base_version(release)}/{rfile}.sig'
185184
# Upload Sigstore certificate
186-
if os.path.exists(ftp_root + "%s/%s.crt" % (base_version(release), rfile)):
187-
d["sigstore_cert_file"] = download_root + '%s/%s.crt' % (base_version(release), rfile)
185+
if os.path.exists(ftp_root + f"{base_version(release)}/{rfile}.crt"):
186+
d["sigstore_cert_file"] = download_root + f'{base_version(release)}/{rfile}.crt'
188187
# Upload Sigstore bundle
189-
if os.path.exists(ftp_root + "%s/%s.sigstore" % (base_version(release), rfile)):
190-
d["sigstore_bundle_file"] = download_root + '%s/%s.sigstore' % (base_version(release), rfile)
188+
if os.path.exists(ftp_root + f"{base_version(release)}/{rfile}.sigstore"):
189+
d["sigstore_bundle_file"] = download_root + f'{base_version(release)}/{rfile}.sigstore'
191190
# Upload SPDX SBOM file
192-
if os.path.exists(ftp_root + "%s/%s.spdx.json" % (base_version(release), rfile)):
193-
d["sbom_spdx2_file"] = download_root + '%s/%s.spdx.json' % (base_version(release), rfile)
191+
if os.path.exists(ftp_root + f"{base_version(release)}/{rfile}.spdx.json"):
192+
d["sbom_spdx2_file"] = download_root + f'{base_version(release)}/{rfile}.spdx.json'
194193

195194
return d
196195

@@ -206,36 +205,36 @@ def list_files(release):
206205
if rfile.startswith(prefix):
207206
break
208207
else:
209-
print(' File %s/%s has wrong prefix' % (reldir, rfile))
208+
print(f' File {reldir}/{rfile} has wrong prefix')
210209
continue
211210
if rfile.endswith('.chm'):
212211
if rfile[:-4] != 'python' + release.replace('.', ''):
213-
print(' File %s/%s has a different version' % (reldir, rfile))
212+
print(f' File {reldir}/{rfile} has a different version')
214213
continue
215214
else:
216215
try:
217216
prefix, rest = rfile.split('-', 1)
218-
except:
217+
except: # noqa: E722
219218
prefix, rest = rfile, ''
220219
if not rest.startswith((release + '-', release + '.')):
221-
print(' File %s/%s has a different version' % (reldir, rfile))
220+
print(f' File {reldir}/{rfile} has a different version')
222221
continue
223222
for rx, info in get_file_descriptions(release):
224223
if rx.search(rfile):
225224
file_desc, os_pk, add_download, add_desc = info
226225
yield rfile, file_desc, os_pk, add_download, add_desc
227226
break
228227
else:
229-
print(' File %s/%s not recognized' % (reldir, rfile))
228+
print(f' File {reldir}/{rfile} not recognized')
230229
continue
231230

232231
def query_object(objtype, **params):
233232
"""Find an API object by query parameters."""
234233
uri = base_url + 'downloads/%s/' % objtype
235-
uri += '?' + '&'.join('%s=%s' % v for v in params.items())
234+
uri += '?' + '&'.join(f'{k}={v}' for k, v in params.items())
236235
resp = requests.get(uri, headers=headers)
237236
if resp.status_code != 200 or not json.loads(resp.text)['objects']:
238-
raise RuntimeError('no object for %s params=%r' % (objtype, params))
237+
raise RuntimeError(f'no object for {objtype} params={params!r}')
239238
obj = json.loads(resp.text)['objects'][0]
240239
return int(obj['resource_uri'].strip('/').split('/')[-1])
241240

@@ -248,17 +247,17 @@ def post_object(objtype, datadict):
248247
info = json.loads(resp.text)
249248
print(info.get('error_message', 'No error message.'))
250249
print(info.get('traceback', ''))
251-
except:
250+
except: # noqa: E722
252251
pass
253-
print('Creating %s failed: %s' % (objtype, resp.status_code))
252+
print(f'Creating {objtype} failed: {resp.status_code}')
254253
return -1
255254
newloc = resp.headers['Location']
256255
pk = int(newloc.strip('/').split('/')[-1])
257256
return pk
258257

259258
def sign_release_files_with_sigstore(release, release_files):
260259
filenames = [
261-
ftp_root + "%s/%s" % (base_version(release), rfile)
260+
ftp_root + f"{base_version(release)}/{rfile}"
262261
for rfile, file_desc, os_pk, add_download, add_desc in release_files
263262
]
264263

release.py

Lines changed: 16 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,12 +12,11 @@
1212
import optparse
1313
import os
1414
import re
15-
import readline # noqa
15+
import readline # noqa: F401
1616
import shutil
1717
import subprocess
1818
import sys
1919
import tempfile
20-
2120
from contextlib import contextmanager
2221

2322
COMMASPACE = ', '
@@ -72,7 +71,7 @@ def chdir_to_repo_root():
7271
def test_first_line(filename, test):
7372
if not os.path.exists(filename):
7473
return False
75-
with open(filename, "rt") as f:
74+
with open(filename) as f:
7675
lines = f.read().split('\n')
7776
if not (lines and test(lines[0])):
7877
return False
@@ -168,12 +167,12 @@ def tweak_patchlevel(tag, done=False):
168167
169168
/* Version as a string */
170169
#define PY_VERSION \t\"{tag.text}{plus}"'''.strip()
171-
level_def = dict(
172-
a = 'PY_RELEASE_LEVEL_ALPHA',
173-
b = 'PY_RELEASE_LEVEL_BETA',
174-
rc = 'PY_RELEASE_LEVEL_GAMMA',
175-
f = 'PY_RELEASE_LEVEL_FINAL',
176-
)[tag.level]
170+
level_def = {
171+
'a': 'PY_RELEASE_LEVEL_ALPHA',
172+
'b': 'PY_RELEASE_LEVEL_BETA',
173+
'rc': 'PY_RELEASE_LEVEL_GAMMA',
174+
'f': 'PY_RELEASE_LEVEL_FINAL',
175+
}[tag.level]
177176
new_constants = template.format(tag=tag, level_def=level_def,
178177
plus=done and '+' or '')
179178
if tag.as_tuple() >= (3, 7, 0, 'a', 3):
@@ -254,7 +253,7 @@ def tarball(source, clamp_mtime):
254253
# Sorts the entries in the tarball by name.
255254
"--sort=name",
256255
# Sets a maximum 'modified time' of entries in tarball.
257-
"--mtime=%s" % (clamp_mtime,), "--clamp-mtime",
256+
f"--mtime={clamp_mtime}", "--clamp-mtime",
258257
# Sets the owner uid and gid to 0.
259258
"--owner=0", "--group=0", "--numeric-owner",
260259
# Omits process ID, file access, and status change times.
@@ -370,7 +369,7 @@ def build_docs():
370369
with tempfile.TemporaryDirectory() as venv:
371370
run_cmd(['python3', '-m', 'venv', venv])
372371
pip = os.path.join(venv, 'bin', 'pip')
373-
run_cmd([pip, 'install', '-r' 'Doc/requirements.txt'])
372+
run_cmd([pip, 'install', '-r', 'Doc/requirements.txt'])
374373
sphinx_build = os.path.join(venv, 'bin', 'sphinx-build')
375374
blurb = os.path.join(venv, 'bin', 'blurb')
376375
with pushd('Doc'):
@@ -389,11 +388,11 @@ def scp(from_loc, to_loc):
389388
scp('src', '/data/python-releases/%s' % tag.nickname)
390389
print("Upload doc tarballs")
391390
scp('docs', '/data/python-releases/doc/%s' % tag.nickname)
392-
print("* Now change the permissions on the tarballs so they are " \
393-
"writable by the webmaster group. *")
391+
print("* Now change the permissions on the tarballs so they are "
392+
"writable by the webmaster group. *")
394393

395394

396-
class Tag(object):
395+
class Tag:
397396

398397
def __init__(self, tag_name):
399398
# if tag is ".", use current directory name as tag
@@ -424,13 +423,13 @@ def __init__(self, tag_name):
424423
self.text = self.normalized()
425424
if self.level != "f":
426425
self.text += self.level + str(self.serial)
427-
self.basic_version = '%s.%s' % (self.major, self.minor)
426+
self.basic_version = f'{self.major}.{self.minor}'
428427

429428
def __str__(self):
430429
return self.text
431430

432431
def normalized(self):
433-
return "{}.{}.{}".format(self.major, self.minor, self.patch)
432+
return f"{self.major}.{self.minor}.{self.patch}"
434433

435434
@property
436435
def branch(self):
@@ -467,7 +466,7 @@ def committed_at(self):
467466
# Fetch the epoch of the tagged commit for build reproducibility.
468467
proc = subprocess.run(["git", "log", self.gitname, "-1", "--pretty=%ct"], stdout=subprocess.PIPE)
469468
if proc.returncode != 0:
470-
error("Couldn't fetch the epoch of tag %s" % (self.gitname,))
469+
error(f"Couldn't fetch the epoch of tag {self.gitname}")
471470
return datetime.datetime.fromtimestamp(int(proc.stdout.decode().strip()), tz=datetime.timezone.utc)
472471

473472

run_release.py

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -11,21 +11,19 @@
1111
import contextlib
1212
import functools
1313
import getpass
14-
import itertools
1514
import json
1615
import os
1716
import pathlib
1817
import re
1918
import shelve
2019
import shutil
2120
import subprocess
22-
import tempfile
21+
import sys
2322
import time
2423
import urllib.request
25-
import sys
2624
from dataclasses import dataclass
2725
from shelve import DbfilenameShelf
28-
from typing import Callable, Iterator, List, Optional, final
26+
from typing import Callable, Iterator, List, Optional
2927

3028
import aiohttp
3129
import gnupg
@@ -34,8 +32,8 @@
3432
from alive_progress import alive_bar
3533

3634
import release as release_mod
37-
from buildbotapi import BuildBotAPI
3835
import sbom
36+
from buildbotapi import BuildBotAPI
3937

4038
API_KEY_REGEXP = re.compile(r"(?P<major>\w+):(?P<minor>\w+)")
4139

@@ -443,7 +441,7 @@ def run_autoconf(db: DbfilenameShelf) -> None:
443441

444442
def check_pyspecific(db):
445443
with open(
446-
db["git_repo"] / "Doc" / "tools" / "extensions" / "pyspecific.py", "r"
444+
db["git_repo"] / "Doc" / "tools" / "extensions" / "pyspecific.py"
447445
) as pyspecific:
448446
for line in pyspecific:
449447
if "SOURCE_URI =" in line:
@@ -557,20 +555,20 @@ def put_dir(self, source, target, progress=None):
557555
for item in os.listdir(source):
558556
if os.path.isfile(os.path.join(source, item)):
559557
progress.text(item)
560-
self.put(os.path.join(source, item), "%s/%s" % (target, item))
558+
self.put(os.path.join(source, item), f"{target}/{item}")
561559
progress()
562560
else:
563-
self.mkdir("%s/%s" % (target, item), ignore_existing=True)
561+
self.mkdir(f"{target}/{item}", ignore_existing=True)
564562
self.put_dir(
565563
os.path.join(source, item),
566-
"%s/%s" % (target, item),
564+
f"{target}/{item}",
567565
progress=progress,
568566
)
569567

570568
def mkdir(self, path, mode=511, ignore_existing=False):
571569
try:
572570
super().mkdir(path, mode)
573-
except IOError:
571+
except OSError:
574572
if ignore_existing:
575573
pass
576574
else:

sbom.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,9 @@
2121
import subprocess
2222
import sys
2323
import tarfile
24+
import typing
2425
import zipfile
2526
from urllib.request import urlopen
26-
import typing
2727

2828

2929
def spdx_id(value: str) -> str:

size.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,16 +2,16 @@
22

33
"""Dump the sizes for the given files, suitable for pasting into content.ht"""
44

5+
import hashlib
56
import os
67
import sys
7-
import hashlib
88

99
DOT = '.'
1010

1111

1212
# For consistency with historical use.
13-
sort_order = dict((ext, i) for i, ext in enumerate(
14-
('tgz', 'tar.bz2', 'tar.xz', 'pdb.zip', 'amd64.msi', 'msi', 'chm', 'dmg')))
13+
sort_order = {ext: i for i, ext in enumerate(
14+
('tgz', 'tar.bz2', 'tar.xz', 'pdb.zip', 'amd64.msi', 'msi', 'chm', 'dmg'))}
1515

1616

1717
def ignore(filename):
@@ -35,4 +35,4 @@ def key(filename):
3535
with open(filename, 'rb') as fp:
3636
md5.update(fp.read())
3737
size = os.stat(filename).st_size
38-
print(' {} {:8} {}'.format(md5.hexdigest(), size, filename))
38+
print(f' {md5.hexdigest()} {size:8} {filename}')

0 commit comments

Comments
 (0)