-
Notifications
You must be signed in to change notification settings - Fork 60
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
issue with list comprehension in python 3.12 #93
Comments
What I can say off the top of my head is that One thing is that the AST representation tends to change in almost every Python minor version, which is often enough to make it frustrating to keep your side projects updated. For a concrete example, The other thing is, scope analysis in Python has always been a headache (see e.g. the "Full Monty" paper by Politz et al., 2013; or if you prefer code, unpythonic's scope analyzer, which is much newer than what we have in Other things may also have broken. Yet others were either never properly implemented in It pains me to say, but I haven't needed Although I write my own research codes in Python, in practice that means that 90% of the time, I'm writing new code to solve some new problem. As we all know, this is wildly different from most kinds of software engineering. The other 10% of the time, I'm looking at either my own old code, or at something modular enough where a local manual analysis is enough. Numerics tends to have very simple linear control flow, with highly nontrivial algorithms, which again is the polar opposite of most other kinds of software engineering. Of my metaprogramming projects, I'm semi-actively using some parts of unpythonic, and I have a minor interest in keeping the mcpyrate macro expander alive (as it goes much further than earlier designs, and no one else seems to have run off with the mantle). But that's basically all I can afford. Even for those, the most recent opportunity I had to work on them was almost two years ago. So even those projects are stuck on Python 3.10 at the moment. Since there is a continuing community interest in P.S. To any interested developer reading this: My current opinion is that the design of If I was writing the tool now, I'd only do what can be done purely statically (simple is better than complex). This would remove some features, but it would also make it much easier to communicate which kinds of things the tool understands. Basically, if you have to run the code in your head, that's dynamic analysis, and a static analyzer shouldn't even attempt to do that. A static analyzer should only look at the definitions, and at their placement in the source code. Contrast also the concepts of scope and dynamic extent. Also specifically, the last seen value mechanism is a Hail Mary that goes against the very philosophy of Python, and should be removed at the first possible opportunity. Analyze the structure explicitly, or skip it. Refuse the temptation to guess. |
Thanks for your long response @Technologicat . Unfortunately I do not qualify as metaprogramer and I do not have enough free time to take over. I am stilling some time from my boss to make this issue progress:
python 3.12 :
python 3.10:
The issue is comming from a change in behavior in symtable called here : Line 1264 in 350ea49
|
Thanks for the analysis! That does sound like some internals of list comprehensions have changed in 3.12. I suppose it's time to check the release notes. Indeed: ---8<---8<---8<--- PEP 709: Comprehension inlining Dictionary, list, and set comprehensions are now inlined, rather than creating a new single-use function object for each execution of the comprehension. This speeds up execution of a comprehension by up to two times. See PEP 709 for further details. Comprehension iteration variables remain isolated and don’t overwrite a variable of the same name in the outer scope, nor are they visible after the comprehension. Inlining does result in a few visible behavior changes: There is no longer a separate frame for the comprehension in tracebacks, and tracing/profiling no longer shows the comprehension as a function call. The symtable module will no longer produce child symbol tables for each comprehension; instead, the comprehension’s locals will be included in the parent function’s symbol table.
(Contributed by Carl Meyer and Vladimir Matveev in PEP 709.) ---8<---8<---8<--- My personal opinion is, that's a hack that breaks the language's scoping contract. The performance increase comes at the cost of not having an explicit scope reported for variables that anyway behave as if they had such a scope. This just made the Python scoping rules an even bigger headache than they used to be. If you want to have a try at fixing the analyzer, some ideas:
|
Ah, one more thing: if you want to try the latter option, I can help with capturing the comprehension variable names from the relevant AST node. That's something that requires knowledge of the Python AST format, but needs only a few lines of code. It shouldn't take much longer to implement that particular thing than it takes to write these comments here. :) (Worst case is, we'll need an AST walker that runs over the whole source file, keeping track of scopes. But we already have that in |
Hi @Technologicat, I've just run into this issue, and in my case it was solved by just no doing the comprehension logic at all, in my use case i'm subclassing the Analyzer class so, this did the trick for me: def analyze_comprehension(self, *args, **kwargs):
pass i'm using it in |
PEP-0709 has remove comprehension scopes and we should ignore them as well Ref: https://peps.python.org/pep-0709/ Ref: Technologicat/pyan#93
PEP-0709 has remove comprehension scopes and we should ignore them as well Ref: https://peps.python.org/pep-0709/ Ref: Technologicat/pyan#93
Hello,
I am running pyan3 (1.2.0) through sphinx 7.2.6.
Nice graph are generated when usint python 3.10 but the scripts fails when using python 3.12.
list comprehension is indeed located in
Model_buildup.Chain_Unchain
module:Any clue on why the same pyan version with the same sphinx version runs differently on list comprehension between python 3.10 and 3.12 ??
The text was updated successfully, but these errors were encountered: