From 89e75d20019d32581a310bb8d4d54f8e53a04c2f Mon Sep 17 00:00:00 2001 From: Dave Evans Date: Tue, 22 Sep 2026 12:13:59 +0100 Subject: [PATCH 1/5] Apply fixes from the latest version of Ruff Closes #2051 --- hooks/ehrql_branch.py | 2 +- scripts/__init__.py | 0 scripts/wordcount.py | 4 ++-- 3 files changed, 3 insertions(+), 3 deletions(-) create mode 100644 scripts/__init__.py diff --git a/hooks/ehrql_branch.py b/hooks/ehrql_branch.py index 3f2b6dcf9..9e3af0f18 100644 --- a/hooks/ehrql_branch.py +++ b/hooks/ehrql_branch.py @@ -19,7 +19,7 @@ def on_config(config): ehrql_nav_index, ehrql_nav_section = next( (i, section) for i, section in enumerate(config["nav"]) - if list(section.keys())[0] == "ehrQL" + if next(iter(section.keys())) == "ehrQL" ) new_import_string = ehrql_nav_section["ehrQL"].replace( "branch=main", f"branch={ehrql_branch}" diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/scripts/wordcount.py b/scripts/wordcount.py index 1eea5af67..d1e2deae3 100644 --- a/scripts/wordcount.py +++ b/scripts/wordcount.py @@ -1,5 +1,5 @@ -from html.parser import HTMLParser import sys +from html.parser import HTMLParser class ArticleParser(HTMLParser): @@ -24,7 +24,7 @@ def handle_data(self, data): if __name__ == "__main__": total = 0 for filename in sys.argv[1:]: - with open(filename, "r", encoding="utf-8") as f: + with open(filename, encoding="utf-8") as f: parser = ArticleParser() parser.feed(f.read()) text = " ".join(parser.text) From 80482631b2204118e63539a0af424e110d3d6288 Mon Sep 17 00:00:00 2001 From: Dave Evans Date: Tue, 22 Sep 2026 12:16:29 +0100 Subject: [PATCH 2/5] Exclude legacy docs from Ruff formatting --- pyproject.toml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/pyproject.toml b/pyproject.toml index dffbe0385..5702c6285 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -15,6 +15,8 @@ exclude = [ "docker", "htmlcov", "venv", + # These are frozen and we don't intend to update them + "docs/legacy", ] [tool.ruff.lint] From 70ff69a41fc710671f451f0f6fd2294570bbfac0 Mon Sep 17 00:00:00 2001 From: Dave Evans Date: Tue, 22 Sep 2026 12:23:23 +0100 Subject: [PATCH 3/5] Exclude docs example from Ruff formatting This is clearer split over multiple lines and without the trailing comma. --- docs/case-control-studies.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/docs/case-control-studies.md b/docs/case-control-studies.md index d6bb6c7fc..0b902e879 100644 --- a/docs/case-control-studies.md +++ b/docs/case-control-studies.md @@ -185,6 +185,7 @@ matched_patients = table_from_file( ``` This allows us to only include the matched controls in our dataset. + ```python from ehrql import create_dataset @@ -193,6 +194,7 @@ dataset.define_population( matched_patients.exists_for_patient() ) ``` + Don't forget to add additional population constraints to the dataset if you require them! The `index_date` column in `matched_patients` is the date generated by the matching process, From a30921e8cbca8774227bb021c91f3f0f85a88162 Mon Sep 17 00:00:00 2001 From: Dave Evans Date: Tue, 22 Sep 2026 12:24:34 +0100 Subject: [PATCH 4/5] Apply Ruff formatting fixes to code in Markdown Ruff now includes such code automatically. --- docs/actions-reusable.md | 5 +++-- docs/case-control-studies.md | 24 ++++++++++++------------ docs/federation.md | 21 +++++++++++---------- 3 files changed, 26 insertions(+), 24 deletions(-) diff --git a/docs/actions-reusable.md b/docs/actions-reusable.md index 90230a4fc..fc490c833 100644 --- a/docs/actions-reusable.md +++ b/docs/actions-reusable.md @@ -72,10 +72,11 @@ Where *action/cli.py* is: ```python def main(): - print("A reusable action") + print("A reusable action") + if __name__ == "__main__": - main() + main() ``` When developing a reusable action, just as when developing a scripted action, the action's dependencies are made available by the runtime; they are not made available by the action. diff --git a/docs/case-control-studies.md b/docs/case-control-studies.md index 0b902e879..b7fe62b78 100644 --- a/docs/case-control-studies.md +++ b/docs/case-control-studies.md @@ -175,12 +175,12 @@ from ehrql import table_from_file CONTROLS = "output/matched_matches.arrow" matched_patients = table_from_file( - CONTROLS, - columns={ - "age": int, - "sex": str, - "index_date": datetime.date - } + CONTROLS, + columns={ + "age": int, + "sex": str, + "index_date": datetime.date, + }, ) ``` @@ -227,12 +227,12 @@ CONTROLS = "output/matched_matches.arrow" codelist = codelist_from_csv("codelists/codelist.csv") matched_patients = table_from_file( - CONTROLS, - columns={ - "age": int, - "sex": str, - "index_date": datetime.date - } + CONTROLS, + columns={ + "age": int, + "sex": str, + "index_date": datetime.date, + }, ) dataset = create_dataset() diff --git a/docs/federation.md b/docs/federation.md index ed35d6593..3d01d513d 100644 --- a/docs/federation.md +++ b/docs/federation.md @@ -40,16 +40,17 @@ For example, this section of the study definition creates a variable that indica ```python - - sev_obesity = patients.with_these_clinical_events( - sev_obesity_codes, - returning = "date", - ignore_missing_values = True, - find_last_match_in_period = True, - on_or_after = "bmi_stage_date", - on_or_before = "index_date", - date_format = "YYYY-MM-DD", - ), +sev_obesity = ( + patients.with_these_clinical_events( + sev_obesity_codes, + returning="date", + ignore_missing_values=True, + find_last_match_in_period=True, + on_or_after="bmi_stage_date", + on_or_before="index_date", + date_format="YYYY-MM-DD", + ), +) ``` From 15c48a3abd5c6470aac9cfa171429e53aa4bceff Mon Sep 17 00:00:00 2001 From: Dave Evans Date: Tue, 22 Sep 2026 12:34:59 +0100 Subject: [PATCH 5/5] Run `just check` in CI --- .github/workflows/check.yml | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 .github/workflows/check.yml diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml new file mode 100644 index 000000000..cb1610feb --- /dev/null +++ b/.github/workflows/check.yml @@ -0,0 +1,29 @@ +name: "Check formatting and linting" + +on: + push: + pull_request: + workflow_dispatch: + +permissions: + contents: read + +jobs: + check: + name: "just check" + runs-on: ubuntu-24.04 + + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 + with: + persist-credentials: false + + - uses: opensafely-core/setup-action@d9171097dd0d37bdb7bed58f701eb03ff317ed17 # v1.7.0 + with: + python-version: "3.11" + install-just: true + install-uv: true + cache: uv + + - name: Check formatting, linting, and import sorting + run: just check