Skip to content

Resolve obscure super errors#1535

Merged
BCSharp merged 6 commits intoIronLanguages:masterfrom
BCSharp:super_runtime
Aug 29, 2022
Merged

Resolve obscure super errors#1535
BCSharp merged 6 commits intoIronLanguages:masterfrom
BCSharp:super_runtime

Conversation

@BCSharp
Copy link
Copy Markdown
Member

@BCSharp BCSharp commented Aug 18, 2022

It started when I looked into why super() generates NameError/UnboundLocalError while in CPython it is RuntimeError (tested for by StdLib). It turns out that the CPython's implementation hence behaviour is different in some corner cases. Specifically, 0-argument super() does not have default arguments __class__ and self injected during compilation, but resolved during runtime. One of the consequences is that __class__ is always resolved to a class cell rather than whatever the namebinder finds in the local scope.

As far as I can see, these are truly obscure cases that would lead to IronPython/CPython differences and almost always bad Python programming, but it was an interesting exercise and you never know what other consequences might be there.

For what I know, most IronPython/CPython differences are resolved now, the only few remaining are in some pathological and totally useless constructs, in which the error message (but not type) might be different. See the new tests for specifics.

Copy link
Copy Markdown
Contributor

@slozier slozier left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the PR! I'm sure I've come across the super alias issue before but I can't find any issue about it... Looks good to me. My understanding of this part of the code base is somewhat limited so I will defer to you - feel free to merge when you're happy with it.

In case you're interested in another obscure error:

class C:
    def f2(self):
        s_p_r = super
        return s_p_r()

C().f2()

Comment thread Src/IronPython/Compiler/Ast/ScopeStatement.cs Outdated
Comment thread Tests/test_super.py Outdated
Comment thread Tests/test_super.py Outdated
Comment thread Tests/test_super.py Outdated
@BCSharp
Copy link
Copy Markdown
Member Author

BCSharp commented Aug 19, 2022

In case you're interested in another obscure error:

class C:
    def f2(self):
        s_p_r = super
        return s_p_r()

C().f2()

Thanks, it is a good one. I think I will adjust the part that triggers the class cell generation, but not the part that lifts arg[0] to a cell. Class cell generation is fairly innocuous, being executed only once per class, so very low performance impact, but lifting self to a cell in every case super is referred to means that the price is being paid for every call of such method and every statement in that method using self. It feels like a bad deal, just to support another obscure scenario. Note that all parameters get lifted unconditionally if FullFrames are used, so there will be a workaround.

It a way it then becomes another case like #562. So this will be fully solved if #562 gets solved.

@BCSharp BCSharp marked this pull request as ready for review August 28, 2022 21:32
@BCSharp BCSharp merged commit 894df46 into IronLanguages:master Aug 29, 2022
@BCSharp BCSharp deleted the super_runtime branch August 29, 2022 01:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants