("Re: C API: Move PEP 523 "Adding a frame evaluation API to CPython"
private C API to the internal C API")
On Fri, Apr 1, 2022 at 11:01 AM Chris Angelico <rosuav@gmail.com> wrote:
>
> On Fri, 1 Apr 2022 at 19:51, Victor Stinner <vstinner@python.org> wrote:
> > In Python, sadly the types.CodeType type also has a public constructor
> > and many projects break at each Python release because the API
> > changes. Hopefully, it seems like the new CodeType.replace() method
> > added to Python 3.8 mitigated the issue. IMO CodeType.replace() is a
> > better abstraction and closer to what developers need in practice.
>
> It certainly has been for me. When I want to do bytecode hackery, I
> usually start by creating a function with def/lambda, then construct a
> modified function using f.__code__.replace(). It's the easiest way to
> ensure that all the little details are correct.
Python 3.11 added the concept of "exception table"
(code.co_exceptiontable). You have to build this table, otherwise
Python can no longer catch exceptions :-)
I don't know how to build this exception table. It seems like
currently there is no Python function in the stdlib to build this
table.
Example:
---
def f():
try:
print("raise")
raise ValueError
except ValueError:
print("except")
else:
print("else")
print("exit func")
def g(): pass
if 1:
code = f.__code__
g.__code__ = g.__code__.replace(
co_code=code.co_code,
co_consts=code.co_consts,
co_names=code.co_names,
co_flags=code.co_flags,
co_stacksize=code.co_stacksize)
else:
g.__code__ = f.__code__ # this code path works on Python 3.11
g()
---
Output with Python 3.10 (ok):
---
raise
except
exit func
---
Output with Python 3.11 (oops):
---
raise
Traceback (most recent call last):
...
ValueError
---
By the way, this change is not documented at all:
* https://docs.python.org/dev/library/types.html#types.CodeType
* https://docs.python.org/dev/whatsnew/3.11.html
I understand that these changes come from the "Zero cost exception
handling" change:
https://bugs.python.org/issue40222
Victor
--
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/KWSPCLXDHBAP2U4LBSMLQEOC7LREDMPB/
Code of Conduct: http://python.org/psf/codeofconduct/
private C API to the internal C API")
On Fri, Apr 1, 2022 at 11:01 AM Chris Angelico <rosuav@gmail.com> wrote:
>
> On Fri, 1 Apr 2022 at 19:51, Victor Stinner <vstinner@python.org> wrote:
> > In Python, sadly the types.CodeType type also has a public constructor
> > and many projects break at each Python release because the API
> > changes. Hopefully, it seems like the new CodeType.replace() method
> > added to Python 3.8 mitigated the issue. IMO CodeType.replace() is a
> > better abstraction and closer to what developers need in practice.
>
> It certainly has been for me. When I want to do bytecode hackery, I
> usually start by creating a function with def/lambda, then construct a
> modified function using f.__code__.replace(). It's the easiest way to
> ensure that all the little details are correct.
Python 3.11 added the concept of "exception table"
(code.co_exceptiontable). You have to build this table, otherwise
Python can no longer catch exceptions :-)
I don't know how to build this exception table. It seems like
currently there is no Python function in the stdlib to build this
table.
Example:
---
def f():
try:
print("raise")
raise ValueError
except ValueError:
print("except")
else:
print("else")
print("exit func")
def g(): pass
if 1:
code = f.__code__
g.__code__ = g.__code__.replace(
co_code=code.co_code,
co_consts=code.co_consts,
co_names=code.co_names,
co_flags=code.co_flags,
co_stacksize=code.co_stacksize)
else:
g.__code__ = f.__code__ # this code path works on Python 3.11
g()
---
Output with Python 3.10 (ok):
---
raise
except
exit func
---
Output with Python 3.11 (oops):
---
raise
Traceback (most recent call last):
...
ValueError
---
By the way, this change is not documented at all:
* https://docs.python.org/dev/library/types.html#types.CodeType
* https://docs.python.org/dev/whatsnew/3.11.html
I understand that these changes come from the "Zero cost exception
handling" change:
https://bugs.python.org/issue40222
Victor
--
Night gathers, and now my watch begins. It shall not end until my death.
_______________________________________________
Python-Dev mailing list -- python-dev@python.org
To unsubscribe send an email to python-dev-leave@python.org
https://mail.python.org/mailman3/lists/python-dev.python.org/
Message archived at https://mail.python.org/archives/list/python-dev@python.org/message/KWSPCLXDHBAP2U4LBSMLQEOC7LREDMPB/
Code of Conduct: http://python.org/psf/codeofconduct/