mirror of https://github.com/astral-sh/ruff
122 lines
2.3 KiB
Markdown
122 lines
2.3 KiB
Markdown
# `del` statement
|
|
|
|
## Basic
|
|
|
|
```py
|
|
a = 1
|
|
del a
|
|
# error: [unresolved-reference]
|
|
reveal_type(a) # revealed: Unknown
|
|
|
|
# error: [invalid-syntax] "Invalid delete target"
|
|
del 1
|
|
|
|
# error: [unresolved-reference]
|
|
del a
|
|
|
|
x, y = 1, 2
|
|
del x, y
|
|
# error: [unresolved-reference]
|
|
reveal_type(x) # revealed: Unknown
|
|
# error: [unresolved-reference]
|
|
reveal_type(y) # revealed: Unknown
|
|
|
|
def cond() -> bool:
|
|
return True
|
|
|
|
b = 1
|
|
if cond():
|
|
del b
|
|
|
|
# error: [possibly-unresolved-reference]
|
|
reveal_type(b) # revealed: Literal[1]
|
|
|
|
c = 1
|
|
if cond():
|
|
c = 2
|
|
else:
|
|
del c
|
|
|
|
# error: [possibly-unresolved-reference]
|
|
reveal_type(c) # revealed: Literal[2]
|
|
|
|
d = 1
|
|
|
|
def delete():
|
|
# TODO: this results in `UnboundLocalError`; we should emit `unresolved-reference`
|
|
del d
|
|
|
|
delete()
|
|
reveal_type(d) # revealed: Literal[1]
|
|
|
|
def delete_global():
|
|
global d
|
|
del d
|
|
|
|
delete_global()
|
|
# The variable should have been removed, but we won't check it for now.
|
|
reveal_type(d) # revealed: Literal[1]
|
|
```
|
|
|
|
## Delete attributes
|
|
|
|
If an attribute is referenced after being deleted, it will be an error at runtime. But we don't
|
|
treat this as an error (because there may have been a redefinition by a method between the `del`
|
|
statement and the reference). However, deleting an attribute invalidates type narrowing by
|
|
assignment, and the attribute type will be the originally declared type.
|
|
|
|
### Invalidate narrowing
|
|
|
|
```py
|
|
class C:
|
|
x: int = 1
|
|
|
|
c = C()
|
|
del c.x
|
|
reveal_type(c.x) # revealed: int
|
|
|
|
# error: [unresolved-attribute]
|
|
del c.non_existent
|
|
|
|
c.x = 1
|
|
reveal_type(c.x) # revealed: Literal[1]
|
|
del c.x
|
|
reveal_type(c.x) # revealed: int
|
|
```
|
|
|
|
### Delete an instance attribute definition
|
|
|
|
```py
|
|
class C:
|
|
x: int = 1
|
|
|
|
c = C()
|
|
reveal_type(c.x) # revealed: int
|
|
|
|
del C.x
|
|
c = C()
|
|
# This attribute is unresolved, but we won't check it for now.
|
|
reveal_type(c.x) # revealed: int
|
|
```
|
|
|
|
## Delete items
|
|
|
|
Deleting an item also invalidates the narrowing by the assignment, but accessing the item itself is
|
|
still valid.
|
|
|
|
```py
|
|
def f(l: list[int]):
|
|
del l[0]
|
|
# If the length of `l` was 1, this will be a runtime error,
|
|
# but if it was greater than that, it will not be an error.
|
|
reveal_type(l[0]) # revealed: int
|
|
|
|
# error: [call-non-callable]
|
|
del l["string"]
|
|
|
|
l[0] = 1
|
|
reveal_type(l[0]) # revealed: Literal[1]
|
|
del l[0]
|
|
reveal_type(l[0]) # revealed: int
|
|
```
|