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-105481: Generate the opcode lists in dis from data extracted from bytecodes.c by iritkatriel · Pull Request #106758 · python/cpython

Conversation

@iritkatriel

@iritkatriel iritkatriel commented Jul 14, 2023 •
edited by bedevere-bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Member

The generated lists are more correct than the (old) hard-coded ones, which were not maintained properly.

For example:

Old:

>>> [opcode.opname[op] for op in opcode.haslocal]
['LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'LOAD_FAST_CHECK', 'LOAD_FAST_AND_CLEAR', 'STORE_FAST_MAYBE_NULL', 'LOAD_CLOSURE']

New:

>>> [opcode.opname[op] for op in opcode.haslocal]
['LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'LOAD_FAST_CHECK', 'MAKE_CELL', 'LOAD_DEREF', 'STORE_DEREF', 'DELETE_DEREF', 'LOAD_FAST_AND_CLEAR', 'LOAD_FAST_LOAD_FAST', 'STORE_FAST_LOAD_FAST', 'STORE_FAST_STORE_FAST', 'LOAD_FROM_DICT_OR_DEREF', 'STORE_FAST_MAYBE_NULL', 'LOAD_CLOSURE']
  • Issue: Generate opcode metadata from bytecodes.c instead of opcode.py #105481

Sorry, something went wrong.

Uh oh!

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

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction
@iritkatriel
pythongh-105481: add haslocal to _opcode.py. Generate most oplists in…
36a7d56
… opcode.py with the functions in _opcode.py
@iritkatriel
iritkatriel requested a review from markshannon as a code owner July 14, 2023 21:05
@bedevere-bot bedevere-bot added the awaiting core review label Jul 14, 2023
@bedevere-bot bedevere-bot mentioned this pull request Jul 14, 2023
Generate opcode metadata from bytecodes.c instead of opcode.py #105481
Closed
@iritkatriel
iritkatriel requested a review from gvanrossum July 14, 2023 21:05
iritkatriel
iritkatriel commented Jul 14, 2023
View reviewed changes
Comment thread Lib/opcode.py Resolved

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 14, 2023

Copy link
Copy Markdown
Member Author

The generated lists are more correct than the (old) hard-coded ones, which were not maintained properly.

For example:

Old:

>>> [opcode.opname[op] for op in opcode.haslocal]
['LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'LOAD_FAST_CHECK', 'LOAD_FAST_AND_CLEAR', 'STORE_FAST_MAYBE_NULL', 'LOAD_CLOSURE']

New:

>>> [opcode.opname[op] for op in opcode.haslocal]
['LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'LOAD_FAST_CHECK', 'MAKE_CELL', 'LOAD_DEREF', 'STORE_DEREF', 'DELETE_DEREF', 'LOAD_FAST_AND_CLEAR', 'LOAD_FAST_LOAD_FAST', 'STORE_FAST_LOAD_FAST', 'STORE_FAST_STORE_FAST', 'LOAD_FROM_DICT_OR_DEREF', 'STORE_FAST_MAYBE_NULL', 'LOAD_CLOSURE']

Maybe in this case actually the new list is incorrect - all the opcodes with DEREF seem to belong to hasfree rather than haslocal:

[opcode.opname[op] for op in opcode.hasfree]
['MAKE_CELL', 'LOAD_DEREF', 'STORE_DEREF', 'DELETE_DEREF', '<148>', 'LOAD_FROM_DICT_OR_DEREF']

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

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

gvanrossum
gvanrossum reviewed Jul 14, 2023
View reviewed changes
Comment thread Lib/opcode.py Resolved

Uh oh!

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

Comment thread Lib/opcode.py Outdated
for op, i in opmap.items():
opname[i] = op

# _opcode may not be ready during early stages of the build

@gvanrossum gvanrossum Jul 14, 2023

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.

Is that separate from Larry's limerick at the top?

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Jul 14, 2023

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.

It's the same thing. I'm planning to try and get rid of this issue - figure out what is needed in the build and separate it out somehow.

Sorry, something went wrong.

Uh oh!

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

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@gvanrossum gvanrossum Jul 14, 2023 •
edited
Loading

Uh oh!

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

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.

Bot we've gotta keep a limerick in. :-)

Sorry, something went wrong.

Uh oh!

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

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

@iritkatriel iritkatriel Jul 15, 2023

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.

Is it in the stable ABI?

Sorry, something went wrong.

Uh oh!

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

olife-png reacted with thumbs up emoji gvanrossum reacted with laugh emoji
All reactions
  • 👍 1 reaction
  • 😄 1 reaction
Comment thread Tools/cases_generator/generate_cases.py Resolved

Uh oh!

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

@gvanrossum

gvanrossum commented Jul 14, 2023

Copy link
Copy Markdown
Member

The generated lists are more correct than the (old) hard-coded ones, which were not maintained properly.
For example:
Old:

>>> [opcode.opname[op] for op in opcode.haslocal]
['LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'LOAD_FAST_CHECK', 'LOAD_FAST_AND_CLEAR', 'STORE_FAST_MAYBE_NULL', 'LOAD_CLOSURE']

New:

>>> [opcode.opname[op] for op in opcode.haslocal]
['LOAD_FAST', 'STORE_FAST', 'DELETE_FAST', 'LOAD_FAST_CHECK', 'MAKE_CELL', 'LOAD_DEREF', 'STORE_DEREF', 'DELETE_DEREF', 'LOAD_FAST_AND_CLEAR', 'LOAD_FAST_LOAD_FAST', 'STORE_FAST_LOAD_FAST', 'STORE_FAST_STORE_FAST', 'LOAD_FROM_DICT_OR_DEREF', 'STORE_FAST_MAYBE_NULL', 'LOAD_CLOSURE']

Maybe in this case actually the new list is incorrect - all the opcodes with DEREF seem to belong to hasfree rather than haslocal:

[opcode.opname[op] for op in opcode.hasfree]
['MAKE_CELL', 'LOAD_DEREF', 'STORE_DEREF', 'DELETE_DEREF', '<148>', 'LOAD_FROM_DICT_OR_DEREF']

Ugh. Worse, now LOAD_CLOSURE is gone, it’s ambiguous. Who uses this? How? (Only dis.py?)

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 14, 2023

Copy link
Copy Markdown
Member Author

Ugh. Worse, now LOAD_CLOSURE is gone, it’s ambiguous. Who uses this? How? (Only dis.py?)

LOAD_CLOSURE is just an alias (pseudo op) for LOAD_FAST. It's in the haslocal list in the old and new version, no change there.

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

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

@iritkatriel
iritkatriel marked this pull request as draft July 14, 2023 21:34
@bedevere-bot bedevere-bot removed the awaiting core review label Jul 14, 2023
@iritkatriel
added HAS_FREE flag. Removed HAS_FREE from the HAS_LOCAL list
75019ca
@iritkatriel iritkatriel changed the title gh-105481: add haslocal to _opcode.py. Generate most oplists in opcode.py with the functions in _opcode.py gh-105481: add haslocal/hasfree to _opcode.py. Generate most oplists in opcode.py with the functions in _opcode.py Jul 14, 2023
@iritkatriel

iritkatriel commented Jul 14, 2023

Copy link
Copy Markdown
Member Author

Now it's like this:

Old:

>>> sorted([opcode.opname[op] for op in opcode.hasfree])
['<148>', 'DELETE_DEREF', 'LOAD_DEREF', 'LOAD_FROM_DICT_OR_DEREF', 'MAKE_CELL', 'STORE_DEREF']
>>> sorted([opcode.opname[op] for op in opcode.haslocal])
['DELETE_FAST', 'LOAD_CLOSURE', 'LOAD_FAST', 'LOAD_FAST_AND_CLEAR', 'LOAD_FAST_CHECK', 'STORE_FAST', 'STORE_FAST_MAYBE_NULL']

New:

>>> sorted([opcode.opname[op] for op in opcode.hasfree])
['DELETE_DEREF', 'LOAD_DEREF', 'LOAD_FROM_DICT_OR_DEREF', 'MAKE_CELL', 'STORE_DEREF']
>>> sorted([opcode.opname[op] for op in opcode.haslocal])
['DELETE_FAST', 'LOAD_CLOSURE', 'LOAD_FAST', 'LOAD_FAST_AND_CLEAR', 'LOAD_FAST_CHECK', 'LOAD_FAST_LOAD_FAST', 'STORE_FAST', 'STORE_FAST_LOAD_FAST', 'STORE_FAST_MAYBE_NULL', 'STORE_FAST_STORE_FAST']

The "<148>" is because in opcode.py in main we have hasfree.append(148) even though there is no such opcode.

In the haslocal list, we see that the old list is missing the super instructions.

olife-png reacted with thumbs up emoji olife-png reacted with hooray emoji
All reactions
  • 👍 1 reaction
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 14, 2023

Copy link
Copy Markdown
Member Author

For the other lists:

Old:

>>> sorted([opcode.opname[op] for op in opcode.hasconst])
['KW_NAMES', 'LOAD_CONST', 'RETURN_CONST']

New:

>>> sorted([opcode.opname[op] for op in opcode.hasconst])
['INSTRUMENTED_RETURN_CONST', 'KW_NAMES', 'LOAD_CONST', 'RETURN_CONST']

old is missing the INSTRUMENTED_*.

Old:

>>> sorted([opcode.opname[op] for op in opcode.hasname])
['DELETE_ATTR', 'DELETE_GLOBAL', 'DELETE_NAME', 'IMPORT_FROM', 'IMPORT_NAME', 'LOAD_ATTR', 'LOAD_FROM_DICT_OR_GLOBALS', 'LOAD_GLOBAL', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_SUPER_ATTR', 'LOAD_SUPER_METHOD', 'LOAD_ZERO_SUPER_ATTR', 'LOAD_ZERO_SUPER_METHOD', 'STORE_ATTR', 'STORE_GLOBAL', 'STORE_NAME']

New:

>>> sorted([opcode.opname[op] for op in opcode.hasname])
['DELETE_ATTR', 'DELETE_GLOBAL', 'DELETE_NAME', 'IMPORT_FROM', 'IMPORT_NAME', 'LOAD_ATTR', 'LOAD_FROM_DICT_OR_GLOBALS', 'LOAD_GLOBAL', 'LOAD_METHOD', 'LOAD_NAME', 'LOAD_SUPER_ATTR', 'LOAD_SUPER_METHOD', 'LOAD_ZERO_SUPER_ATTR', 'LOAD_ZERO_SUPER_METHOD', 'STORE_ATTR', 'STORE_GLOBAL', 'STORE_NAME']

Old is missing LOAD_ZERO_SUPER_ATTR and LOAD_ZERO_SUPER_METHOD.

Old:

>>> sorted([opcode.opname[op] for op in opcode.hasjrel])
['FOR_ITER', 'JUMP', 'JUMP_BACKWARD', 'JUMP_BACKWARD_NO_INTERRUPT', 'JUMP_FORWARD', 'JUMP_NO_INTERRUPT', 'POP_JUMP_IF_FALSE', 'POP_JUMP_IF_NONE', 'POP_JUMP_IF_NOT_NONE', 'POP_JUMP_IF_TRUE', 'SEND']

New:

>>> sorted([opcode.opname[op] for op in opcode.hasjrel])
['ENTER_EXECUTOR', 'FOR_ITER', 'JUMP', 'JUMP_BACKWARD', 'JUMP_BACKWARD_NO_INTERRUPT', 'JUMP_FORWARD', 'JUMP_NO_INTERRUPT', 'POP_JUMP_IF_FALSE', 'POP_JUMP_IF_NONE', 'POP_JUMP_IF_NOT_NONE', 'POP_JUMP_IF_TRUE', 'SEND']

New has ENTER_EXECUTOR as a jump.

For hasarg, the old list contained a few that the new list does not:

{'INSTRUMENTED_CALL_FUNCTION_EX', 'INSTRUMENTED_RETURN_VALUE', 'INSTRUMENTED_LINE', 'INSTRUMENTED_END_SEND', 'INSTRUMENTED_INSTRUCTION', 'INSTRUMENTED_END_FOR'}

olife-png reacted with thumbs up emoji olife-png reacted with hooray emoji
All reactions
  • 👍 1 reaction
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 14, 2023

Copy link
Copy Markdown
Member Author

It mostly looks right, except for INSTRUMENTED_CALL_FUNCTION_EX, which delegates the work to CALL_FUNCTION_EX which does have an arg.

olife-png reacted with thumbs up emoji olife-png reacted with hooray emoji
All reactions
  • 👍 1 reaction
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

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

@gvanrossum

gvanrossum commented Jul 14, 2023

Copy link
Copy Markdown
Member

Ugh. Worse, now LOAD_CLOSURE is gone, it’s ambiguous. Who uses this? How? (Only dis.py?)

LOAD_CLOSURE is just an alias (pseudo op) for LOAD_FAST. It's in the haslocal list in the old and new version, no change there.

My point is that LOAD_CLOSURE used to be separate because it was in the hasfree list. Now some LOAD_FAST instances refer to a local and others to a free variable. Example:

>>> def foo(a):
...   print(a)
...   def bar(): return a
... 
>>> dis.dis(foo)
              0 MAKE_CELL                0 (a)

  1           2 RESUME                   0

  2           4 LOAD_GLOBAL              1 (NULL + print)
             14 LOAD_DEREF               0 (a)
             16 CALL                     1
             24 POP_TOP

  3          26 LOAD_FAST                0 (a)
             28 BUILD_TUPLE              1
             30 LOAD_CONST               1 (<code object bar at 0x101d18400, file "<stdin>", line 3>)
             32 MAKE_FUNCTION
             34 SET_FUNCTION_ATTRIBUTE   8 (closure)
             36 STORE_FAST               1 (bar)
             38 RETURN_CONST             0 (None)

Disassembly of <code object bar at 0x101d18400, file "<stdin>", line 3>:
              0 COPY_FREE_VARS           1

  3           2 RESUME                   0
              4 LOAD_DEREF               0 (a)
              6 RETURN_VALUE
>>> 

The LOAD_FAST (a) at offset 26 used to be a LOAD_CLOSURE in 3.12 and before (and in 3.13 until LOAD_CLOSURE was made a pseudo-op). It's harmless, because we have co_varnames indexed by both locals and cells. So maybe hasfree is no longer useful?

I don't think

olife-png reacted with thumbs up emoji olife-png reacted with hooray emoji
All reactions
  • 👍 1 reaction
  • 🎉 1 reaction

Sorry, something went wrong.

Uh oh!

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

@gvanrossum

gvanrossum commented Jul 14, 2023

Copy link
Copy Markdown
Member

The "<148>" is because in opcode.py in main we have hasfree.append(148) even though there is no such opcode.

Looks like a relic. In 3.11, 148 was LOAD_CLASSDEREF. That opcode no longer exists in 3.12 (it was removed in gh-103764 for PEP 695). So let's get rid of it.

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 15, 2023

Copy link
Copy Markdown
Member Author

The LOAD_FAST (a) at offset 26 used to be a LOAD_CLOSURE in 3.12 and before (and in 3.13 until LOAD_CLOSURE was made a pseudo-op). It's harmless, because we have co_varnames indexed by both locals and cells. So maybe hasfree is no longer useful?

So we merge hasfree into haslocal and remove hasfree? Or leave it empty and soft deprecate it?

olife-png reacted with thumbs up emoji
All reactions
  • 👍 1 reaction

Sorry, something went wrong.

Uh oh!

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

iritkatriel added 2 commits July 15, 2023 17:14
@iritkatriel
add hasjump, soft deprecate hasjrel and hasjabs. Fix build bug
494680a
@iritkatriel
generate hasexc from the C macros instead of defining it again
24786fb
@iritkatriel iritkatriel changed the title gh-105481: add haslocal/hasfree to _opcode.py. Generate most oplists in opcode.py with the functions in _opcode.py gh-105481: add has_local/has_free/etc to _opcode.py. Generate oplists in opcode.py with the functions in _opcode.py Jul 15, 2023
@gvanrossum

gvanrossum commented Jul 15, 2023

Copy link
Copy Markdown
Member

So we merge hasfree into haslocal and remove hasfree? Or leave it empty and soft deprecate it?

Hm, I was just writing up a rationale for this when I realized that we should just keep hasfree and populate it correctly, and explain the special situation where LOAD_FAST can be used to load a cell (previously LOAD_CLOSURE) separately.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 15, 2023 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Member Author

Ok, then this PR is probably fine w.r.t. hasfree and haslocal.

The only list in oplists now is hascompare, which contains only COMPARE_OP:

>>> [opcode.opname[op] for op in opcode.hascompare]
['COMPARE_OP']

It is used by dis to identify that its op (>=, ==, etc) needs to be displayed.

All reactions

Sorry, something went wrong.

Uh oh!

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

gvanrossum
gvanrossum reviewed Jul 15, 2023
View reviewed changes
Comment thread Modules/_opcode.c Resolved

Uh oh!

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

@gvanrossum

gvanrossum commented Jul 15, 2023

Copy link
Copy Markdown
Member

It is used by dis to identify that its op (>=, ==, etc) needs to be displayed.

Since there's only one opcode like this, maybe dis can just check whether it's that opcode? Or do you anticipate that in the future there will be multiple ones? (Were there ever?)

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel
typo
563b431
@iritkatriel

iritkatriel commented Jul 15, 2023

Copy link
Copy Markdown
Member Author

It is used by dis to identify that its op (>=, ==, etc) needs to be displayed.

Since there's only one opcode like this, maybe dis can just check whether it's that opcode? Or do you anticipate that in the future there will be multiple ones? (Were there ever?)

It's just this one all the way back to 3.8.

dis can stop using the list, but it's documented in the dis module so can we remove it?

All reactions

Sorry, something went wrong.

Uh oh!

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

@gvanrossum

gvanrossum commented Jul 15, 2023

Copy link
Copy Markdown
Member

dis can stop using the list, but it's documented in the dis module so can we remove it?

I guess deprecate it like hasjabs/hasjrel.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel iritkatriel changed the title gh-105481: add has_local/has_free/etc to _opcode.py. Generate oplists in opcode.py with the functions in _opcode.py gh-105481: Generate the opcode lists in dis from data extracted from bytecodes.c Jul 17, 2023
iritkatriel
iritkatriel commented Jul 17, 2023
View reviewed changes
Comment thread Lib/opcode.py Resolved

Uh oh!

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

iritkatriel and others added 3 commits July 17, 2023 22:08
@iritkatriel
remove unnecessary comment
ce76a60
@iritkatriel
make the tests more precise
4194a12
@iritkatriel
sort the lists
6b8c46b
gvanrossum
gvanrossum reviewed Jul 17, 2023
View reviewed changes
Comment thread Lib/opcode.py Resolved

Uh oh!

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

Comment thread Lib/opcode.py Resolved

Uh oh!

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

Comment thread Lib/opcode.py Resolved

Uh oh!

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

Comment thread Lib/opcode.py Resolved

Uh oh!

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

Comment thread Lib/opcode.py
for op, i in opmap.items():
opname[i] = op

# The build uses older versions of Python which do not have _opcode.has_* functions

@gvanrossum gvanrossum Jul 17, 2023

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 quite mysterious. IIRC Brandt (?) wrote some hack that reads opcode.py and then execs it? But I can't find it.

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Jul 18, 2023

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.

Yes, in Tools/build/generate_opcode_h.py. But when it execs opcode.py that tries to import _opcode and call its has_arg etc to construct the oplists (which are not used during the build).

Ideally we should just get rid of generate_opcode_h.py if we can.

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Jul 18, 2023

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.

I think we don't need to import _opcode into opcode at all. We can just import it directly into dis (which is not used by any build scripts). I'll try that.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test__opcode.py Outdated
self.assertIsInstance(func(op), bool)
self.assertEqual(func(op), expected)

EXPECTED_OPLISTS = {

@gvanrossum gvanrossum Jul 17, 2023

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.

Does this mean that each time we add or remove an opcode we need to update this test? That feels tedious. (Even though it looks like it was always done like this and you're just refactoring that code a bit.)

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Jul 17, 2023

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.

In the past the list was built in opcode.py so we would need to make sure we added i there. Now the lists are derived automatically from bytecodes.c via heuristics, and you will need to update the test (which you are less likely to be able to do incorrectly). I'm not sure it's safe to not have these full tests.

Sorry, something went wrong.

Uh oh!

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

All reactions

@gvanrossum gvanrossum Jul 17, 2023

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.

Hm. So the point of the heuristics is that we don't have to manually maintain it, but the tests are manually maintained to check that the heuristics are still working. If they are, and if an instruction is added (or deleted) that changes one of these lists, we'll get a bogus test failure, and hopefully the contributor who gets to debug the test failure understands they have to fix the test. I think this warrants a comment right there where we expect the test to fail (I think on line 102, self.assertEqual(res, op in expected)).

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Jul 18, 2023 •
edited
Loading

Uh oh!

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

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.

The manually maintained lists were not tested and had some errors. We could remove the tests and trust people to examine the diff in the metadata file when they make changes. If we do that we should remove it from the autogenerated list so that it's not collapsed in a PR diff.

Sorry, something went wrong.

Uh oh!

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

All reactions
iritkatriel and others added 8 commits July 18, 2023 10:56
@iritkatriel
address some of the code review comments
e15f7d5
@iritkatriel
remove hard-coded lists from the tests
21fe0a4
@iritkatriel
remove opcode metadata file from generated files list so diff are vis…
75795db
…ible
@iritkatriel
import _opcode directly into dis, rather than via opcode
1a0a2b2
@iritkatriel
add stack effect to dis.__all__
f530469
@iritkatriel
Merge branch 'main' into opcode_py
71ffe34
@iritkatriel
import _specializations, _specialized_instructions directly from _opc…
d525c53
…ode_metadata rather than via opcode
@iritkatriel
update Tools/scripts/summarize_stats.py to use _opcode_metadata inste…
5e1c4a4
…ad of opcode for _specialized_instructions
gvanrossum
gvanrossum approved these changes Jul 18, 2023
View reviewed changes
@bedevere-bot bedevere-bot added awaiting merge and removed awaiting core review labels Jul 18, 2023
@iritkatriel

iritkatriel commented Jul 18, 2023

Copy link
Copy Markdown
Member Author

I think I need to add in whatsnew that the dis module's opcode lists are no longer also defined in the opcode module. The opcode module is not documented, but if you look on GitHub you can see some places where people import it.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Jul 18, 2023

Copy link
Copy Markdown
Member Author

I think I need to add in whatsnew that the dis module's opcode lists are no longer also defined in the opcode module. The opcode module is not documented, but if you look on GitHub you can see some places where people import it.

Or maybe this is a breaking change that I can't make without deprecation? I'm not sure what the status of the opcode module is.

I can put the lists back in opcode, and instead work to remove the dependency of the build on opcode.

All reactions

Sorry, something went wrong.

Uh oh!

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

@gvanrossum

gvanrossum commented Jul 18, 2023

Copy link
Copy Markdown
Member

I have a feeling that opcode is actually a better place than dis for the official public API. And that's probably why people have been importing it despite its undocumented status.

All reactions

Sorry, something went wrong.

Uh oh!

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

iritkatriel added 4 commits July 18, 2023 18:28
@iritkatriel
Revert "update Tools/scripts/summarize_stats.py to use _opcode_metada…
6077263
…ta instead of opcode for _specialized_instructions"

This reverts commit 5e1c4a4.
@iritkatriel
Revert "import _specializations, _specialized_instructions directly f…
98ba11f
…rom _opcode_metadata rather than via opcode"

This reverts commit d525c53.
@iritkatriel
Revert "add stack effect to dis.__all__"
cc8e5e1
This reverts commit f530469.
@iritkatriel
Revert "import _opcode directly into dis, rather than via opcode"
31dbfec
This reverts commit 1a0a2b2.
@iritkatriel

iritkatriel commented Jul 18, 2023

Copy link
Copy Markdown
Member Author

OK, I reverted the last few commits so we leave everything in opcode. We will rid the build of opcode in a future PR once the opcode.h file is generated from bytecodes.c.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel
Merge branch 'main' into opcode_py
1abf6ca
@iritkatriel
iritkatriel merged commit 40f3f11 into python:main Jul 18, 2023
@bedevere-bot bedevere-bot removed the awaiting merge label Jul 18, 2023
@iritkatriel
iritkatriel deleted the opcode_py branch July 25, 2023 18:02
@hugovk hugovk mentioned this pull request Sep 25, 2023
Improve import time of various stdlib modules #109653
Closed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@gvanrossum gvanrossum gvanrossum approved these changes
@markshannon markshannon Awaiting requested review from markshannon markshannon 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.

3 participants

@iritkatriel @gvanrossum @bedevere-bot
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.