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 — Specialize calls to inherited `list.append` on list subclasses · Issue #155456 · python/cpython

Specialize calls to inherited list.append on list subclasses #155456

New issue
Copy link
New issue
Copy link
Open
Open
Specialize calls to inherited list.append on list subclasses#155456
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is providedperformancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement

Description

@marinelay
marinelay
opened on Aug 10, 2026
Issue body actions

Feature or enhancement

Proposal:

I was reading the code around CALL_LIST_APPEND and noticed a possible optimization for list subclasses that inherit list.append without overriding it.

I am wondering whether inherited list.append calls could be supported deliberately, with matching specialization time and runtime checks.

For example:

class MyList(list):
    pass

def append_one(values):
    values.append(1)

For an exact list, this call can specialize to CALL_LIST_APPEND. For MyList, it currently specializes to CALL_METHOD_DESCRIPTOR_O, even though attribute lookup still resolves to the built-in list.append.


The specialization is made in specialize_method_descriptor().

It checks that the receiver is an exact list:

if ((PyObject *)descr == list_append && oparg == 1) {
    assert(self_or_null != NULL);
    if (PyList_CheckExact(self_or_null)) {
        specialize(instr, CALL_LIST_APPEND);
        return 0;
    }
}

and CALL_LIST_APPEND macro is defined as follows:

macro(CALL_LIST_APPEND) =
    unused/1 +
    unused/2 +
    _GUARD_CALLABLE_LIST_APPEND +
    _GUARD_NOS_NOT_NULL +
    _GUARD_NOS_LIST +
    _CALL_LIST_APPEND +
    POP_TOP +
    POP_TOP;

As far as I understand, this should exclude subclasses that shadow append.

But, _CALL_LIST_APPEND ultimately uses _PyList_AppendTakeRef, which accepts list subclasses through PyList_Check, just like the generic list.append path. So the underlying append operation already appears to support subclasses.

The remaining problem is ensuring that the specialization and runtime guards admit them safely.

Possible approach

The safer structure seems to be leaving the existing instruction unchanged and adding a separate specialization for list subclasses such as CALL_LIST_APPEND_SUBTYPE

The specializer could select the existing instruction for exact lists and the new instruction for subclasses:

if (PyList_CheckExact(self_or_null)) {
    specialize(instr, CALL_LIST_APPEND);
}
else if (PyList_Check(self_or_null)) {
    specialize(instr, CALL_LIST_APPEND_SUBTYPE);
}

Both instructions could then share _CALL_LIST_APPEND while keeping their receiver assumptions separate:

macro(CALL_LIST_APPEND) =
    unused/1 +
    unused/2 +
    _GUARD_CALLABLE_LIST_APPEND +
    _GUARD_NOS_NOT_NULL +
    _GUARD_NOS_LIST +
    _CALL_LIST_APPEND +
    POP_TOP +
    POP_TOP;

macro(CALL_LIST_APPEND_SUBTYPE) =
    unused/1 +
    unused/2 +
    _GUARD_CALLABLE_LIST_APPEND +
    _GUARD_NOS_NOT_NULL +
    _GUARD_NOS_LIST_SUBTYPE +
    _CALL_LIST_APPEND +
    POP_TOP +
    POP_TOP;
op(_GUARD_NOS_LIST_SUBTYPE, (self -- self)) {
    EXIT_IF(!PyList_Check(self));
}

This keeps the meaning of CALL_LIST_APPEND unchanged, while isolating the new subtype behavior.

Alternative approach

A smaller alternative would be to let the existing CALL_LIST_APPEND instruction accept list subclasses:

- if (PyList_CheckExact(self_or_null)) {
+ if (PyList_Check(self_or_null)) {
      specialize(instr, CALL_LIST_APPEND);
  }

and replace its exact list guard:

 macro(CALL_LIST_APPEND) =
     unused/1 +
     unused/2 +
     _GUARD_CALLABLE_LIST_APPEND +
     _GUARD_NOS_NOT_NULL +
-    _GUARD_NOS_LIST +
+    _GUARD_NOS_LIST_SUBTYPE +
     _CALL_LIST_APPEND +
     POP_TOP +
     POP_TOP;

It is a smaller code change, but it broadens the meaning of an existing instruction. I have not verified all assumptions outside, so I am not sure that changing the existing instruction is the right approach.


Is there any semantic or implementation reason why a list subclass inheriting the built-in list.append should not reuse the _CALL_LIST_APPEND fast path?

If the optimization is worthwhile, would it be preferable to extend the existing instruction, or to keep the new behavior isolated in a separate specialization?

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

#141367

Linked PRs

  • gh-155456 Specialize list.append for list subclasses #155474

Activity

  1. marinelay
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on Aug 10, 2026
  2. Sumitha007 commented on Aug 10, 2026

    @Sumitha007
    Sumitha007
    on Aug 10, 2026
    More actions

    I’d like to work on this issue. I’ll investigate the existing specialization and guards first, then prepare a patch with tests if the optimization is safe.

    Reacted by Stefan Pochmann
  3. cocolato
    added
    performancePerformance or resource usagePerformance or resource usage
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    on Aug 10, 2026
  4. picnixz commented on Aug 10, 2026

    @picnixz
    picnixz
    on Aug 10, 2026
    Member
    More actions

    @Sumitha007 We still didn't decide whether this is a relevant feature to have.


    I don't think it's common to subclass lists honestly. I don't think it's really worth the change here.

  5. picnixz
    added
    pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is provided
    on Aug 10, 2026
  6. picnixz commented on Aug 10, 2026

    @picnixz
    picnixz
    on Aug 10, 2026
    Member
    More actions

    cc @Fidget-Spinner

  7. marinelay commented on Aug 10, 2026

    @marinelay
    marinelay
    on Aug 10, 2026
    ContributorAuthor
    More actions

    I agree that it is not a very common pattern.
    I’ve occasionally seen list subclasses used to implement special data structures (such as XML node list or NLTK tree, ...), but I’m not sure how commonly they’re used in application.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)pendingThe issue will be closed if no feedback is providedThe issue will be closed if no feedback is providedperformancePerformance or resource usagePerformance or resource usagetype-featureA feature request or enhancementA feature request or enhancement

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

      You are visitor 01402503 — 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.