Title: agent: prefer dataclasses over named tuples for structured return types · Issue #1873 · usethis-python/usethis-python · GitHub
Open Graph Title: agent: prefer dataclasses over named tuples for structured return types · Issue #1873 · usethis-python/usethis-python
X Title: agent: prefer dataclasses over named tuples for structured return types · Issue #1873 · usethis-python/usethis-python
Description: What happened A NamedTuple was used for SubprocessResult — a structured return type holding stdout and stderr from a subprocess invocation. During review, this was flagged as the wrong choice: a dataclass should have been used instead. R...
Open Graph Description: What happened A NamedTuple was used for SubprocessResult — a structured return type holding stdout and stderr from a subprocess invocation. During review, this was flagged as the wrong choice: a da...
X Description: What happened A NamedTuple was used for SubprocessResult — a structured return type holding stdout and stderr from a subprocess invocation. During review, this was flagged as the wrong choice: a da...
Opengraph URL: https://github.com/usethis-python/usethis-python/issues/1873
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"agent: prefer dataclasses over named tuples for structured return types","articleBody":"## What happened\n\nA `NamedTuple` was used for `SubprocessResult` — a structured return type holding `stdout` and `stderr` from a subprocess invocation. During review, this was flagged as the wrong choice: a dataclass should have been used instead.\n\n## Root cause\n\nThe agent defaulted to `NamedTuple` when creating a simple two-field container type, likely because named tuples are concise and feel lightweight. However, named tuples inherit tuple semantics (indexing, unpacking, iteration, comparison by position) that are inappropriate for a structured record. These extra behaviours leak implementation details and invite fragile code that depends on field ordering rather than field names.\n\n## Generalised principle\n\nAlways prefer `dataclasses.dataclass` over `typing.NamedTuple` for structured return types and value objects. Named tuples should only be used when tuple semantics (positional access, iteration, structural comparison) are genuinely needed. When the goal is simply to group named fields together, a dataclass is the correct choice — it provides attribute access without the unintended tuple behaviours.\n\n## Resolution\n\nChanged `SubprocessResult` from `NamedTuple` to `@dataclass` in `_subprocess.py`. All existing code accessed fields via `.stdout` and `.stderr` attributes, so no call sites needed updating.\n\n## Follow-up\n\nNone.","author":{"url":"https://github.com/nathanjmcdougall","@type":"Person","name":"nathanjmcdougall"},"datePublished":"2026-04-07T21:24:53.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/1873/usethis-python/issues/1873"}
| 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:7919b7ce-df30-6f0f-5038-5bbe1536b24f |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | AAA4:9E28B:1022E79:15A0324:6A4D899C |
| html-safe-nonce | 3220769ee50592a462f84bd1475c859af32cbcff4667282654b32acd38fbd481 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJBQUE0OjlFMjhCOjEwMjJFNzk6MTVBMDMyNDo2QTREODk5QyIsInZpc2l0b3JfaWQiOiIzMjk3Nzk1NTgzODAwODcxMzI0IiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 9b0d617bff58437db67b80e97061d0d72d682a8b665c5baffd8c751987b08256 |
| hovercard-subject-tag | issue:4220672376 |
| 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/1873/issue_layout |
| twitter:image | https://opengraph.githubassets.com/1eaa17351b5237dab0f70ae3bc6308549957e2a47b8bbc83fa1a1062268ad78a/usethis-python/usethis-python/issues/1873 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/1eaa17351b5237dab0f70ae3bc6308549957e2a47b8bbc83fa1a1062268ad78a/usethis-python/usethis-python/issues/1873 |
| og:image:alt | What happened A NamedTuple was used for SubprocessResult — a structured return type holding stdout and stderr from a subprocess invocation. During review, this was flagged as the wrong choice: a da... |
| 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 | 9f8758a3953dfe943439713a6fa4f90d542a3431f10e861ca03dd7f39009f320 |
| 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 | bffd5484f01713a661b03469b77678f72b6574ed |
| ui-target | canary-2 |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width