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-132732: Automatically constant evaluate pure operations by Fidget-Spinner · Pull Request #132733 · python/cpython

Conversation

@Fidget-Spinner

@Fidget-Spinner Fidget-Spinner commented Apr 19, 2025 •
edited by bedevere-app Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member
  • Issue: Constant evaluate/propagate pure ops automatically #132732

Sorry, something went wrong.

Uh oh!

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

All reactions
@Fidget-Spinner
Automatically constant evaluate pure operations
1ffbb6b
@Fidget-Spinner
Fidget-Spinner requested a review from markshannon as a code owner April 19, 2025 16:21
@python-cla-bot

python-cla-bot Bot commented Apr 19, 2025 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown

All commit authors signed the Contributor License Agreement.

CLA signed

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-app bedevere-app Bot added the awaiting core review label Apr 19, 2025
@Fidget-Spinner
Fidget-Spinner requested review from brandtbucher and removed request for markshannon April 19, 2025 16:21
@bedevere-app bedevere-app Bot mentioned this pull request Apr 19, 2025
Constant evaluate/propagate pure ops automatically #132732
Closed
blurb-it Bot and others added 3 commits April 19, 2025 16:22
@blurb-it
📜🤖 Added by blurb_it.
691084d
@Fidget-Spinner
Fix tests
b89e4dc
@Fidget-Spinner
Merge branch 'pure' of github.com:Fidget-Spinner/cpython into pure
0959918
StanFromIreland
StanFromIreland reviewed Apr 19, 2025
View reviewed changes
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2025-04-19-16-22-47.gh-issue-132732.jgqhlF.rst Resolved

Uh oh!

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

@brandtbucher brandtbucher mentioned this pull request Apr 24, 2025
gh-131798: Use sym_new_type instead of sym_new_not_null for _BUILD_STRING, _BUILD_SET #132564
Merged
brandtbucher
brandtbucher reviewed Apr 24, 2025
View reviewed changes

@brandtbucher brandtbucher left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is really neat!

Other than two opcodes I found that shouldn't be marked pure, I just have one thought:

Rather than rewriting the bodies like this to use the symbols-manipulating functions (which seems error-prone), would we be able to just use stackrefs to do this?

For example, _BINARY_OP_ADD_INT is defined like this:

PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
// ...
res = PyStackRef_FromPyObjectSteal(res_o);

Rather than rewriting uses of these functions, could it be easier to just do something like this, since we're guranteed not to escape?

if (sym_is_const(ctx, stack_pointer[-2]) && sym_is_const(ctx, stack_pointer[-1])) {
    // Generated code to turn constant symbols into stackrefs:
    _PyStackRef left = PyStackRef_FromPyObjectBorrow(sym_get_const(ctx, stack_pointer[-2]));
    _PyStackRef right = PyStackRef_FromPyObjectBorrow(sym_get_const(ctx, stack_pointer[-1]));
    _PyStackRef res;
    // Now the actual body, same as it appears in executor_cases.c.h:
    PyObject *left_o = PyStackRef_AsPyObjectBorrow(left);
    PyObject *right_o = PyStackRef_AsPyObjectBorrow(right);
    // ...
    res = PyStackRef_FromPyObjectSteal(res_o);
    // Generated code to turn stackrefs into constant symbols:
    stack_pointer[-1] = sym_new_const(ctx, PyStackRef_AsPyObjectSteal(res));
}

I'm not too familiar with the design of the cases generator though, so maybe this is way harder or something. Either way, I'm excited to see this get in!

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Python/bytecodes.c Resolved

Uh oh!

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

Comment thread Python/bytecodes.c Resolved

Uh oh!

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

Comment thread Python/bytecodes.c Resolved

Uh oh!

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

@Fidget-Spinner

Fidget-Spinner commented Apr 24, 2025

Copy link
Copy Markdown
Member Author

Rather than rewriting uses of these functions, could it be easier to just do something like this, since we're guranteed not to escape?

Seems feasible. I could try to rewrite all occurences of the variable with a stackref-producing const one. Let me try that.

All reactions

Sorry, something went wrong.

Uh oh!

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

Fidget-Spinner added 2 commits April 25, 2025 07:16
@Fidget-Spinner
Merge remote-tracking branch 'upstream/main' into pure
2541683
@Fidget-Spinner
Apply review suggestions
d5b2208
@Fidget-Spinner

Fidget-Spinner commented Apr 25, 2025

Copy link
Copy Markdown
Member Author

I've verified no refleak on test_capi.test_opt locally apart from #132731 which is pre-existing.

All reactions

Sorry, something went wrong.

Uh oh!

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

@Fidget-Spinner
reduce diff
71ced86
@Fidget-Spinner Fidget-Spinner mentioned this pull request Apr 26, 2025
gh-131798: JIT: Propagate the result in _BINARY_OP_SUBSCR_TUPLE_INT #133003
Merged
@markshannon

markshannon commented Apr 30, 2025

Copy link
Copy Markdown
Member

There's a lot going on in this PR, probably too much for one PR.

Could we start with a PR to fix up the pure annotations so that they are on the correct instructions and maybe add the pure_guard annotation that Brandt suggested?

All reactions

Sorry, something went wrong.

Uh oh!

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

@markshannon

markshannon commented Apr 30, 2025

Copy link
Copy Markdown
Member

Could we have the default code generator generate a function for the body of the pure instruction and then call that from the three interpreters?

All reactions

Sorry, something went wrong.

Uh oh!

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

@brandtbucher

brandtbucher commented Apr 30, 2025

Copy link
Copy Markdown
Member

Could we have the default code generator generate a function for the body of the pure instruction and then call that from the three interpreters?

Hm, I think I’d prefer not to. Sounds like it could hurt performance, especially for the JIT (where things can’t inline).

All reactions

Sorry, something went wrong.

Uh oh!

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

@brandtbucher

brandtbucher commented Apr 30, 2025

Copy link
Copy Markdown
Member

I think a good progression would be:

  • Implement the pure attribute, and the optimizer changes. Remove the pure attributes where they don’t belong (so nothing breaks) and leave the existing ones as proof that the implementation works. (This PR)
  • Audit the existing non-pure bytecodes and add pure where it makes sense. (Follow-up PR)
  • Implement the pure_guard attribute, and annotate any bytecodes that can use it. (Follow-up PR)
All reactions

Sorry, something went wrong.

Uh oh!

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

@Fidget-Spinner

Fidget-Spinner commented Apr 30, 2025

Copy link
Copy Markdown
Member Author

Could we have the default code generator generate a function for the body of the pure instruction and then call that from the three interpreters?

Hm, I think I’d prefer not to. Sounds like it could hurt performance, especially for the JIT (where things can’t inline).

I thought about this and I think we can inline if we autogenerate a header file and include that directly. But then we're at the mercy of the compiler in both the normal interpreter and the JIT deciding to inline or not to inline the body again. Which I truly do not want.

All reactions

Sorry, something went wrong.

Uh oh!

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

Fidget-Spinner added 2 commits May 7, 2025 06:48
@Fidget-Spinner
Merge remote-tracking branch 'upstream/main' into pure
a10d5a1
@Fidget-Spinner
Update pycore_opcode_metadata.h
d22f165
@Fidget-Spinner

Fidget-Spinner commented May 8, 2025

Copy link
Copy Markdown
Member Author

@brandtbucher @markshannon what can I do to get this PR moving?

@tomasr8 if youd like to review, here's a summary of the PR:

  1. If a bytecode operation is pure (no side effects) we can mark it as pure in bytecodes.c.
  2. In the optimizer, we automatically generate the body that does evaluation of the symbolic constants by copy pasting the bytecodes.c definition into the optimizer's C code. Of course we check that the inputs are constants first.
  3. All changes to the cases generator is for the second point.
tomasr8 reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

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

@tomasr8

tomasr8 commented May 8, 2025

Copy link
Copy Markdown
Member

Thanks for the ping! I actually wanted to try/review this PR, I was just very busy this week with work :/ I'll have a look this weekend :)

Fidget-Spinner reacted with heart emoji
All reactions
  • ❤️ 1 reaction

Sorry, something went wrong.

Uh oh!

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

tomasr8
tomasr8 reviewed May 9, 2025
View reviewed changes

@tomasr8 tomasr8 left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only had time to skim the PR, I'll do a more thorough review this weekend :)

Sorry, something went wrong.

Uh oh!

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

Fidget-Spinner reacted with heart emoji
All reactions
  • ❤️ 1 reaction
Comment thread Python/optimizer_bytecodes.c Resolved

Uh oh!

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

Comment thread Python/optimizer_analysis.c Resolved

Uh oh!

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

Comment thread Tools/cases_generator/optimizer_generator.py Resolved

Uh oh!

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

Comment thread Tools/cases_generator/optimizer_generator.py Resolved

Uh oh!

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

@Fidget-Spinner @tomasr8
Apply changes from code review
8ae38c7
Co-Authored-By: Tomas R. <[email protected]>
@markshannon

markshannon commented Jun 20, 2025

Copy link
Copy Markdown
Member

In case it wasn't clear. The helper functions would be:
PyObject *compare_op_0(PyObject *a, PyObject *b) { return PyObject_RichCompare(a, b, 0) }
and so on.

All reactions

Sorry, something went wrong.

Uh oh!

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

@python python deleted a comment from Rk13-gold Jun 20, 2025
@Fidget-Spinner

Fidget-Spinner commented Jun 20, 2025

Copy link
Copy Markdown
Member Author

In case it wasn't clear. The helper functions would be: PyObject *compare_op_0(PyObject *a, PyObject *b) { return PyObject_RichCompare(a, b, 0) } and so on.

Is this the same as this?

If you're worried about the bulk of the generated code, I can open an issue for someone to make a follow up PR to generate function templates from the bytecodes.c file, similar to what we already do for the tail calling interpreter. This would allow us to just call the function. That should go into a follow-up commit though, because it requires changes that affect more than just the optimizer (it will also touch executor_cases and such).

All reactions

Sorry, something went wrong.

Uh oh!

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

markshannon
markshannon requested changes Jun 27, 2025
View reviewed changes

@markshannon markshannon left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once skip_to is removed from generators_common, this becomes nicely self contained.

With it properly encapsulated, it should be easy to modify in the future should we decide to use a slightly different approach.

I've a few more suggestions for tidying things up, but nothing fundamental.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Python/bytecodes.c Outdated
}

pure op(_BINARY_OP_EXTEND, (descr/4, left, right -- res)) {
pure op(_BINARY_OP_EXTEND, (descr/4, left, right -- res)) {

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This isn't "pure". It can do anything

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/generators_common.py Outdated
out.emit(tkn)
raise analysis_error(f"Expecting {end}. Reached end of file", tkn)

def skip_to(tkn_iter: TokenIterator, end: str) -> Token:

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is only used in the optimizer emitter (and I don't think it is needed there anyway)

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
write_header,
Emitter,
TokenIterator,
skip_to,

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See earlier comment.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
) -> bool:
skip_to(tkn_iter, "SEMI")

emitter = OptimizerConstantEmitter(self.out, {}, self.original_uop, copy.deepcopy(self.stack))

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
emitter = OptimizerConstantEmitter(self.out, {}, self.original_uop, copy.deepcopy(self.stack))
emitter = OptimizerConstantEmitter(self.out, {}, self.original_uop, self.stack.copy())

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
"""

import argparse
import copy

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Stacks already support copying efficiently and correctly.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
storage: Storage,
inst: Instruction | None,
) -> bool:
skip_to(tkn_iter, "SEMI")

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If you're just going to throw away the arguments, why have them?
Either check the names match or, better still, don't require the inputs at all.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
return not unconditional


def replace_opcode_if_evaluates_pure_identifiers(uop: Uop) -> list[str]:

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You already have the input names from the uop, [item.name for item in uop.stack.inputs]

Sorry, something went wrong.

Uh oh!

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

All reactions

@Fidget-Spinner Fidget-Spinner Jun 27, 2025

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No this is the input names from the REPLACE_OPCODE_IF_EVALUATES_PURE macro. However, now that you mentioned it, I should get the names from the replacement function, not from this. So thanks for pointing it out.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
out.emit(f"{type}{cache.name} = ({cast})this_instr->operand0;\n")
if override:
emitter = OptimizerEmitter(out, {})
emitter = OptimizerEmitter(out, {}, uop, copy.deepcopy(stack))

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
emitter = OptimizerEmitter(out, {}, uop, copy.deepcopy(stack))
emitter = OptimizerEmitter(out, {}, uop, stack.copy())

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Tools/cases_generator/optimizer_generator.py Outdated
return "JitOptRef "

def stackref_type_name(var: StackItem) -> str:
if var.is_array():

@markshannon markshannon Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
if var.is_array():
assert not var.is_array(), "Unsafe to convert a symbol to an array-like StackRef."

Check this in the caller if that makes sense, and raise an analysis error there so we aren't relying on assert to handle input errors.

Sorry, something went wrong.

Uh oh!

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

All reactions
@bedevere-app bedevere-app Bot added awaiting changes and removed awaiting change review labels Jun 27, 2025
@bedevere-app

bedevere-app Bot commented Jun 27, 2025

Copy link
Copy Markdown

When you're done making the requested changes, leave the comment: I have made the requested changes; please review again.

All reactions

Sorry, something went wrong.

Uh oh!

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

Fidget-Spinner added 3 commits June 27, 2025 17:48
@Fidget-Spinner
Address review
0e9ce84
@Fidget-Spinner
reduce diff
f2fc3fc
@Fidget-Spinner
fix mypy
2408fb0
@Fidget-Spinner

Fidget-Spinner commented Jun 27, 2025

Copy link
Copy Markdown
Member Author

Thanks Mark for the review. The code is a lot cleaner now and self-contained.

I have made the requested changes; please review again

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-app bedevere-app Bot added awaiting change review and removed awaiting changes labels Jun 27, 2025
@bedevere-app

bedevere-app Bot commented Jun 27, 2025

Copy link
Copy Markdown

Thanks for making the requested changes!

@markshannon, @tomasr8: please review the changes made to this pull request.

All reactions

Sorry, something went wrong.

Uh oh!

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

@bedevere-app
bedevere-app Bot requested review from markshannon and tomasr8 June 27, 2025 09:51
markshannon
markshannon approved these changes Jun 27, 2025
View reviewed changes

@markshannon markshannon left a comment

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's much better. Thanks.

Sorry, something went wrong.

Uh oh!

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

All reactions
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting change review labels Jun 27, 2025
@Fidget-Spinner
fix wrong error message
e40cb06
@Fidget-Spinner
Fidget-Spinner merged commit 695ab61 into python:main Jun 27, 2025
@bedevere-app bedevere-app Bot removed the awaiting merge label Jun 27, 2025
@Fidget-Spinner
Fidget-Spinner deleted the pure branch June 27, 2025 11:37
@bedevere-bot

bedevere-bot commented Jun 27, 2025

Copy link
Copy Markdown

⚠️⚠️⚠️ Buildbot failure ⚠️⚠️⚠️

Hi! The buildbot iOS ARM64 Simulator 3.x (tier-3) has failed when building commit 695ab61.

What do you need to do:

  1. Don't panic.
  2. Check the buildbot page in the devguide if you don't know what the buildbots are or how they work.
  3. Go to the page of the buildbot that failed (https://buildbot.python.org/#/builders/1380/builds/4083) and take a look at the build logs.
  4. Check if the failure is related to this commit (695ab61) or if it is a false positive.
  5. If the failure is related to this commit, please, reflect that on the issue and make a new Pull Request with a fix.

You can take a look at the buildbot page here:

https://buildbot.python.org/#/builders/1380/builds/4083

Failed tests:

  • test_socketserver

Failed subtests:

  • test_ThreadingUnixDatagramServer - test.test_socketserver.SocketServerTest.test_ThreadingUnixDatagramServer
  • test_UnixDatagramServer - test.test_socketserver.SocketServerTest.test_UnixDatagramServer

Summary of the results of the build (if available):

==

Click to see traceback logs
Traceback (most recent call last):
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 222, in test_UnixDatagramServer
    self.run_server(socketserver.UnixDatagramServer,
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    socketserver.DatagramRequestHandler,
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    self.dgram_examine)
                    ^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/support/threading_helper.py", line 66, in decorator
    return func(*args)
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 133, in run_server
    testfunc(svrcls.address_family, addr)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 160, in dgram_examine
    buf = data = receive(s, 100)
                 ~~~~~~~^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 43, in receive
    raise RuntimeError("timed out on %r" % (sock,))
RuntimeError: timed out on <socket.socket fd=23, family=1, type=2, proto=0, laddr=./test_python_x18vehwp.sock>


Traceback (most recent call last):
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/threading.py", line 1074, in _bootstrap_inner
    self._context.run(self.run)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/threading.py", line 1016, in run
    self._target(*self._args, **self._kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 240, in serve_forever
    self._handle_request_noblock()
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 320, in _handle_request_noblock
    self.handle_error(request, client_address)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 318, in _handle_request_noblock
    self.process_request(request, client_address)
    ~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 349, in process_request
    self.finish_request(request, client_address)
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 362, in finish_request
    self.RequestHandlerClass(request, client_address, self)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 768, in __init__
    self.finish()
    ~~~~~~~~~~~^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 863, in finish
    self.socket.sendto(self.wfile.getvalue(), self.client_address)
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ConnectionResetError: [Errno 54] Connection reset by peer
ERROR


Traceback (most recent call last):
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 228, in test_ThreadingUnixDatagramServer
    self.run_server(socketserver.ThreadingUnixDatagramServer,
    ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    socketserver.DatagramRequestHandler,
                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
                    self.dgram_examine)
                    ^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/support/threading_helper.py", line 66, in decorator
    return func(*args)
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 133, in run_server
    testfunc(svrcls.address_family, addr)
    ~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 160, in dgram_examine
    buf = data = receive(s, 100)
                 ~~~~~~~^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/test/test_socketserver.py", line 43, in receive
    raise RuntimeError("timed out on %r" % (sock,))
RuntimeError: timed out on <socket.socket fd=23, family=1, type=2, proto=0, laddr=./test_python_a8m4t39h.sock>


Traceback (most recent call last):
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/threading.py", line 1074, in _bootstrap_inner
    self._context.run(self.run)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/threading.py", line 1016, in run
    self._target(*self._args, **self._kwargs)
    ~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 699, in process_request_thread
    self.handle_error(request, client_address)
    ~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 697, in process_request_thread
    self.finish_request(request, client_address)
    ~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 362, in finish_request
    self.RequestHandlerClass(request, client_address, self)
    ~~~~~~~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 768, in __init__
    self.finish()
    ~~~~~~~~~~~^^
  File "/Users/buildbot/Library/Developer/XCTestDevices/3299090E-A190-41F9-9EFB-E7EB12DA3473/data/Containers/Bundle/Application/EDDB3F71-0E9C-40F0-97D8-EB8A643BB963/iOSTestbed.app/python/lib/python3.15/socketserver.py", line 863, in finish
    self.socket.sendto(self.wfile.getvalue(), self.client_address)
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
ConnectionResetError: [Errno 54] Connection reset by peer
Warning -- threading_cleanup() failed to clean up threads in 1.0 seconds
Warning --   before: thread count=0, dangling=1
Warning --   after: thread count=1, dangling=4
Warning -- Dangling thread: <_MainThread(MainThread, started 4302897664)>
Warning -- Dangling thread: <Thread(Thread-2933 (process_request_thread), stopped 6218264576)>
Warning -- Dangling thread: <Thread(Thread-2932 (process_request_thread), stopped 6201438208)>
Warning -- Dangling thread: <Thread(<class 'socketserver.ThreadingUnixDatagramServer'> serving, started daemon 6184611840)>
ERROR
All reactions

Sorry, something went wrong.

Uh oh!

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

brandtbucher
brandtbucher reviewed Jun 27, 2025
View reviewed changes
Comment thread Python/optimizer_symbols.c
return (typ == &PyLong_Type) ||
(typ == &PyUnicode_Type) ||
(typ == &PyFloat_Type) ||
(typ == &PyTuple_Type) ||

@brandtbucher brandtbucher Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Fidget-Spinner, tuple isn't safe for comparisons either. The contained items may escape when compared.

We could check the items recursively for safety using sym_tuple_getitem. Or just remove this.

I'm leaning slightly towards the recursive check, but either could make sense.

Sorry, something went wrong.

Uh oh!

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

All reactions

@brandtbucher brandtbucher Jun 27, 2025

Copy link
Copy Markdown
Member

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also add None here, as well.

Sorry, something went wrong.

Uh oh!

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

All reactions

@Fidget-Spinner Fidget-Spinner Jun 27, 2025

Copy link
Copy Markdown
Member Author

There was a problem hiding this comment.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok let's remove it.

Sorry, something went wrong.

Uh oh!

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

All reactions
@brandtbucher brandtbucher mentioned this pull request Jul 1, 2025
The JIT's "pure" _BINARY_OP evaluation produces UB (and incorrect results) #136183
Closed
AndPuQing pushed a commit to AndPuQing/cpython that referenced this pull request Jul 11, 2025
@Fidget-Spinner @tomasr8 @AndPuQing
pythongh-132732: Automatically constant evaluate pure operations (pyt…
a6a656f
…honGH-132733)

This adds a "macro" to the optimizer DSL called "REPLACE_OPCODE_IF_EVALUATES_PURE", which allows automatically constant evaluating a bytecode body if certain inputs have no side effects upon evaluations (such as ints, strings, and floats).


Co-authored-by: Tomas R. <[email protected]>
Pranjal095 pushed a commit to Pranjal095/cpython that referenced this pull request Jul 12, 2025
@Fidget-Spinner @tomasr8 @Pranjal095
pythongh-132732: Automatically constant evaluate pure operations (pyt…
836d9fa
…honGH-132733)

This adds a "macro" to the optimizer DSL called "REPLACE_OPCODE_IF_EVALUATES_PURE", which allows automatically constant evaluating a bytecode body if certain inputs have no side effects upon evaluations (such as ints, strings, and floats).


Co-authored-by: Tomas R. <[email protected]>
taegyunkim pushed a commit to taegyunkim/cpython that referenced this pull request Aug 4, 2025
@Fidget-Spinner @tomasr8 @taegyunkim
pythongh-132732: Automatically constant evaluate pure operations (pyt…
c54e755
…honGH-132733)

This adds a "macro" to the optimizer DSL called "REPLACE_OPCODE_IF_EVALUATES_PURE", which allows automatically constant evaluating a bytecode body if certain inputs have no side effects upon evaluations (such as ints, strings, and floats).


Co-authored-by: Tomas R. <[email protected]>
Agent-Hellboy pushed a commit to Agent-Hellboy/cpython that referenced this pull request Aug 19, 2025
@Fidget-Spinner @tomasr8 @Agent-Hellboy
pythongh-132732: Automatically constant evaluate pure operations (pyt…
73ffe50
…honGH-132733)

This adds a "macro" to the optimizer DSL called "REPLACE_OPCODE_IF_EVALUATES_PURE", which allows automatically constant evaluating a bytecode body if certain inputs have no side effects upon evaluations (such as ints, strings, and floats).


Co-authored-by: Tomas R. <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@sobolevn sobolevn sobolevn left review comments
@brandtbucher brandtbucher brandtbucher left review comments
@StanFromIreland StanFromIreland StanFromIreland left review comments
@markshannon markshannon markshannon approved these changes
@tomasr8 tomasr8 Awaiting requested review from tomasr8 tomasr8 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.

7 participants

@Fidget-Spinner @markshannon @brandtbucher @tomasr8 @bedevere-bot @sobolevn @StanFromIreland
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 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.