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

del and name binding #125677

Closed
paulehoffman opened this issue Oct 18, 2024 · 6 comments
Closed

del and name binding #125677

paulehoffman opened this issue Oct 18, 2024 · 6 comments
Labels
docs Documentation in the Doc dir

Comments

@paulehoffman
Copy link
Contributor

Documentation

Section 4.2.1 in Execution model says "A target occurring in a del statement is also considered bound for this purpose (though the actual semantics are to unbind the name)." The "for this purpose" makes no sense because the target of a del statement must already be bound to something; otherwise you get a NameError.

I propose that this paragraph either be removed or worded better to say why the target that is already bound is rebound (if that's what it is trying to say).

@paulehoffman paulehoffman added the docs Documentation in the Doc dir label Oct 18, 2024
@JelleZijlstra
Copy link
Member

Link: https://docs.python.org/3/reference/executionmodel.html#binding-of-names

The point made by this paragraph is relevant because del ing a name in a scope makes it so the name is considered to exist in that scope, which might affect e.g. the lookup of variables in nested scopes.

@paulehoffman
Copy link
Contributor Author

I am not sure what you comment means (but I am also not sure what the current doc means either...). deling a name causes the name not to exist, at least in the global scope.

>>> a = 1
>>> dir()
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'a']
>>> del a
>>> dir()
['__annotations__', '__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__']

@JelleZijlstra
Copy link
Member

If there is an occurrence of del a in a scope, that causes a to be considered a local in that scope.

In other words, these two programs behave differently:

a = "global"

def outer():
    def inner():
        print(a)
    
    if False:
        del a
    inner()

outer()
a = "global"

def outer():
    def inner():
        print(a)
    
    inner()

outer()

@paulehoffman
Copy link
Contributor Author

OK, I can see this now. It is confusing because it is about a name already being bound, but the discussion is about how names become bound.

Is del special? That is, is "A target occurring in a FOO statement is also considered bound for this purpose" true for any other statements?

@JelleZijlstra
Copy link
Member

del is different because it counts as an assignment. If my code sample instead had just if False: a, it wouldn't have the same effect.

@paulehoffman
Copy link
Contributor Author

Thanks, the explanation makes sense. I don't see a better way to word the current text to capture this, so I'll close this issue.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
docs Documentation in the Doc dir
Projects
None yet
Development

No branches or pull requests

2 participants