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 — Remove redundant decref from _PyLong_Negate · Issue #143050 · python/cpython

Remove redundant decref from _PyLong_Negate #143050

New issue
Copy link
New issue
Copy link
Closed
Closed
Remove redundant decref from _PyLong_Negate#143050
Copy link
Labels
interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)release-blockertype-featureA feature request or enhancementA feature request or enhancement

Description

@eendebakpt
eendebakpt
opened on Dec 21, 2025
Issue body actions

Feature or enhancement

Proposal:

In _PyLong_Negate there is a fast path for unique referenced longs. The slow path assumes the argument is a small int. We can add an assert for this condition, and remove the final decref (small ints are immortal).

Has this already been discussed elsewhere?

No response given

Links to previous discussion of this feature:

No response

Linked PRs

  • gh-143050: Remove redundant decref in _PyLong_Negate (gh-143051) #143051
  • Revert "gh-143050: Remove redundant decref in _PyLong_Negate (gh-143051)" #145891
  • gh-143050: correct PyLong_FromString() to use _PyLong_Negate() #145901
  • [3.14] gh-143050: Correct PyLong_FromString() to use _PyLong_Negate() (GH-145901) #147331
  • [3.13] gh-143050: Correct PyLong_FromString() to use _PyLong_Negate() (#145901) #147437
  • gh-143050: add helper _PyLong_InitTag() #147956

Activity

Next
  1. eendebakpt
    added
    type-featureA feature request or enhancementA feature request or enhancement
    on Dec 21, 2025
  2. StanFromIreland
    added
    interpreter-core(Objects, Python, Grammar, and Parser dirs)(Objects, Python, Grammar, and Parser dirs)
    on Dec 21, 2025
  3. serhiy-storchaka commented on Dec 23, 2025

    @serhiy-storchaka
    serhiy-storchaka
    on Dec 23, 2025
    Member
    More actions

    Even if they are immortal, I prefer to keep incref/decref balanced. This saves time when you read code.

  4. sergey-miryanov commented on Dec 23, 2025

    @sergey-miryanov
    sergey-miryanov
    on Dec 23, 2025
    Contributor
    More actions

    Maybe it is worth to replace Py_DECREF with something like Py_DECREF_IMMORTAL?

  5. eendebakpt commented on Dec 23, 2025

    @eendebakpt
    eendebakpt
    on Dec 23, 2025
    ContributorAuthor
    More actions

    Maybe it is worth to replace Py_DECREF with something like Py_DECREF_IMMORTAL?

    I would be in favor of that. There is a related discussion here #124074

    Reacted by Sergey Miryanov
  6. colesbury
    added a commit that references this issue on Mar 10, 2026

    gh-143050: Remove redundant decref in _PyLong_Negate (gh-143051)

    5197ecb
  7. colesbury commented on Mar 10, 2026

    @colesbury
    colesbury
    on Mar 10, 2026
    Contributor
    More actions

    Thanks

  8. colesbury
    closed this as completedon Mar 10, 2026
  9. StanFromIreland
    reopened this on Mar 12, 2026
  10. StanFromIreland
    added a commit that references this issue on Mar 12, 2026

    Revert "pythongh-143050: Remove redundant decref in _PyLong_Negate (p…

    77db5c3
  11. StanFromIreland commented on Mar 12, 2026

    @StanFromIreland
    StanFromIreland
    on Mar 12, 2026
    Member
    More actions

    This introduced a regression that was caught by our OSS Fuzzer (https://oss-fuzz.com/testcase-detail/6342648498814976).

    $ ./python -c "
    import sys
    sys.set_int_max_str_digits(10000)
    
    while True:
        try:
            int('-' + '0' * 7000, 10)
        except:
            pass
    "
    python: Objects/longobject.c:371: _PyLong_Negate: Assertion `_long_is_small_int((PyObject *)x)' failed.
    Aborted                    (core dumped)
    
    full reproducer

    To reproduce, download the testcase: https://drive.google.com/file/d/1Ain_DfzbodyKU_YiwtZPaT4ViAOssvOt/view?usp=sharing

    And run it to trigger the assert, note that it requires a few iterations:

    $ ./python -c "
    import sys
    sys.set_int_max_str_digits(10000)
    with open('/tmp/inttestcase','rb') as f:
        data = f.read().decode('utf-8')
    
    while True:
        try:
            int(data, 10)
        except:
            pass
    "
    python: Objects/longobject.c:371: _PyLong_Negate: Assertion `_long_is_small_int((PyObject *)x)' failed.
    Aborted                    (core dumped)
    
  12. eendebakpt commented on Mar 12, 2026

    @eendebakpt
    eendebakpt
    on Mar 12, 2026
    ContributorAuthor
    More actions

    Thanks for reporting, I will have a look at the reproducer tomorrow.

  13. colesbury
    added a commit that references this issue on Mar 13, 2026

    Revert "gh-143050: Remove redundant decref in _PyLong_Negate (gh-143051…

    0adc728
  14. colesbury commented on Mar 13, 2026

    @colesbury
    colesbury
    on Mar 13, 2026
    Contributor
    More actions

    I stuck this into Claude and I think it (mostly) got it right:

    1. int('-' + '0' * 7000, 10) -> PyLong_FromString -> _pylong.int_from_string, which returns 0
    2. We then call _PyLong_FlipSign on it, which corrupts 0

    So it was a pre-existing bug in PyLong_FromString.

  15. skirpichev
    self-assigned this
    on Mar 13, 2026
  16. 13 remaining items

  17. vstinner
    closed this as completedon Mar 31, 2026
  18. github-project-automation
    moved this from Todo to Done in Release and Deferred blockers 🚫on Mar 31, 2026
  19. skirpichev commented on Mar 31, 2026

    @skirpichev
    skirpichev
    on Mar 31, 2026
    Member
    More actions

    I don't think that avoiding one Py_DECREF() in _PyLong_Negate() is worth it.

    Why not do it?

    I think that original PR was correct and now @eendebakpt can restore it with small adaptation (for a new helper).

  20. skirpichev
    added 3 commits that reference this issue on Apr 1, 2026

    pythongh-143050: add new helper _PyLong_Init()

    27a5b39

    pythongh-143050: add helper _PyLong_Init()

    bb287e6

    pythongh-143050: add helper _PyLong_Init()

    d7073e5
  21. vstinner commented on Apr 1, 2026

    @vstinner
    vstinner
    on Apr 1, 2026
    Member
    More actions

    Why not do it?

    I will quote @serhiy-storchaka:

    Even if they are immortal, I prefer to keep incref/decref balanced. This saves time when you read code.

  22. skirpichev commented on Apr 1, 2026

    @skirpichev
    skirpichev
    on Apr 1, 2026
    Member
    More actions

    Even if they are immortal, I prefer to keep incref/decref balanced.

    We can use _Py_DECREF_INT here, no?

  23. vstinner
    added a commit that references this issue on Apr 1, 2026

    gh-143050: Add helper _PyLong_InitTag() (#147956)

    b456cb2
  24. clin1234
    added 2 commits that reference this issue on Apr 16, 2026

    pythongh-143050: Correct PyLong_FromString() to use _PyLong_Negate() (p…

    a7070f3

    pythongh-143050: Add helper _PyLong_InitTag() (python#147956)

    f178a75
  25. ljfp
    added 4 commits that reference this issue on Apr 25, 2026

    pythongh-143050: Remove redundant decref in _PyLong_Negate (pythongh-…

    63a9908

    Revert "pythongh-143050: Remove redundant decref in _PyLong_Negate (p…

    da4a55e

    pythongh-143050: Correct PyLong_FromString() to use _PyLong_Negate() (p…

    2f7f76e

    pythongh-143050: Add helper _PyLong_InitTag() (python#147956)

    8099933
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)release-blockertype-featureA feature request or enhancementA feature request or enhancement

    Projects

    • Release and Deferred blockers 🚫
      Status
      Done
      Show more project fields

    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.