From c0baf62f713a5d1781862626bc0058bdef6765f6 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Fri, 16 Jan 2026 22:12:39 -0400 Subject: [PATCH 01/14] Ignore .worktrees directory (#6) --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 9c325f3e29f8..880418969bd2 100644 --- a/.gitignore +++ b/.gitignore @@ -51,6 +51,7 @@ include/ pyvenv.cfg .tox +.worktrees pip-wheel-metadata From b5dfda62f4e05eea475fe6b1a40b7da76ca9b96d Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sat, 17 Jan 2026 00:28:47 -0400 Subject: [PATCH 02/14] chore: sync AGENTS rules to keep contributor guidance consistent (#8) --- .gitignore | 2 +- AGENTS.md | 17 +++++++++++++++++ 2 files changed, 18 insertions(+), 1 deletion(-) create mode 100644 AGENTS.md diff --git a/.gitignore b/.gitignore index 880418969bd2..ed1e1ff7d572 100644 --- a/.gitignore +++ b/.gitignore @@ -51,7 +51,6 @@ include/ pyvenv.cfg .tox -.worktrees pip-wheel-metadata @@ -61,3 +60,4 @@ test_capi test_capi /mypyc/lib-rt/build/ /mypyc/lib-rt/*.so +.worktrees/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000000..2855e173a207 --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,17 @@ +# Agent Requirements + +All agents must follow these rules: + +1) Fully test your changes before submitting a PR (run the full suite or all relevant tests). +2) PR titles must be descriptive and follow Conventional Commits-style prefixes: + - Common: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `test:`, `perf:` + - Support titles: `fix(docs):`, `fix(benchmarks):`, `fix(cicd):` +3) Commit messages must follow the same Conventional Commits-style prefixes and include a short functional description plus a user-facing value proposition. +4) PR descriptions must include Summary, Rationale, and Details sections. +5) Run relevant Python tests for changes (pytest/unittest or the repo's configured runner). +6) Follow formatting/linting configured in pyproject.toml, setup.cfg, tox.ini, or ruff.toml. +7) Update dependency lockfiles when adding or removing Python dependencies. +8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. +9) Keep base image tags pinned. + +Reference: https://www.conventionalcommits.org/en/v1.0.0/ From f910a54fd5ee55e2876dd38258f0202c61f7d9a8 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:19:01 -0400 Subject: [PATCH 03/14] mypyc: add ascii format fast path (#17) * mypyc: add ascii format fast path * mypyc: extend ascii constant-fold tests --- mypyc/irbuild/format_str_tokenizer.py | 34 +++++++++++++++----- mypyc/primitives/str_ops.py | 11 ++++++- mypyc/test-data/irbuild-constant-fold.test | 36 ++++++++++++++++++++++ mypyc/test-data/irbuild-str.test | 7 ++++- 4 files changed, 79 insertions(+), 9 deletions(-) diff --git a/mypyc/irbuild/format_str_tokenizer.py b/mypyc/irbuild/format_str_tokenizer.py index 5a35900006d2..d34ecfe00801 100644 --- a/mypyc/irbuild/format_str_tokenizer.py +++ b/mypyc/irbuild/format_str_tokenizer.py @@ -12,7 +12,7 @@ ) from mypy.errors import Errors from mypy.messages import MessageBuilder -from mypy.nodes import Context, Expression, StrExpr +from mypy.nodes import Context, Expression from mypy.options import Options from mypyc.ir.ops import Integer, Value from mypyc.ir.rtypes import ( @@ -23,9 +23,10 @@ is_str_rprimitive, ) from mypyc.irbuild.builder import IRBuilder +from mypyc.irbuild.constant_fold import constant_fold_expr from mypyc.primitives.bytes_ops import bytes_build_op from mypyc.primitives.int_ops import int_to_str_op -from mypyc.primitives.str_ops import str_build_op, str_op +from mypyc.primitives.str_ops import ascii_op, str_build_op, str_op @unique @@ -41,6 +42,7 @@ class FormatOp(Enum): STR = "s" INT = "d" + ASCII = "a" BYTES = "b" @@ -52,14 +54,25 @@ def generate_format_ops(specifiers: list[ConversionSpecifier]) -> list[FormatOp] format_ops = [] for spec in specifiers: # TODO: Match specifiers instead of using whole_seq - if spec.whole_seq == "%s" or spec.whole_seq == "{:{}}": + # Conversion flags for str.format/f-strings (e.g. {!a}); only if no format spec. + if spec.conversion and not spec.format_spec: + if spec.conversion == "!a": + format_op = FormatOp.ASCII + else: + return None + # printf-style tokens and special f-string lowering patterns. + elif spec.whole_seq == "%s" or spec.whole_seq == "{:{}}": format_op = FormatOp.STR elif spec.whole_seq == "%d": format_op = FormatOp.INT + elif spec.whole_seq == "%a": + format_op = FormatOp.ASCII elif spec.whole_seq == "%b": format_op = FormatOp.BYTES + # Any other non-empty spec means we can't optimize; fall back to runtime formatting. elif spec.whole_seq: return None + # Empty spec ("{}") defaults to str(). else: format_op = FormatOp.STR format_ops.append(format_op) @@ -143,16 +156,23 @@ def convert_format_expr_to_str( for x, format_op in zip(exprs, format_ops): node_type = builder.node_type(x) if format_op == FormatOp.STR: - if is_str_rprimitive(node_type) or isinstance( - x, StrExpr - ): # NOTE: why does mypyc think our fake StrExprs are not str rprimitives? + if isinstance(folded := constant_fold_expr(builder, x), str): + var_str = builder.load_literal_value(folded) + elif is_str_rprimitive(node_type): var_str = builder.accept(x) elif is_int_rprimitive(node_type) or is_short_int_rprimitive(node_type): var_str = builder.primitive_op(int_to_str_op, [builder.accept(x)], line) else: var_str = builder.primitive_op(str_op, [builder.accept(x)], line) + elif format_op == FormatOp.ASCII: + if (folded := constant_fold_expr(builder, x)) is not None: + var_str = builder.load_literal_value(ascii(folded)) + else: + var_str = builder.primitive_op(ascii_op, [builder.accept(x)], line) elif format_op == FormatOp.INT: - if is_int_rprimitive(node_type) or is_short_int_rprimitive(node_type): + if isinstance(folded := constant_fold_expr(builder, x), int): + var_str = builder.load_literal_value(str(folded)) + elif is_int_rprimitive(node_type) or is_short_int_rprimitive(node_type): var_str = builder.primitive_op(int_to_str_op, [builder.accept(x)], line) else: return None diff --git a/mypyc/primitives/str_ops.py b/mypyc/primitives/str_ops.py index f6d3f722dd7b..2f217b77ad67 100644 --- a/mypyc/primitives/str_ops.py +++ b/mypyc/primitives/str_ops.py @@ -51,6 +51,15 @@ error_kind=ERR_MAGIC, ) +# ascii(obj) +ascii_op = function_op( + name="builtins.ascii", + arg_types=[object_rprimitive], + return_type=str_rprimitive, + c_function_name="PyObject_ASCII", + error_kind=ERR_MAGIC, +) + # translate isinstance(obj, str) isinstance_str = function_op( name="builtins.isinstance", @@ -180,7 +189,7 @@ name="rfind", arg_types=str_find_types[0 : i + 2], return_type=int_rprimitive, - c_function_name=str_find_functions[i], + c_function_name=str_rfind_functions[i], extra_int_constants=str_rfind_constants[i] + [(-1, c_int_rprimitive)], error_kind=ERR_MAGIC, ) diff --git a/mypyc/test-data/irbuild-constant-fold.test b/mypyc/test-data/irbuild-constant-fold.test index cd953c84c541..ba6cc3b73ae1 100644 --- a/mypyc/test-data/irbuild-constant-fold.test +++ b/mypyc/test-data/irbuild-constant-fold.test @@ -186,6 +186,42 @@ L0: big5 = r4 return 1 +[case testConstantFoldFormatArgs] +# This only tests that the callee and args are constant folded, +# it is not intended to test the result. +from typing import Any, Final + +FMT: Final = "{} {}" +FMT_A: Final = "{!a}" + +def f() -> str: + return FMT.format(400 + 20, "roll" + "up") +def g() -> str: + return FMT_A.format("\u00e9") +def g2() -> str: + return FMT_A.format("\u2603") +[out] +def f(): + r0, r1, r2, r3 :: str +L0: + r0 = CPyTagged_Str(840) + r1 = 'rollup' + r2 = ' ' + r3 = CPyStr_Build(3, r0, r2, r1) + return r3 +def g(): + r0, r1 :: str +L0: + r0 = "'\\xe9'" + r1 = CPyStr_Build(1, r0) + return r1 +def g2(): + r0, r1 :: str +L0: + r0 = "'\\u2603'" + r1 = CPyStr_Build(1, r0) + return r1 + [case testIntConstantFoldingFinal] from typing import Final X: Final = 5 diff --git a/mypyc/test-data/irbuild-str.test b/mypyc/test-data/irbuild-str.test index ee618bb34f65..16aed004e02f 100644 --- a/mypyc/test-data/irbuild-str.test +++ b/mypyc/test-data/irbuild-str.test @@ -291,6 +291,7 @@ def f(var: Union[str, NewStr], num: int) -> None: s2 = "I am %d years old." % num s3 = "Hi! I'm %s. I am %d years old." % (var, num) s4 = "Float: %f" % num + s5 = "Ascii: %a" % var [typing fixtures/typing-full.pyi] [out] def f(var, num): @@ -298,7 +299,7 @@ def f(var, num): num :: int r0, r1, r2, s1, r3, r4, r5, r6, s2, r7, r8, r9, r10, r11, s3, r12 :: str r13, r14 :: object - r15, s4 :: str + r15, s4, r16, r17, r18, s5 :: str L0: r0 = "Hi! I'm " r1 = '.' @@ -320,6 +321,10 @@ L0: r14 = PyNumber_Remainder(r12, r13) r15 = cast(str, r14) s4 = r15 + r16 = PyObject_ASCII(var) + r17 = 'Ascii: ' + r18 = CPyStr_Build(2, r17, r16) + s5 = r18 return 1 [case testDecode] From 8c9cd5bb29d2a1507738f7b00af01794e35696ac Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:41:07 -0400 Subject: [PATCH 04/14] Delete AGENTS.md --- AGENTS.md | 17 ----------------- 1 file changed, 17 deletions(-) delete mode 100644 AGENTS.md diff --git a/AGENTS.md b/AGENTS.md deleted file mode 100644 index 2855e173a207..000000000000 --- a/AGENTS.md +++ /dev/null @@ -1,17 +0,0 @@ -# Agent Requirements - -All agents must follow these rules: - -1) Fully test your changes before submitting a PR (run the full suite or all relevant tests). -2) PR titles must be descriptive and follow Conventional Commits-style prefixes: - - Common: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `test:`, `perf:` - - Support titles: `fix(docs):`, `fix(benchmarks):`, `fix(cicd):` -3) Commit messages must follow the same Conventional Commits-style prefixes and include a short functional description plus a user-facing value proposition. -4) PR descriptions must include Summary, Rationale, and Details sections. -5) Run relevant Python tests for changes (pytest/unittest or the repo's configured runner). -6) Follow formatting/linting configured in pyproject.toml, setup.cfg, tox.ini, or ruff.toml. -7) Update dependency lockfiles when adding or removing Python dependencies. -8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. -9) Keep base image tags pinned. - -Reference: https://www.conventionalcommits.org/en/v1.0.0/ From 14c890d5509ace66ed6e870aa9b8ae7d87a59db3 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:41:34 -0400 Subject: [PATCH 05/14] Update .gitignore --- .gitignore | 1 - 1 file changed, 1 deletion(-) diff --git a/.gitignore b/.gitignore index ed1e1ff7d572..9c325f3e29f8 100644 --- a/.gitignore +++ b/.gitignore @@ -60,4 +60,3 @@ test_capi test_capi /mypyc/lib-rt/build/ /mypyc/lib-rt/*.so -.worktrees/ From 36e29deb45db7c51d3344d37b238e0446048be0e Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Sun, 18 Jan 2026 10:44:40 -0400 Subject: [PATCH 06/14] Update str_ops.py --- mypyc/primitives/str_ops.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/mypyc/primitives/str_ops.py b/mypyc/primitives/str_ops.py index 2f217b77ad67..6a178accca8a 100644 --- a/mypyc/primitives/str_ops.py +++ b/mypyc/primitives/str_ops.py @@ -189,7 +189,7 @@ name="rfind", arg_types=str_find_types[0 : i + 2], return_type=int_rprimitive, - c_function_name=str_rfind_functions[i], + c_function_name=str_find_functions[i], extra_int_constants=str_rfind_constants[i] + [(-1, c_int_rprimitive)], error_kind=ERR_MAGIC, ) From b7792b286d3f96c29a5a7e31b0a2641a8430c9ae Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Mon, 19 Jan 2026 19:48:29 -0400 Subject: [PATCH 07/14] chore: update agent requirements to keep contributor workflow consistent --- .gitignore | 1 + AGENTS.md | 20 ++++++++++++++++++++ 2 files changed, 21 insertions(+) create mode 100644 AGENTS.md diff --git a/.gitignore b/.gitignore index 9c325f3e29f8..ed1e1ff7d572 100644 --- a/.gitignore +++ b/.gitignore @@ -60,3 +60,4 @@ test_capi test_capi /mypyc/lib-rt/build/ /mypyc/lib-rt/*.so +.worktrees/ diff --git a/AGENTS.md b/AGENTS.md new file mode 100644 index 000000000000..cfe9f6a1195d --- /dev/null +++ b/AGENTS.md @@ -0,0 +1,20 @@ +# Agent Requirements + +All agents must follow these rules: + +1) Fully test your changes before submitting a PR (run the full suite or all relevant tests). +2) PR titles must be descriptive and follow Conventional Commits-style prefixes: + - Common: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `test:`, `perf:` + - Support titles: `fix(docs):`, `fix(benchmarks):`, `fix(cicd):` +3) Commit messages must follow the same Conventional Commits-style prefixes and include a short functional description plus a user-facing value proposition. +4) PR descriptions must include `Summary`, `Rationale`, and `Details` sections. +5) Run relevant Python tests for changes (pytest/unittest or the repo's configured runner). +6) Follow formatting/linting configured in pyproject.toml, setup.cfg, tox.ini, or ruff.toml. +7) Update dependency lockfiles when adding or removing Python dependencies. +8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. +9) All mypy configuration (flags, overrides, per-module ignores, and file targets) should go in pyproject.toml. Do not split config across CLI args, mypy.ini, setup.cfg, or workflow steps. +10) Centralize pytest settings (flags, markers, ignore patterns, and targets) in pyproject.toml, pytest.ini, setup.cfg, or tox.ini; workflows/hooks should call pytest without inline args. +11) For unittest workflows, prefer python -m unittest without inline args; if discovery arguments are required, centralize them in a single script and call that from CI. +12) Keep base image tags pinned. + +Reference: https://www.conventionalcommits.org/en/v1.0.0/ From 4976c1cbaf73ace63ecb14ca0e1852206fe944ee Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 20 Jan 2026 02:25:00 -0400 Subject: [PATCH 08/14] chore: update agent requirements and .gitignore to keep contributor guidance current --- AGENTS.md | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index cfe9f6a1195d..9f07e9a7b267 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -7,14 +7,15 @@ All agents must follow these rules: - Common: `feat:`, `fix:`, `chore:`, `refactor:`, `docs:`, `test:`, `perf:` - Support titles: `fix(docs):`, `fix(benchmarks):`, `fix(cicd):` 3) Commit messages must follow the same Conventional Commits-style prefixes and include a short functional description plus a user-facing value proposition. -4) PR descriptions must include `Summary`, `Rationale`, and `Details` sections. +4) PR descriptions must include Summary, Rationale, and Details sections. 5) Run relevant Python tests for changes (pytest/unittest or the repo's configured runner). 6) Follow formatting/linting configured in pyproject.toml, setup.cfg, tox.ini, or ruff.toml. 7) Update dependency lockfiles when adding or removing Python dependencies. 8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. -9) All mypy configuration (flags, overrides, per-module ignores, and file targets) should go in pyproject.toml. Do not split config across CLI args, mypy.ini, setup.cfg, or workflow steps. -10) Centralize pytest settings (flags, markers, ignore patterns, and targets) in pyproject.toml, pytest.ini, setup.cfg, or tox.ini; workflows/hooks should call pytest without inline args. -11) For unittest workflows, prefer python -m unittest without inline args; if discovery arguments are required, centralize them in a single script and call that from CI. -12) Keep base image tags pinned. +9) Maximize the use of caching in GitHub workflow files to minimize run duration. +10) Use one of `paths` or `paths-ignore` in every workflow file to make sure workflows only run when required. +11) All mypy configuration (flags, overrides, per-module ignores, and file targets) should go in pyproject.toml. Do not split config across CLI args, mypy.ini, setup.cfg, or workflow steps. +12) Centralize pytest settings (flags, markers, ignore patterns, and targets) in pyproject.toml, pytest.ini, setup.cfg, or tox.ini; workflows/hooks should call pytest without inline args. +13) Keep base image tags pinned. Reference: https://www.conventionalcommits.org/en/v1.0.0/ From d60a83340068010a75e60ed6cbdda7b8009d7b24 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 20 Jan 2026 04:56:45 -0400 Subject: [PATCH 09/14] docs: add agent requirements for consistent automation --- AGENTS.md | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 9f07e9a7b267..2855e173a207 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,10 +12,6 @@ All agents must follow these rules: 6) Follow formatting/linting configured in pyproject.toml, setup.cfg, tox.ini, or ruff.toml. 7) Update dependency lockfiles when adding or removing Python dependencies. 8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. -9) Maximize the use of caching in GitHub workflow files to minimize run duration. -10) Use one of `paths` or `paths-ignore` in every workflow file to make sure workflows only run when required. -11) All mypy configuration (flags, overrides, per-module ignores, and file targets) should go in pyproject.toml. Do not split config across CLI args, mypy.ini, setup.cfg, or workflow steps. -12) Centralize pytest settings (flags, markers, ignore patterns, and targets) in pyproject.toml, pytest.ini, setup.cfg, or tox.ini; workflows/hooks should call pytest without inline args. -13) Keep base image tags pinned. +9) Keep base image tags pinned. Reference: https://www.conventionalcommits.org/en/v1.0.0/ From 2b0381cbed83d5cf5f296b37b272f7570551875a Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 20 Jan 2026 06:48:07 -0400 Subject: [PATCH 10/14] chore: scope mypy/pytest workflow paths to reduce CI noise --- .github/workflows/build_wheels.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index dae4937d5081..f2e78109bfba 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -2,6 +2,18 @@ name: Trigger wheel build on: push: + paths: + - '**/*.py' + - '**/*.pyi' + - 'pyproject.toml' + - 'mypy.ini' + - 'setup.cfg' + - 'setup.py' + - 'requirements*.txt' + - 'tox.ini' + - 'poetry.lock' + - '.pre-commit-config.yaml' + - '.github/workflows/build_wheels.yml' branches: [main, master, 'release*'] tags: ['*'] From 6d892a2c3d03a7adb1174955a706f4bc9024ebbc Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:05:41 -0400 Subject: [PATCH 11/14] chore: trim workflow paths to existing files --- .github/workflows/build_wheels.yml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/.github/workflows/build_wheels.yml b/.github/workflows/build_wheels.yml index f2e78109bfba..e6a951f3c6cb 100644 --- a/.github/workflows/build_wheels.yml +++ b/.github/workflows/build_wheels.yml @@ -6,12 +6,8 @@ on: - '**/*.py' - '**/*.pyi' - 'pyproject.toml' - - 'mypy.ini' - - 'setup.cfg' - 'setup.py' - - 'requirements*.txt' - 'tox.ini' - - 'poetry.lock' - '.pre-commit-config.yaml' - '.github/workflows/build_wheels.yml' branches: [main, master, 'release*'] From c91d9a79087df08c91c50ce810e5b0d65328cf0c Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 20 Jan 2026 17:17:00 -0400 Subject: [PATCH 12/14] chore(cicd): refine workflow paths From 4cf94b8a80e61ded366b8ba473373185b4f863d2 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Tue, 20 Jan 2026 22:34:59 -0400 Subject: [PATCH 13/14] chore: clarify AGENTS remote-branch guidance for up-to-date work --- AGENTS.md | 1 + 1 file changed, 1 insertion(+) diff --git a/AGENTS.md b/AGENTS.md index 2855e173a207..fab5f0c9a2e3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -13,5 +13,6 @@ All agents must follow these rules: 7) Update dependency lockfiles when adding or removing Python dependencies. 8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. 9) Keep base image tags pinned. +10) If the branch you're assigned to work on is from a remote (ie origin/master or upstream/awesome-feature) you must ensure you fetch and pull from the remote before you begin your work. Reference: https://www.conventionalcommits.org/en/v1.0.0/ From be4e5f83b510a964f9df78b89f0d6f5e1f67b498 Mon Sep 17 00:00:00 2001 From: BobTheBuidler <70677534+BobTheBuidler@users.noreply.github.com> Date: Wed, 21 Jan 2026 10:12:55 -0400 Subject: [PATCH 14/14] docs: update AGENTS requirements to clarify contributor expectations --- AGENTS.md | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index fab5f0c9a2e3..9f07e9a7b267 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -12,7 +12,10 @@ All agents must follow these rules: 6) Follow formatting/linting configured in pyproject.toml, setup.cfg, tox.ini, or ruff.toml. 7) Update dependency lockfiles when adding or removing Python dependencies. 8) If the repo uses mypyc, verify tests run against compiled extensions (not interpreted Python) and note how you confirmed. -9) Keep base image tags pinned. -10) If the branch you're assigned to work on is from a remote (ie origin/master or upstream/awesome-feature) you must ensure you fetch and pull from the remote before you begin your work. +9) Maximize the use of caching in GitHub workflow files to minimize run duration. +10) Use one of `paths` or `paths-ignore` in every workflow file to make sure workflows only run when required. +11) All mypy configuration (flags, overrides, per-module ignores, and file targets) should go in pyproject.toml. Do not split config across CLI args, mypy.ini, setup.cfg, or workflow steps. +12) Centralize pytest settings (flags, markers, ignore patterns, and targets) in pyproject.toml, pytest.ini, setup.cfg, or tox.ini; workflows/hooks should call pytest without inline args. +13) Keep base image tags pinned. Reference: https://www.conventionalcommits.org/en/v1.0.0/