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

Assigning function parameter to class attribute by the same name #87546

Open
jennydaman mannequin opened this issue Mar 3, 2021 · 6 comments
Open

Assigning function parameter to class attribute by the same name #87546

jennydaman mannequin opened this issue Mar 3, 2021 · 6 comments
Labels
3.9 only security fixes 3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error

Comments

@jennydaman
Copy link
Mannequin

jennydaman mannequin commented Mar 3, 2021

BPO 43380
Nosy @ericvsmith, @stevendaprano, @jennydaman

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 2021-03-03.00:36:29.041>
labels = ['interpreter-core', 'type-bug', '3.9', '3.10']
title = 'Assigning function parameter to class attribute by the same name'
updated_at = <Date 2021-03-03.09:19:41.364>
user = 'https://github.com/jennydaman'

bugs.python.org fields:

activity = <Date 2021-03-03.09:19:41.364>
actor = 'steven.daprano'
assignee = 'none'
closed = False
closed_date = None
closer = None
components = ['Interpreter Core']
creation = <Date 2021-03-03.00:36:29.041>
creator = 'jennydaman'
dependencies = []
files = []
hgrepos = []
issue_num = 43380
keywords = []
message_count = 6.0
messages = ['387987', '387990', '387991', '387992', '388005', '388008']
nosy_count = 3.0
nosy_names = ['eric.smith', 'steven.daprano', 'jennydaman']
pr_nums = []
priority = 'normal'
resolution = None
stage = None
status = 'open'
superseder = None
type = 'behavior'
url = 'https://bugs.python.org/issue43380'
versions = ['Python 3.9', 'Python 3.10']

@jennydaman
Copy link
Mannequin Author

jennydaman mannequin commented Mar 3, 2021

# Example

Consider these three examples, which are theoretically identical

a = 4

class A:
    a = a

print(A.a)

def createB(b):
    class B:
        z = b
    print(B.z)
    
createB(5)

def createD(D):
    class D:
        d = d
    print(D.d)
    
createD(6)

## Expected Output

4
5
6

## Actual Output

4
5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in createD
  File "<stdin>", line 3, in D
NameError: name 'd' is not defined

@jennydaman jennydaman mannequin added 3.9 only security fixes 3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error labels Mar 3, 2021
@ericvsmith
Copy link
Member

Was
def createD(D):

supposed to be:
def createD(d):

?

Not that that changes your problem. I just want to understand the exact issue.

@jennydaman
Copy link
Mannequin Author

jennydaman mannequin commented Mar 3, 2021

# Example

Consider these three examples, which are theoretically identical

a = 4

class A:
    a = a

print(A.a)

def createB(b):
    class B:
        z = b
    print(B.z)
    
createB(5)

def createD(d):
    class D:
        d = d
    print(D.d)
    
createD(6)

## Expected Output

4
5
6

## Actual Output

4
5
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 2, in createD
  File "<stdin>", line 3, in D
NameError: name 'd' is not defined

@jennydaman
Copy link
Mannequin Author

jennydaman mannequin commented Mar 3, 2021

Yes sorry that was a typo

@stevendaprano
Copy link
Member

Here's an example that shows what is going on:

def demo():
    a = 1
    class B:
        x = a
    print(B.x)  # Okay.
    
    class C:
        x = a  # Fails.
        if False:
            a = None
    print(C.x)

If you run that, B.x is printed (1) but assigning to C.x fails:

>>> demo()
1
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 7, in demo
  File "<stdin>", line 8, in C
NameError: name 'a' is not defined

The reason is that inside a function, assignment to a name makes it a local. This interacts oddly with class scope.

By the way, I get the same results with this all the way back to Python 2.4. (I don't have older versions to test.) So this has existed for a very long time.

@stevendaprano
Copy link
Member

Looking at the disassembly of the demo() function also shows differences between the B and C classes.

I seem to recall discussion about this on, maybe, the Python-Dev list. I think resolving this will probably have to wait on a re-design of the exact scoping rules with respect to classes inside functions.

@ezio-melotti ezio-melotti transferred this issue from another repository Apr 10, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
3.9 only security fixes 3.10 only security fixes interpreter-core (Objects, Python, Grammar, and Parser dirs) type-bug An unexpected behavior, bug, or error
Projects
None yet
Development

No branches or pull requests

2 participants