Title: Respect inserting pre-commit hooks into a config file following prek syntax · Issue #1688 · usethis-python/usethis-python · GitHub
Open Graph Title: Respect inserting pre-commit hooks into a config file following prek syntax · Issue #1688 · usethis-python/usethis-python
X Title: Respect inserting pre-commit hooks into a config file following prek syntax · Issue #1688 · usethis-python/usethis-python
Description: In #1639 I got this stack trace when trying to add a new hook: Details ╭─────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────╮ │ C:\Users\namc\AppData\Local\uv\c...
Open Graph Description: In #1639 I got this stack trace when trying to add a new hook: Details ╭─────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────...
X Description: In #1639 I got this stack trace when trying to add a new hook: Details ╭─────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────...
Opengraph URL: https://github.com/usethis-python/usethis-python/issues/1688
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Respect inserting pre-commit hooks into a config file following prek syntax","articleBody":"In #1639 I got this stack trace when trying to add a new hook:\n\n\u003cdetails\u003e\n\n```\n╭─────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────────╮\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_ui\\interface\\tool.py:219 in │\n│ pre_commit │\n│ │\n│ 216 │ │ ), │\n│ 217 │ │ files_manager(), │\n│ 218 │ ): │\n│ ❱ 219 │ │ _run_tool(use_pre_commit, remove=remove, how=how) │\n│ 220 │\n│ 221 │\n│ 222 @app.command( │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_ui\\interface\\tool.py:444 in │\n│ _run_tool │\n│ │\n│ 441 │ from usethis.errors import UsethisError │\n│ 442 │ │\n│ 443 │ try: │\n│ ❱ 444 │ │ caller(remove=remove, how=how, **kwargs) │\n│ 445 │ except UsethisError as err: │\n│ 446 │ │ err_print(err) │\n│ 447 │ │ raise typer.Exit(code=1) from None │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_core\\tool.py:191 in │\n│ use_pre_commit │\n│ │\n│ 188 │ │ ensure_dep_declaration_file() │\n│ 189 │ │ │\n│ 190 │ │ tool.add_dev_deps() │\n│ ❱ 191 │ │ _add_all_tools_pre_commit_configs() │\n│ 192 │ │ │\n│ 193 │ │ for _tool in ALL_TOOLS: │\n│ 194 │ │ │ _tool.migrate_config_to_pre_commit() │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_core\\tool.py:230 in │\n│ _add_all_tools_pre_commit_configs │\n│ │\n│ 227 │ │ if isinstance(_tool, PreCommitTool): │\n│ 228 │ │ │ continue │\n│ 229 │ │ if _tool.is_used(): │\n│ ❱ 230 │ │ │ _tool.add_pre_commit_config() │\n│ 231 │\n│ 232 │\n│ 233 def use_pyproject_fmt(*, remove: bool = False, how: bool = False) -\u003e None: │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_tool\\base.py:175 in │\n│ add_pre_commit_config │\n│ │\n│ 172 │ │ │ │ │ for hook_id in get_hook_ids() │\n│ 173 │ │ │ │ ): │\n│ 174 │ │ │ │ │ # This will remove the placeholder, if present. │\n│ ❱ 175 │ │ │ │ │ add_repo(repo_config) │\n│ 176 │ │\n│ 177 │ def remove_pre_commit_repo_configs(self) -\u003e None: │\n│ 178 │ │ \"\"\"Remove the tool's pre-commit configuration. │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pre_commit\\hooks. │\n│ py:106 in add_repo │\n│ │\n│ 103 │ │ │ predecessor=last_precedent, │\n│ 104 │ │ ) │\n│ 105 │ │ │\n│ ❱ 106 │ │ mgr.commit_model(model) │\n│ 107 │\n│ 108 │\n│ 109 def insert_repo( │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pre_commit\\yaml.p │\n│ y:59 in commit_model │\n│ │\n│ 56 │ │\n│ 57 │ def commit_model(self, model: schema.JsonSchemaForPreCommitConfigYaml) -\u003e None: │\n│ 58 │ │ doc = self.get() │\n│ ❱ 59 │ │ dump = _pre_commit_fancy_dump(model, reference=doc.content) │\n│ 60 │ │ update_ruamel_yaml_map(doc.content, dump, preserve_comments=True) │\n│ 61 │ │ self.model_validate() │\n│ 62 │ │ self.commit(doc) │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pre_commit\\yaml.p │\n│ y:68 in _pre_commit_fancy_dump │\n│ │\n│ 65 def _pre_commit_fancy_dump( │\n│ 66 │ config: schema.JsonSchemaForPreCommitConfigYaml, *, reference: ModelRepresentation │\n│ 67 ) -\u003e dict[str, ModelRepresentation]: │\n│ ❱ 68 │ dump = fancy_model_dump(config, reference=reference, order_by_cls=ORDER_BY_CLS) │\n│ 69 │ │\n│ 70 │ if not isinstance(dump, dict): │\n│ 71 │ │ msg = ( │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 56 in fancy_model_dump │\n│ │\n│ 53 │ │ │ model.root, reference=reference, order_by_cls=order_by_cls │\n│ 54 │ │ ) │\n│ 55 │ elif isinstance(model, BaseModel): │\n│ ❱ 56 │ │ return _fancy_model_dump_base_model( │\n│ 57 │ │ │ model, reference=reference, order_by_cls=order_by_cls │\n│ 58 │ │ ) │\n│ 59 │ else: │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 154 in _fancy_model_dump_base_model │\n│ │\n│ 151 │ │ if display_key is None: │\n│ 152 │ │ │ display_key = key │\n│ 153 │ │ │\n│ ❱ 154 │ │ d[display_key] = fancy_model_dump( │\n│ 155 │ │ │ value, reference=value_ref, order_by_cls=order_by_cls │\n│ 156 │ │ ) │\n│ 157 │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 42 in fancy_model_dump │\n│ │\n│ 39 │ │ │ │ │ order. RootModels are ignored. │\n│ 40 │ \"\"\" │\n│ 41 │ if isinstance(model, list): │\n│ ❱ 42 │ │ return _fancy_model_dump_list( │\n│ 43 │ │ │ model, reference=reference, order_by_cls=order_by_cls │\n│ 44 │ │ ) │\n│ 45 │ elif isinstance(model, dict): │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 88 in _fancy_model_dump_list │\n│ │\n│ 85 │ │ │\n│ 86 │ │ # We don't use None as the fillvalue because it could be confused with the │\n│ 87 │ │ # case where the content itself is None. │\n│ ❱ 88 │ │ dump = fancy_model_dump(value, reference=ref, order_by_cls=order_by_cls) │\n│ 89 │ │ x.append(dump) │\n│ 90 │ return x │\n│ 91 │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 56 in fancy_model_dump │\n│ │\n│ 53 │ │ │ model.root, reference=reference, order_by_cls=order_by_cls │\n│ 54 │ │ ) │\n│ 55 │ elif isinstance(model, BaseModel): │\n│ ❱ 56 │ │ return _fancy_model_dump_base_model( │\n│ 57 │ │ │ model, reference=reference, order_by_cls=order_by_cls │\n│ 58 │ │ ) │\n│ 59 │ else: │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 154 in _fancy_model_dump_base_model │\n│ │\n│ 151 │ │ if display_key is None: │\n│ 152 │ │ │ display_key = key │\n│ 153 │ │ │\n│ ❱ 154 │ │ d[display_key] = fancy_model_dump( │\n│ 155 │ │ │ value, reference=value_ref, order_by_cls=order_by_cls │\n│ 156 │ │ ) │\n│ 157 │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 42 in fancy_model_dump │\n│ │\n│ 39 │ │ │ │ │ order. RootModels are ignored. │\n│ 40 │ \"\"\" │\n│ 41 │ if isinstance(model, list): │\n│ ❱ 42 │ │ return _fancy_model_dump_list( │\n│ 43 │ │ │ model, reference=reference, order_by_cls=order_by_cls │\n│ 44 │ │ ) │\n│ 45 │ elif isinstance(model, dict): │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 88 in _fancy_model_dump_list │\n│ │\n│ 85 │ │ │\n│ 86 │ │ # We don't use None as the fillvalue because it could be confused with the │\n│ 87 │ │ # case where the content itself is None. │\n│ ❱ 88 │ │ dump = fancy_model_dump(value, reference=ref, order_by_cls=order_by_cls) │\n│ 89 │ │ x.append(dump) │\n│ 90 │ return x │\n│ 91 │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 56 in fancy_model_dump │\n│ │\n│ 53 │ │ │ model.root, reference=reference, order_by_cls=order_by_cls │\n│ 54 │ │ ) │\n│ 55 │ elif isinstance(model, BaseModel): │\n│ ❱ 56 │ │ return _fancy_model_dump_base_model( │\n│ 57 │ │ │ model, reference=reference, order_by_cls=order_by_cls │\n│ 58 │ │ ) │\n│ 59 │ else: │\n│ │\n│ C:\\Users\\namc\\AppData\\Local\\uv\\cache\\archive-v0\\yW5imlSdi7A20ot9JLrcF\\Lib\\site-packages\\usethis\\_integrations\\pydantic\\dump.py: │\n│ 129 in _fancy_model_dump_base_model │\n│ │\n│ 126 │ │\n│ 127 │ d: dict[str, ModelRepresentation] = {} │\n│ 128 │ for key, value in model: │\n│ ❱ 129 │ │ default_value = model.__class__.model_fields[key].default │\n│ 130 │ │ │\n│ 131 │ │ # The value for the reference (for recursion) │\n│ 132 │ │ value_ref = _get_value_ref(reference, key=key) │\n╰─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯\nKeyError: 'priority'\n```\n\u003c/details\u003e\n\nI think this is because our pre-commit file includes extra fields like `priority: 0` which are defined in the `prek` config schema but not the original pre-commit. However, we should respect them and not error out with `KeyError` in this case. Let's add a test for this kind of YAML file in our pre-commit integration tests.\n\nWe should ideally respect arbitrary keys - not only `priority`.","author":{"url":"https://github.com/nathanjmcdougall","@type":"Person","name":"nathanjmcdougall"},"datePublished":"2026-04-01T04:06:46.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/1688/usethis-python/issues/1688"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:d9cb84df-f184-d73e-7138-2f13beafcf68 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | 8E44:165D8F:172FEE9:2022CA2:6A50045B |
| html-safe-nonce | 5178b0bdbcb6010e3bd743644d6a5ebb306359948596bf33701530afc9b7d5d2 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiI4RTQ0OjE2NUQ4RjoxNzJGRUU5OjIwMjJDQTI6NkE1MDA0NUIiLCJ2aXNpdG9yX2lkIjoiNTU5MDcwNjU1ODE1NTYyMTQ2NyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 1384fc82da4f7e8efc7e6ce950712089761b0cb6f13e79b3453dda8d7293e70b |
| hovercard-subject-tag | issue:4183909602 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/usethis-python/usethis-python/1688/issue_layout |
| twitter:image | https://opengraph.githubassets.com/7d28cff0518cb0a62d1be74b530b6e508f30a007f65d14ff31362132be7186bd/usethis-python/usethis-python/issues/1688 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/7d28cff0518cb0a62d1be74b530b6e508f30a007f65d14ff31362132be7186bd/usethis-python/usethis-python/issues/1688 |
| og:image:alt | In #1639 I got this stack trace when trying to add a new hook: Details ╭─────────────────────────────────────────────── Traceback (most recent call last) ───────────────────────────────────────────... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | nathanjmcdougall |
| hostname | github.com |
| expected-hostname | github.com |
| None | 56eec25a3430492dd6ec2a480eb33256a0da5192d5714b0db4f5ab5f33203d94 |
| turbo-cache-control | no-preview |
| go-import | github.com/usethis-python/usethis-python git https://github.com/usethis-python/usethis-python.git |
| octolytics-dimension-user_id | 216362695 |
| octolytics-dimension-user_login | usethis-python |
| octolytics-dimension-repository_id | 842189705 |
| octolytics-dimension-repository_nwo | usethis-python/usethis-python |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 842189705 |
| octolytics-dimension-repository_network_root_nwo | usethis-python/usethis-python |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | e155b8a71f9284454f73118dfe5e634e74f7afb3 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width