GV

GeezerVison

The World Wide Web, restored to 800 pixels of glory.

Home|About|Gaming cabinet|Archives|How it works|Starter sites

On this site

  • Sign in
  • ActionsCI/CD and automation
  • CodespacesCloud development environments
  • All Features
  • Documentation
  • Training
  • Certifications
  • Build with Copilot
  • Customize Copilot
  • Integrations
  • Trending repos
  • GitHub Sponsors
  • Developer articles
  • Enterprises

This view

  • Original page
  • New address

GeezerVison is showing github.com — gh-157407: Argument Clinic: parse positional-only `defining_class` methods without `_PyArg_Parser` by eendebakpt · Pull Request #157483 · python/cpython

Conversation

@eendebakpt

@eendebakpt eendebakpt commented Sep 14, 2026 •
edited by bedevere-app Bot
Loading

Uh oh!

There was an error while loading. Please reload this page.

Copy link
Copy Markdown
Contributor

Methods taking a defining_class whose other parameters are all positional-only (e.g. Decimal.from_float) used the keyword path: a static _PyArg_Parser and a _PyArg_UnpackKeywords() call. They now use _PyArg_NoKwnames().

Typical code change:

-    static const char * const _keywords[] = {"", NULL};
-    static _PyArg_Parser _parser = {
-        .keywords = _keywords,
-        .fname = "from_float",
-        .kwtuple = KWTUPLE,
-    };
-    PyObject *argsbuf[1];
     PyObject *pyfloat;
 
-    args = _PyArg_UnpackKeywords(args, nargs, NULL, kwnames, &_parser,
-            /*minpos*/ 1, /*maxpos*/ 1, /*minkw*/ 0, /*varpos*/ 0, argsbuf);
-    if (!args) {
+    if (!_PyArg_NoKwnames("from_float", kwnames)) {
+        goto exit;
+    }
+    if (!_PyArg_CheckPositional("from_float", nargs, 1, 1)) {

This converts 135 methods in 19 clinic headers. _PyArg_NoKwnames() is now exported for shared extension modules.

Size change in bytes:

.text read-only data .data
Windows x64 (MSVC, LTCG) −6352 −4708 −10512
Linux x86-64 (gcc -O3)* −2592 −1144 −5664

* excluding _decimal, _sqlite3, _dbm and _gdbm, which were not built. Linux also drops 4872 bytes of .rela.dyn.

Changed error messages: these methods now raise the same TypeError messages as other positional-only methods,:

call before after
compressobj().compress() compress() takes exactly 1 positional argument (0 given) compress expected 1 argument, got 0
compressobj().compress(b'', b'') compress() takes at most 1 argument (2 given) compress expected 1 argument, got 2
Pickler(f).dump(obj=1) dump() takes exactly 1 positional argument (0 given) dump() takes no keyword arguments

This is arguably more consistent, but a small change in error messages.

Performance seems slightly improved (but within noise, no not quoting any numbers).

Generated with Claude Code

  • Issue: Reduce some code sizes #157407

Sorry, something went wrong.

Uh oh!

There was an error while loading. Please reload this page.

All reactions
@eendebakpt @claude
pythongh-136681: Drop _PyArg_Parser for positional-only defining-clas…
f72d032
…s methods

A method that takes a defining class and whose other parameters are all
positional-only (e.g. decimal.Decimal.from_float) was routed through
Argument Clinic's generic keyword path: it emitted a static _PyArg_Parser,
an (empty) keyword tuple and an _PyArg_UnpackKeywords() call, even though
it accepts no keyword arguments.

Such methods now go through parse_pos_only(): the wrapper still uses the
mandatory METH_METHOD|METH_FASTCALL|METH_KEYWORDS convention (the only one
that delivers the defining class), but it rejects keywords with
_PyArg_NoKwnames() and reads positional arguments directly, with no
parser, keyword tuple or argsbuf.

This converts 135 methods across 19 clinic headers, removing the static
_PyArg_Parser, the keyword arrays/tuples and the per-call
_PyArg_UnpackKeywords() + parser_init() overhead for each.

_PyArg_NoKwnames() is now exported (PyAPI_FUNC) so generated code in
shared extension modules can use it, like _PyArg_NoKeywords().

Error messages for these methods now match ordinary positional-only
functions ("expected ... arguments" / "takes no keyword arguments"
instead of the _PyArg_UnpackKeywords phrasing); affected stdlib tests
are updated accordingly.

Co-Authored-By: Claude Opus 5 (1M context) <[email protected]>
@eendebakpt
eendebakpt requested review from AA-Turner, ericsnowcurrently and erlend-aasland as code owners September 14, 2026 11:02
@bedevere-app bedevere-app Bot mentioned this pull request Sep 14, 2026
Reduce some code sizes #157407
Open
@bedevere-app bedevere-app Bot added the awaiting core review label Sep 14, 2026
methane
methane approved these changes Sep 14, 2026
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting core review labels Sep 14, 2026
eendebakpt and others added 5 commits September 21, 2026 09:32
@eendebakpt
Merge remote-tracking branch 'origin/main' into pr157483-merge
8873fee
# Conflicts:
#	Modules/_ctypes/clinic/_ctypes.c.h
#	Modules/_io/clinic/bufferedio.c.h
#	Modules/_io/clinic/textio.c.h
#	Modules/clinic/_asynciomodule.c.h
@eendebakpt @claude
pythongh-157407: Rename NEWS entry to the correct issue number
22c7704
Co-Authored-By: Claude Fable 5.1 <[email protected]>
@eendebakpt
Merge remote-tracking branch 'origin/main' into feature/clinic-posonl…
f3f73f9
…y-defclass-2

# Conflicts:
#	Modules/_io/clinic/bufferedio.c.h
#	Modules/_io/clinic/fileio.c.h
#	Modules/_io/clinic/iobase.c.h
#	Modules/_io/clinic/textio.c.h
#	Modules/_io/clinic/winconsoleio.c.h
@eendebakpt
Merge branch 'main' into feature/clinic-posonly-defclass-2
b77aaa0
@eendebakpt
Merge remote-tracking branch 'origin/main' into feature/clinic-posonl…
cb0b107
…y-defclass-2

# Conflicts:
#	Modules/_decimal/clinic/_decimal.c.h
#	Modules/clinic/_dbmmodule.c.h
#	Modules/clinic/_elementtree.c.h
#	Modules/clinic/_gdbmmodule.c.h
#	Modules/clinic/_zoneinfo.c.h
@eendebakpt
eendebakpt enabled auto-merge (squash) September 27, 2026 21:09
@eendebakpt
eendebakpt merged commit 1c4fa4f into python:main Sep 27, 2026
65 checks passed

Uh oh!

There was an error while loading. Please reload this page.

@bedevere-app bedevere-app Bot removed the awaiting merge label Sep 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@methane methane methane approved these changes
@erlend-aasland erlend-aasland Awaiting requested review from erlend-aasland erlend-aasland is a code owner
@ericsnowcurrently ericsnowcurrently Awaiting requested review from ericsnowcurrently ericsnowcurrently is a code owner
@AA-Turner AA-Turner Awaiting requested review from AA-Turner AA-Turner is a code owner

Uh oh!

There was an error while loading. Please reload this page.

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Uh oh!

There was an error while loading. Please reload this page.

2 participants

@eendebakpt @methane
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
You are visitor 01402520 — GeezerVison does not store the pages you look up.
Best viewed with Netscape Navigator 4.7 or Internet Explorer 6 at 800×600. No cookies required.