Skip to content

Commit 1e3d9c4

Browse files
committed
Merge branch 'main' into feature/python-3-14
2 parents 0545220 + 3a2d482 commit 1e3d9c4

19 files changed

+192
-47
lines changed

.github/workflows/documentation.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
name: Build Documentation
2-
32
on:
43
pull_request:
54
branches: [main]
6-
75
jobs:
86
build:
97
runs-on: ubuntu-latest
108
strategy:
119
fail-fast: false
12-
1310
steps:
1411
- uses: actions/checkout@v3
1512
- name: Set up Python 3.12

.github/workflows/pre-commit.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,12 @@
11
name: Run Pre-commit
2-
32
on:
43
pull_request:
54
branches: [main]
6-
75
jobs:
86
build:
97
runs-on: ubuntu-latest
108
strategy:
119
fail-fast: false
12-
1310
steps:
1411
- uses: actions/checkout@v3
1512
- name: Set up Python 3.12

.github/workflows/unit-tests.yaml

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,14 @@
11
name: Unit Tests
2-
32
on:
43
pull_request:
54
branches: [main]
6-
75
jobs:
86
build:
97
runs-on: ubuntu-latest
108
strategy:
119
fail-fast: false
1210
matrix:
1311
python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14.0-beta.1"]
14-
1512
steps:
1613
- uses: actions/checkout@v3
1714
- name: Set up Python ${{ matrix.python-version }}

.pre-commit-config.yaml

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,17 @@ repos:
77
- id: check-yaml
88
- id: check-added-large-files
99
args: [--enforce-all, --maxkb=100]
10+
- repo: https://github.com/google/yamlfmt
11+
rev: v0.16.0
12+
hooks:
13+
- id: yamlfmt
14+
- repo: https://github.com/hhatto/autopep8
15+
rev: v2.3.2
16+
hooks:
17+
- id: autopep8
18+
exclude: docs/source/conf.py
1019
- repo: https://github.com/pycqa/isort
11-
rev: 5.13.2
20+
rev: 6.0.1
1221
hooks:
1322
- id: isort
1423
- repo: https://github.com/jumanjihouse/pre-commit-hooks
@@ -24,12 +33,12 @@ repos:
2433
- id: forbid-crlf
2534
- id: forbid-tabs
2635
- repo: https://github.com/streetsidesoftware/cspell-cli
27-
rev: v8.17.0
36+
rev: v9.0.1
2837
hooks:
2938
- id: cspell
3039
exclude: \.gitignore|.*\.properties
3140
- repo: https://github.com/pycqa/flake8
32-
rev: 7.1.1
41+
rev: 7.2.0
3342
hooks:
3443
- id: flake8
3544
args: [--max-line-length=150]
@@ -39,14 +48,14 @@ repos:
3948
hooks:
4049
- id: pydocstyle
4150
additional_dependencies: ["tomli"]
42-
exclude: examples|tests|conf.py
51+
exclude: examples|tests|.pre-commit-hooks|conf.py
4352
- repo: https://github.com/regebro/pyroma
44-
rev: f4ef6995f6c054586fe6d5d33d180abe71ebabd0
53+
rev: "4.2"
4554
hooks:
46-
- id: pyroma
47-
args: ["-d", "--min=10", ".", "--skip-tests", "ValidREST"]
55+
- id: pyroma
56+
args: ["-d", "--min=10", "."]
4857
- repo: https://github.com/pre-commit/mirrors-mypy
49-
rev: v1.14.1
58+
rev: v1.15.0
5059
hooks:
5160
- id: mypy
5261
additional_dependencies: ["types-docutils", "types-python-dateutil", "types-requests"]
@@ -59,3 +68,11 @@ repos:
5968
- --template
6069
- (C) Crown Copyright [OWNER]
6170
- --owner=GCHQ
71+
- repo: local
72+
hooks:
73+
- id: double-string-fixer
74+
name: string fixer
75+
description: Replace single-quoted strings with double-quoted strings
76+
types: [python]
77+
language: python
78+
entry: python3 .pre-commit-hooks/double_string_fixer.py
Lines changed: 117 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,117 @@
1+
"""
2+
A copy of https://github.com/pre-commit/pre-commit-hooks/tree/main#double-quote-string-fixer,
3+
except it replaces single-quoted strings with double-quoted strings.
4+
5+
Copyright (c) 2014 pre-commit dev team: Anthony Sottile, Ken Struys
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+
"""
25+
from __future__ import annotations
26+
27+
import argparse
28+
import io
29+
import re
30+
import sys
31+
import tokenize
32+
from typing import Sequence
33+
34+
if sys.version_info >= (3, 12): # pragma: >=3.12 cover
35+
FSTRING_START = tokenize.FSTRING_START
36+
FSTRING_END = tokenize.FSTRING_END
37+
else: # pragma: <3.12 cover
38+
FSTRING_START = FSTRING_END = -1
39+
40+
START_QUOTE_RE = re.compile("^[a-zA-Z]*'")
41+
42+
43+
def handle_match(token_text: str) -> str:
44+
if '"""' in token_text or "'''" in token_text:
45+
return token_text
46+
47+
match = START_QUOTE_RE.match(token_text)
48+
if match is not None:
49+
meat = token_text[match.end():-1]
50+
if '"' in meat or "'" in meat:
51+
return token_text
52+
else:
53+
return match.group().replace("'", '"') + meat + '"'
54+
else:
55+
return token_text
56+
57+
58+
def get_line_offsets_by_line_no(src: str) -> list[int]:
59+
# Padded so we can index with line number
60+
offsets = [-1, 0]
61+
for line in src.splitlines(True):
62+
offsets.append(offsets[-1] + len(line))
63+
return offsets
64+
65+
66+
def fix_strings(filename: str) -> int:
67+
with open(filename, encoding="UTF-8", newline="") as f:
68+
contents = f.read()
69+
line_offsets = get_line_offsets_by_line_no(contents)
70+
71+
# Basically a mutable string
72+
splitcontents = list(contents)
73+
74+
fstring_depth = 0
75+
76+
# Iterate in reverse so the offsets are always correct
77+
tokens_l = list(tokenize.generate_tokens(io.StringIO(contents).readline))
78+
tokens = reversed(tokens_l)
79+
for token_type, token_text, (srow, scol), (erow, ecol), _ in tokens:
80+
if token_type == FSTRING_START: # pragma: >=3.12 cover
81+
fstring_depth += 1
82+
elif token_type == FSTRING_END: # pragma: >=3.12 cover
83+
fstring_depth -= 1
84+
elif fstring_depth == 0 and token_type == tokenize.STRING:
85+
new_text = handle_match(token_text)
86+
splitcontents[
87+
line_offsets[srow] + scol:
88+
line_offsets[erow] + ecol
89+
] = new_text
90+
91+
new_contents = "".join(splitcontents)
92+
if contents != new_contents:
93+
with open(filename, "w", encoding="UTF-8", newline="") as f:
94+
f.write(new_contents)
95+
return 1
96+
else:
97+
return 0
98+
99+
100+
def main(argv: Sequence[str] | None = None) -> int:
101+
parser = argparse.ArgumentParser()
102+
parser.add_argument("filenames", nargs="*", help="Filenames to fix")
103+
args = parser.parse_args(argv)
104+
105+
retv = 0
106+
107+
for filename in args.filenames:
108+
return_value = fix_strings(filename)
109+
if return_value != 0:
110+
print(f"Fixing strings in {filename}")
111+
retv |= return_value
112+
113+
return retv
114+
115+
116+
if __name__ == "__main__":
117+
raise SystemExit(main())

.readthedocs.yaml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,14 @@
1-
21
# Read the Docs configuration file for Sphinx projects
32
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
4-
53
version: 2
6-
74
build:
85
os: ubuntu-22.04
96
tools:
107
python: "3.12"
11-
128
sphinx:
139
configuration: docs/source/conf.py
1410
builder: "html"
1511
fail_on_warning: true
16-
1712
python:
18-
install:
13+
install:
1914
- requirements: docs/requirements.txt

CONTRIBUTING.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ To run the checks at any time:
3131
$ pre-commit run --all-files
3232
```
3333

34+
Please do not add any new pre-commit checks yourself and instead raise a ticket.
35+
3436
### Tests
3537

3638
Before opening a pull request, please ensure that the tests pass. To do this, run the following:
@@ -80,11 +82,20 @@ $ python3 -m sphinx -b linkcheck docs/source docs/build # check that all links
8082

8183
## Coding Standards and Conventions
8284

83-
Concourse Tools is a fully-typed library, so please ensure all functions, methods and classes are fully typed. Although
84-
we tend to make use of future annotations (`from __future__ import annotations`) please continue using the `typing`
85-
module for all types to ensure compatibility with our documentation.
85+
Concourse Tools is a fully-typed library, so please ensure all functions, methods and classes are fully typed.
8686

8787
Concourse Tools uses [Sphinx-style docstrings](https://sphinx-rtd-tutorial.readthedocs.io/en/latest/docstrings.html).
8888

8989
This project aims to depend only on the standard library, so contributions which add additional dependencies outside of
9090
the standard library are likely to be rejected unless absolutely necessary.
91+
92+
93+
### Style Guide
94+
95+
Concourse Tools does not have an explicit style guide outside of the pre-commit checks for enforcing PEP8 and double-quote strings.
96+
However, please ensure your code is as readable and clear as possible. Reviewers will highlight any code changes they feel
97+
is inconsistent or difficult to parse.
98+
99+
Please refrain from running Black over the code, as it can cause readability issues for nested statements.
100+
101+
Finally, please do not refactor "other people's" code when submitting a pull request.

concoursetools/cli/docstring.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,6 @@ def _pair_up(data: list[str]) -> Generator[tuple[str, str], None, None]:
7676
"""
7777
for i in range(0, len(data), 2):
7878
try:
79-
yield data[i], data[i+1]
79+
yield data[i], data[i + 1]
8080
except IndexError:
8181
raise ValueError(f"Needed an even number of values, got {len(data)}")

concoursetools/mocking.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,7 +202,7 @@ def _get_folder_as_dict(self, folder_path: Path, max_depth: int = 2, encoding: s
202202
first_chunk = rf.read(byte_limit)
203203
folder_dict[item.name] = first_chunk
204204
elif item.is_dir():
205-
folder_dict[item.name] = self._get_folder_as_dict(item, max_depth=max_depth-1, encoding=encoding)
205+
folder_dict[item.name] = self._get_folder_as_dict(item, max_depth=max_depth - 1, encoding=encoding)
206206
return folder_dict
207207

208208
def _set_folder_from_dict(self, folder_path: Path, folder_dict: FolderDict, encoding: str | None = None) -> None:

cspell.config.yaml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
version: "0.2"
22
language: en-GB
3-
useGitignore: true,
3+
useGitignore: true
44
ignorePaths:
55
- tests
66
- requirements*.txt
77
- .pre-commit-config.yaml
8+
- .pre-commit-hooks/*
89
dictionaries:
910
- python
1011
words:

0 commit comments

Comments
 (0)