Title: Drop bytes input in 2.0; require str · Issue #245 · derek73/python-nameparser · GitHub
Open Graph Title: Drop bytes input in 2.0; require str · Issue #245 · derek73/python-nameparser
X Title: Drop bytes input in 2.0; require str · Issue #245 · derek73/python-nameparser
Description: Summary 2.0 should stop accepting bytes anywhere and require str, making decoding the caller's job. The bytes tolerance is a Python 2 legacy, and — verified below — it is already inconsistent to the point of being half-broken: bytes inpu...
Open Graph Description: Summary 2.0 should stop accepting bytes anywhere and require str, making decoding the caller's job. The bytes tolerance is a Python 2 legacy, and — verified below — it is already inconsistent to th...
X Description: Summary 2.0 should stop accepting bytes anywhere and require str, making decoding the caller's job. The bytes tolerance is a Python 2 legacy, and — verified below — it is already inconsistent t...
Opengraph URL: https://github.com/derek73/python-nameparser/issues/245
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"Drop bytes input in 2.0; require str","articleBody":"## Summary\n\n2.0 should stop accepting `bytes` anywhere and require `str`, making decoding the caller's job. The bytes tolerance is a Python 2 legacy, and — verified below — it is already inconsistent to the point of being half-broken: bytes input currently gets a different behavior depending on which door it walks through.\n\n## Current state (verified)\n\n| Entry point | Behavior with bytes |\n|---|---|\n| `HumanName(b'John Smith')` | works — decoded with the `encoding` kwarg; emits `DeprecationWarning` since 1.3.0 |\n| `hn.first = b'Jane'` / `HumanName(first=b'Jane')` | **crashes** — `_set_list` explicitly accepts bytes, then `parse_pieces` fails deep inside with the confusing inverse error `TypeError: a bytes-like object is required, not 'str'` (`bytes.split(' ')`) |\n| `SetManager.add(b'esq')` | works — decoded, but see the stdin sniffing below; emits `DeprecationWarning` since 1.3.0 |\n| `SetManager(b'esq')` / `SetManager([b'esq'])` | already rejected loudly with a decode hint (1.3.0: #238, PR #240) |\n\nSo the \"feature\" is: two paths that decode, one that crashes confusingly despite an isinstance check that promises support, and one that's already banned. Nobody can be relying on the full surface, because part of it doesn't function.\n\n## Additional defect: environment-dependent decoding\n\n`SetManager.add_with_encoding` resolves the encoding as `encoding or sys.stdin.encoding or DEFAULT_ENCODING`. The encoding of the process's stdin has no relationship to an arbitrary `bytes` argument, so the same call can decode differently depending on how the process was launched (terminal vs. pipe vs. embedded with `sys.stdin = None`). Library behavior should not vary with the runtime environment.\n\n## What's removed in 2.0\n\n- `full_name: str | bytes` and `original: str | bytes` become `str`\n- The `encoding` constructor kwarg and `self.encoding` attribute\n- The bytes branch in `_set_list` and the bytes tolerance in `parse_pieces` (accepting what later crashes)\n- `add_with_encoding()` — `add()` becomes str-only, raising the same decode-hint `TypeError` the constructor already raises; the stdin sniffing goes with it\n\n## Migration\n\nOne line at the boundary: `HumanName(raw.decode('utf-8'))` — the caller knows the real encoding; the library never did. Everything else is the same call with `str`.\n\n## Bridge\n\n- [x] `DeprecationWarning` when bytes reaches `full_name` or `SetManager.add()`, naming the decode-first replacement — shipped in 1.3.0 (#253)\n\n\n- [ ] 1.4: `DeprecationWarning` on every `add_with_encoding()` call regardless of argument type, naming `add()` as the replacement — the str path is silent today, so the method's removal is otherwise unwarned (bytes callers additionally get the existing decode-first warning; two distinct migrations). Tracked in #263.\n","author":{"url":"https://github.com/derek73","@type":"Person","name":"derek73"},"datePublished":"2026-07-06T01:56:33.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":0},"url":"https://github.com/245/python-nameparser/issues/245"}
| 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:fb50c1d9-9b3c-674a-beeb-6f539a48798d |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | D9CC:383791:6148F:81859:6A5584F2 |
| html-safe-nonce | 46e9928378c77e2d8593d7ee8ec92ad5e4d91e43c6add558ef7a09c188e61184 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJEOUNDOjM4Mzc5MTo2MTQ4Rjo4MTg1OTo2QTU1ODRGMiIsInZpc2l0b3JfaWQiOiI5MTg4ODMyNzg3ODE3NjYxNjgyIiwicmVnaW9uX2VkZ2UiOiJpYWQiLCJyZWdpb25fcmVuZGVyIjoiaWFkIn0= |
| visitor-hmac | 1b78d0169ced57b90f81c22a6e516bdb6f1e32358add99a3f1b661ef2632751d |
| hovercard-subject-tag | issue:4815348393 |
| 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/derek73/python-nameparser/245/issue_layout |
| twitter:image | https://opengraph.githubassets.com/81aa4c17ca8ef73756eca3849e89f6f4849cafd76f9767a40a80ee87cbce863a/derek73/python-nameparser/issues/245 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/81aa4c17ca8ef73756eca3849e89f6f4849cafd76f9767a40a80ee87cbce863a/derek73/python-nameparser/issues/245 |
| og:image:alt | Summary 2.0 should stop accepting bytes anywhere and require str, making decoding the caller's job. The bytes tolerance is a Python 2 legacy, and — verified below — it is already inconsistent to th... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | derek73 |
| hostname | github.com |
| expected-hostname | github.com |
| None | b5665c84831ed9ac4fb79519c16c9c5580ba8092fb8bb6e3e72972ec7197348e |
| turbo-cache-control | no-preview |
| go-import | github.com/derek73/python-nameparser git https://github.com/derek73/python-nameparser.git |
| octolytics-dimension-user_id | 18306 |
| octolytics-dimension-user_login | derek73 |
| octolytics-dimension-repository_id | 18353524 |
| octolytics-dimension-repository_nwo | derek73/python-nameparser |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 18353524 |
| octolytics-dimension-repository_network_root_nwo | derek73/python-nameparser |
| 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 | 3215163789b3dc58dba97bd78a30c20c949f477f |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width