Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[C API] Move the PyCodeObject structure to the internal C API (make the structure opaque) #91397

Closed
vstinner opened this issue Apr 6, 2022 · 5 comments
Labels
3.11 only security fixes topic-C-API

Comments

@vstinner
Copy link
Member

vstinner commented Apr 6, 2022

BPO 47241
Nosy @vstinner

Note: these values reflect the state of the issue at the time it was migrated and might not reflect the current state.

Show more details

GitHub fields:

assignee = None
closed_at = None
created_at = <Date 2022-04-06.13:56:37.081>
labels = ['expert-C-API', '3.11']
title = '[C API] Move the PyCodeObject structure to the internal C API (make the structure opaque)'
updated_at = <Date 2022-04-06.13:56:37.081>
user = 'https://github.com/vstinner'

bugs.python.org fields:

activity = <Date 2022-04-06.13:56:37.081>
actor = 'vstinner'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['C API']
creation = <Date 2022-04-06.13:56:37.081>
creator = 'vstinner'
dependencies = []
files = []
hgrepos = []
issue_num = 47241
keywords = []
message_count = 1.0
messages = ['416869']
nosy_count = 1.0
nosy_names = ['vstinner']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = None
url = 'https://bugs.python.org/issue47241'
versions = ['Python 3.11']

@vstinner
Copy link
Member Author

vstinner commented Apr 6, 2022

The PyCodeObject structure is documented at:
https://docs.python.org/dev/c-api/code.html

The structured evolved a lot in Python 3.11 to optimize Python/ceval.c performance:

  • read-only co_code (object) was replaced with modifiable co_code_adaptive (char[])
  • co_varnames, co_freevars and co_cellvars were removed: merged into co_localsplusnames with co_localspluskinds
  • co_cell2arg was removed
  • co_zombieframe ("free list") was removed
  • co_opcache, co_opcache_map, co_opcache_flag and co_opcache_size were removed: see PEP-659
    https://peps.python.org/pep-0659/

New members:

  • co_exceptiontable
  • co_warmup, co_code_adaptive
  • co_nlocalsplus, co_nplaincellvars, co_ncellvars, co_nfreevars
  • co_localsplusnames, co_localspluskinds
  • co_qualname
  • co_endlinetable, co_columntable

The PyCodeObject structure should be made opaque in the public C API and only accessed with function calls.

In Python 3.11, the PyFrameObject structure was made opaque (bpo-46836) and multiple getters were added (bpo-40421). The idea is similar, but it might be too late to do that in Python 3.11 (beta1 feature freeze is close).

---

By the way, it was proposed multiple times on python-dev to mark the PyCode_New() function as "unstable" since its API changed often. PEP-670 "Python Positional-Only Parameters" caused a lot of troubles in Cython when it added a new parameter to PyCode_New(). The change was reverted: instead, a new PyCode_NewWithPosOnlyArgs() function was added.

  • PyCode_New() has 19 parameters!
  • PyCode_NewWithPosOnlyArgs() has 20 parameters!!

On Python 3.11a1 and newer, Cython uses the code.replace() method (added to Python 3.8) to build new code objects. Otherwise, it just calls directly PyCode_New().
https://docs.python.org/dev/library/types.html#types.CodeType.replace

@vstinner vstinner added 3.11 only security fixes topic-C-API labels Apr 6, 2022
@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
@vstinner
Copy link
Member Author

vstinner commented May 2, 2022

@vstinner
Copy link
Member Author

vstinner commented May 2, 2022

On nedbat/coveragepy#1353 (comment), @Fidget-Spinner wrote:

Also, co_code has been gone since 2bde682. Which is 3.11a7 and up only. For that you'd need the internal _PyCode_GetCode (Huh, I just realised we should probably expose that in CPython's API).

It would be nice to add a public C API getter function, something like PyCode_GetCode() which would return a strong reference to a bytes object.

@vstinner
Copy link
Member Author

vstinner commented May 2, 2022

It would be nice to add a public C API getter function, something like PyCode_GetCode() which would return a strong reference to a bytes object.

Ah, @Fidget-Spinner opened #92154 for that!

@vstinner
Copy link
Member Author

vstinner commented Jun 7, 2022

Cython issue related to PyCodeObject structure size in Python 3.11: cython/cython#4827

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.11 only security fixes topic-C-API
Projects
None yet
Development

No branches or pull requests

1 participant