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-126072: Set docstring attribute for module and class by xuantengh · Pull Request #126231 · python/cpython

Conversation

@xuantengh

@xuantengh xuantengh commented Oct 31, 2024 •
edited by bedevere-app Bot
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor

This is the ongoging work of #126101, where we introduced a new attribute ste_has_docstring in the symbol table entry. This PR aims to set this attribute for modules and classes whenever there are docstrings for them. Meanwhile, it also prevents None being added to co_consts for lambda, annotation and type alias.

  • Issue: The method for storing docstrings in code objects is awkward and prevents optimizations. #126072

Sorry, something went wrong.

Uh oh!

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

All reactions
@xuantengh
xuantengh requested review from JelleZijlstra, carljm, iritkatriel and markshannon as code owners October 31, 2024 07:59
@bedevere-app bedevere-app Bot added the awaiting review label Oct 31, 2024
@bedevere-app bedevere-app Bot mentioned this pull request Oct 31, 2024
The method for storing docstrings in code objects is awkward and prevents optimizations. #126072
Closed
@xuantengh
xuantengh force-pushed the main branch from c563df0 to e4953d9 Compare October 31, 2024 08:35
iritkatriel
iritkatriel reviewed Oct 31, 2024
View reviewed changes
Comment thread Python/symtable.c Resolved

Uh oh!

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

@xuantengh
xuantengh force-pushed the main branch from 1b8ab5a to 0f68ad8 Compare October 31, 2024 13:54
JelleZijlstra
JelleZijlstra reviewed Oct 31, 2024
View reviewed changes
Comment thread Python/symtable.c Resolved

Uh oh!

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

JelleZijlstra
JelleZijlstra reviewed Oct 31, 2024
View reviewed changes
Comment thread Misc/NEWS.d/next/Core_and_Builtins/2024-10-31-21-49-00.gh-issue-126072.o9k8Ns.rst Resolved

Uh oh!

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

@xuantengh
xuantengh force-pushed the main branch 2 times, most recently from 1dc125e to 8622d78 Compare November 2, 2024 13:16
@xuantengh

xuantengh commented Nov 3, 2024

Copy link
Copy Markdown
Contributor Author

Just kindly to ask any further updates needed? I'm not sure whether it's proper to re-request review in CPython PR workflow.

All reactions

Sorry, something went wrong.

Uh oh!

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

@xuantengh
xuantengh force-pushed the main branch from 8622d78 to 1ee5d04 Compare November 3, 2024 05:20
iritkatriel
iritkatriel reviewed Nov 3, 2024
View reviewed changes

@iritkatriel iritkatriel 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.

Excuse formatting, reviewing on my phone.

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Lib/test/test_compile.py Resolved

Uh oh!

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

Comment thread Python/codegen.c Outdated
PyObject *docstring = _PyAST_GetDocString(body);
assert(OPTIMIZATION_LEVEL(c) < 2 || docstring == NULL);
if (docstring) {
assert(ste->ste_has_docstring);

@iritkatriel iritkatriel Nov 3, 2024

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 it still true that GetDocstring returns non-null only when ste_has_docstring is true?

Perhaps it should be
if(ste_has_docstring) assert(GetDocstring)?

Sorry, something went wrong.

Uh oh!

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

All reactions

@xuantengh xuantengh Nov 3, 2024

Copy link
Copy Markdown
Contributor 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.

Currently I think they are equivalent, i.e., ste_has_docstring == 1 iff. there is a docstring during symbol table generation.

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Nov 3, 2024

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.

And when you run python -OO?

Sorry, something went wrong.

Uh oh!

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

All reactions

@xuantengh xuantengh Nov 4, 2024 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor 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.

Currently when running with -OO, the first docstring is removed and the subsequent docstring is converted into JoinedStr in the AST stage. For _PyAST_GetDocString, it will not identify the converted JoinedStr as docstring, so ste_has_docstring will not be set.

Sorry, something went wrong.

Uh oh!

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

All reactions

@xuantengh xuantengh Nov 4, 2024

Copy link
Copy Markdown
Contributor 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.

Add a test for docstring optimization under -OO.

Sorry, something went wrong.

Uh oh!

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

All reactions

@iritkatriel iritkatriel Nov 4, 2024

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.

Currently when running with -OO, the first docstring is removed and the subsequent docstring is converted into JoinedStr in the AST stage. For _PyAST_GetDocString, it will not identify the converted JoinedStr as docstring, so ste_has_docstring will not be set.

Right, but we want to remove that hack.

Sorry, something went wrong.

Uh oh!

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

All reactions

@xuantengh xuantengh Nov 4, 2024

Copy link
Copy Markdown
Contributor 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.

Should we do it in this PR?

Sorry, something went wrong.

Uh oh!

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

All reactions
Comment thread Python/symtable.c Resolved

Uh oh!

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

@xuantengh
xuantengh force-pushed the main branch 4 times, most recently from d9c97a6 to 7db42a1 Compare November 4, 2024 11:56
@xuantengh

xuantengh commented Nov 4, 2024

Copy link
Copy Markdown
Contributor Author

@iritkatriel Hi, I've encountered an issue when trying to remove f-string conversion in astfold_body. For the following function when opt=0 or 1:

def func():
    "not " + "a docstring"

astfold_body prevents the concatenated string (optimized as const expression statement somewhere during AST optimization I guess) being parsed as docstring by converting it into f-string. But if we remove the logic, the symbol table generation cannot distinguish "not a docstring" is originally a real docstring, or optimized concatenated string.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Nov 5, 2024

Copy link
Copy Markdown
Member

@iritkatriel Hi, I've encountered an issue when trying to remove f-string conversion in astfold_body. For the following function when opt=0 or 1:

def func():
    "not " + "a docstring"

astfold_body prevents the concatenated string (optimized as const expression statement somewhere during AST optimization I guess) being parsed as docstring by converting it into f-string. But if we remove the logic, the symbol table generation cannot distinguish "not a docstring" is originally a real docstring, or optimized concatenated string.

I thought the idea is that it uses ste_has_docstring to determine whether there is a docstring or not, rather than the type of the first expression.

JelleZijlstra 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.

@xuantengh

xuantengh commented Nov 6, 2024

Copy link
Copy Markdown
Contributor Author

I thought the idea is that it uses ste_has_docstring to determine whether there is a docstring or not, rather than the type of the first expression.

Sorry I'm a little confused now. 😂

If we remove the f-string conversion in the astfold_body function, the _PyAST_GetDocString returns true and set ste_has_docstring incorrectly in symbol table generation stage.

cpython/Python/symtable.c

Lines 1846 to 1848 in 83ba8c2

if (_PyAST_GetDocString(s->v.FunctionDef.body)) {
new_ste->ste_has_docstring = 1;
}

The reason is _PyAST_GetDocString checks whether there is a docstring by inspecting the first expression type. If it's a Constant_kind, then it returns true. If we remove the f-string conversion in AST optimization stage, it cannot distinguish the constant expression is actually a docstring or concatenated string expression. In either cases, it returns true and ste_has_docstring will be set.

If there is something I misunderstood, please correct me, thanks!

All reactions

Sorry, something went wrong.

Uh oh!

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

@JelleZijlstra

JelleZijlstra commented Nov 6, 2024

Copy link
Copy Markdown
Member

I guess the problem is that we perform AST optimization before we build the symtable, so we have to keep doing the f-string conversion to avoid breaking the symtable. Maybe we can instead run the symtable before ast optimization, so we can get rid of the f-string trick in the AST optimizer.

All reactions

Sorry, something went wrong.

Uh oh!

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

@xuantengh

xuantengh commented Nov 6, 2024 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor Author

I guess the problem is that we perform AST optimization before we build the symtable

Yeah that's the problem. That's say, we cannot convey the information from AST construction to symtable generation phase.

Maybe we can instead run the symtable before ast optimization, so we can get rid of the f-string trick in the AST optimizer.

Theoratically it's feasible, but I'm afraid that there are side-effects and the scope is beyond this PR.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Nov 6, 2024

Copy link
Copy Markdown
Member

My proposal (in #126072 (comment)) was to move the docstring removal to the symtable, so it's all in one place.

All reactions

Sorry, something went wrong.

Uh oh!

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

@xuantengh

xuantengh commented Nov 6, 2024 •
edited
Loading

Uh oh!

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

Copy link
Copy Markdown
Contributor Author

My proposal (in #126072 (comment)) was to move the docstring removal to the symtable, so it's all in one place.

But I think the problem is still not addressed, we've lost some information after the AST optimization (the concatenated string has been optimized as constant string). Even though the docstring removal is put together with symtable, it still fails to distinguish in the above case.

All reactions

Sorry, something went wrong.

Uh oh!

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

@xuantengh
xuantengh force-pushed the main branch 2 times, most recently from 75bfe7b to 0f06e57 Compare November 7, 2024 05:30
@xuantengh
xuantengh requested a review from isidentical as a code owner November 7, 2024 05:30
xuantengh added 5 commits November 8, 2024 13:46
@xuantengh
add ste fetch and news
a67a4ea
@xuantengh
simplify code
8942676
@xuantengh
add docstring test under -OO
fe1db96
@xuantengh
simplify astfold_body
82a32c8
@xuantengh
use optimize when generate symtable
1b1fcae
@xuantengh
xuantengh force-pushed the main branch 2 times, most recently from 2194f4f to 390caaa Compare November 8, 2024 06:40
@xuantengh
add const string multiply test
88f6acf
@xuantengh
xuantengh force-pushed the main branch from 390caaa to 88f6acf Compare November 8, 2024 07:36
@xuantengh

xuantengh commented Nov 8, 2024

Copy link
Copy Markdown
Contributor Author

Revert to the version without swapping AST optimization and symtable generation. The docstring removal in astfold_body can be omitted in cunrrent implementation, but the f-string conversion should be retained. IMHO, removing the f-string conversion will introduce a lot of compromise changes, which even makes the code more complicated.

All reactions

Sorry, something went wrong.

Uh oh!

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

xuantengh added 2 commits November 8, 2024 15:42
@xuantengh
hide private function
119db3b
@xuantengh
update docs
24e2c8f
@iritkatriel

iritkatriel commented Nov 8, 2024

Copy link
Copy Markdown
Member

Specifically, can we disable the constant string concatenation optimization in AST when opt=1?

No, this would mean we optimise less when we should be optimising more.

I think we should leave symtable after ast_opt and try my suggestion to just move the docstring handling from ast_opt to symtable.

All reactions

Sorry, something went wrong.

Uh oh!

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

@xuantengh

xuantengh commented Nov 8, 2024

Copy link
Copy Markdown
Contributor Author

I think we should leave symtable after ast_opt and try my suggestion to just move the docstring handling from ast_opt to symtable.

As mentioned above, what blocks us doing so is if we leave the docstring handling to symtable, for the following code:

def with_const_expression():
    "aa" * 4

The optimized AST will be:

Module(
  body=[
    FunctionDef(
      name='with_const_expression',
      args=arguments(),
      body=[
        Expr(
          value=Constant(value='aaaaaaaa'))])])

Then in the symtable stage, it cannot distinguish whether the constant string 'aaaaaaaa' is really a docstring, or the optimized concatenated string. So the compiler will incorrectly set ste_has_docstring.

All reactions

Sorry, something went wrong.

Uh oh!

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

@iritkatriel

iritkatriel commented Nov 8, 2024

Copy link
Copy Markdown
Member

Ok, I see. I think we should just forget about that for this PR. Can you revert all the changes related to removing the hack, and make this PR just about about module and class change?

xuantengh 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.

@xuantengh
revert ast_opt hacking commits
b81f4a4
iritkatriel
iritkatriel reviewed Nov 8, 2024
View reviewed changes
Comment thread Python/codegen.c Resolved

Uh oh!

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

@xuantengh
uniformly use ste_has_docstring to judge whether there is docstring
d08920a
iritkatriel
iritkatriel reviewed Nov 8, 2024
View reviewed changes
Comment thread Python/codegen.c Resolved

Uh oh!

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

@xuantengh
add docstring assert
3c072f3
iritkatriel
iritkatriel approved these changes Nov 8, 2024
View reviewed changes
@bedevere-app bedevere-app Bot added awaiting merge and removed awaiting review labels Nov 8, 2024
@iritkatriel
Merge branch 'main' into main
263a2d7
@iritkatriel
iritkatriel enabled auto-merge (squash) November 8, 2024 14:17
@xuantengh
retrigger checks
442d7a2
@iritkatriel
iritkatriel merged commit 6ec8865 into python:main Nov 8, 2024
@bedevere-app bedevere-app Bot removed the awaiting merge label Nov 8, 2024
picnixz pushed a commit to picnixz/cpython that referenced this pull request Dec 8, 2024
@xuantengh @picnixz
pythongh-126072: Set docstring attribute for module and class (python…
90cb6e9
…#126231)
ebonnal pushed a commit to ebonnal/cpython that referenced this pull request Jan 12, 2025
@xuantengh @ebonnal
pythongh-126072: Set docstring attribute for module and class (python…
ea1e8b6
…#126231)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@JelleZijlstra JelleZijlstra JelleZijlstra left review comments
@iritkatriel iritkatriel iritkatriel approved these changes
@carljm carljm Awaiting requested review from carljm carljm is a code owner
@markshannon markshannon Awaiting requested review from markshannon markshannon is a code owner
@isidentical isidentical Awaiting requested review from isidentical
@Eclips4 Eclips4 Awaiting requested review from Eclips4

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

@xuantengh @iritkatriel @JelleZijlstra
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.