Skip to content

Commit

Permalink
Avoid failures due to non-deterministic binding ordering (#10478)
Browse files Browse the repository at this point in the history
## Summary

We're seeing failures in #10470
because `resolve_qualified_import_name` isn't guaranteed to return a
specific import if a symbol is accessible in two ways (e.g., you have
both `import logging` and `from logging import error` in scope, and you
want `logging.error`). This PR breaks up the failing tests such that the
imports aren't in the same scope.

Closes #10470.

## Test Plan

I added a `bindings.reverse()` to `resolve_qualified_import_name` to
ensure that the tests pass regardless of the binding order.
  • Loading branch information
charliermarsh committed Mar 19, 2024
1 parent ffd6e79 commit bc9b457
Show file tree
Hide file tree
Showing 17 changed files with 1,001 additions and 1,120 deletions.
@@ -1,9 +1,12 @@
import logging
def func():
import logging

logging.WARN # LOG009
logging.WARNING # OK
logging.WARN # LOG009
logging.WARNING # OK

from logging import WARN, WARNING

WARN # LOG009
WARNING # OK
def func():
from logging import WARN, WARNING

WARN # LOG009
WARNING # OK
35 changes: 26 additions & 9 deletions crates/ruff_linter/resources/test/fixtures/pyupgrade/UP017.py
@@ -1,11 +1,28 @@
import datetime
import datetime as dt
from datetime import timezone
from datetime import timezone as tz
def func():
import datetime

print(datetime.timezone(-1))
print(timezone.utc)
print(tz.utc)
print(datetime.timezone(-1))

print(datetime.timezone.utc)
print(dt.timezone.utc)

def func():
from datetime import timezone

print(timezone.utc)


def func():
from datetime import timezone as tz

print(tz.utc)


def func():
import datetime

print(datetime.timezone.utc)


def func():
import datetime as dt

print(dt.timezone.utc)
13 changes: 3 additions & 10 deletions crates/ruff_linter/resources/test/fixtures/refurb/FURB163.py
@@ -1,25 +1,17 @@
import math

from math import e as special_e
from math import log as special_log

# Errors.
# Errors
math.log(1, 2)
math.log(1, 10)
math.log(1, math.e)
foo = ...
math.log(foo, 2)
math.log(foo, 10)
math.log(foo, math.e)
math.log(1, special_e)
special_log(1, 2)
special_log(1, 10)
special_log(1, math.e)
special_log(1, special_e)
math.log(1, 2.0)
math.log(1, 10.0)

# Ok.
# OK
math.log2(1)
math.log10(1)
math.log(1)
Expand All @@ -40,6 +32,7 @@

math.log(1, base=2) # math.log does not accept keyword arguments.


def log(*args):
print(f"Logging: {args}")

Expand Down
21 changes: 0 additions & 21 deletions crates/ruff_linter/resources/test/fixtures/ruff/RUF013_0.py
@@ -1,4 +1,3 @@
import typing
from typing import Annotated, Any, Literal, Optional, Tuple, Union, Hashable


Expand Down Expand Up @@ -26,10 +25,6 @@ def f(arg: str = None): # RUF013
pass


def f(arg: typing.List[str] = None): # RUF013
pass


def f(arg: Tuple[str] = None): # RUF013
pass

Expand All @@ -41,10 +36,6 @@ def f(arg: Optional[int] = None):
pass


def f(arg: typing.Optional[int] = None):
pass


# Union


Expand All @@ -60,10 +51,6 @@ def f(arg: Union[str, None] = None):
pass


def f(arg: typing.Union[int, str, None] = None):
pass


def f(arg: Union[int, str, Any] = None):
pass

Expand All @@ -80,10 +67,6 @@ def f(arg: Union[int, str] = None): # RUF013
pass


def f(arg: typing.Union[int, str] = None): # RUF013
pass


# PEP 604 Union


Expand Down Expand Up @@ -130,10 +113,6 @@ def f(arg: Literal[1, "foo"] = None): # RUF013
pass


def f(arg: typing.Literal[1, "foo", True] = None): # RUF013
pass


# Annotated


Expand Down
@@ -1,5 +1,5 @@
# No `typing.Optional` import


def f(arg: int = None): # RUF011
def f(arg: int = None): # RUF013
pass
30 changes: 30 additions & 0 deletions crates/ruff_linter/resources/test/fixtures/ruff/RUF013_3.py
@@ -0,0 +1,30 @@
import typing


def f(arg: typing.List[str] = None): # RUF013
pass


# Optional


def f(arg: typing.Optional[int] = None):
pass


# Union


def f(arg: typing.Union[int, str, None] = None):
pass


def f(arg: typing.Union[int, str] = None): # RUF013
pass


# Literal


def f(arg: typing.Literal[1, "foo", True] = None): # RUF013
pass
38 changes: 30 additions & 8 deletions crates/ruff_linter/resources/test/fixtures/tryceratops/TRY400.py
Expand Up @@ -3,13 +3,10 @@
Use '.exception' over '.error' inside except blocks
"""

import logging
import sys

logger = logging.getLogger(__name__)


def bad():
import logging

try:
a = 1
except Exception:
Expand All @@ -20,6 +17,10 @@ def bad():


def bad():
import logging

logger = logging.getLogger(__name__)

try:
a = 1
except Exception:
Expand Down Expand Up @@ -50,6 +51,10 @@ def bad():


def good():
import logging

logger = logging.getLogger(__name__)

try:
a = 1
except Exception:
Expand All @@ -64,23 +69,31 @@ def good():


def fine():
import logging

logger = logging.getLogger(__name__)

try:
a = 1
except Exception:
logger.error("Context message here", exc_info=True)


def fine():
import logging
import sys

logger = logging.getLogger(__name__)

try:
a = 1
except Exception:
logger.error("Context message here", exc_info=sys.exc_info())


from logging import error, exception


def bad():
from logging import error, exception

try:
a = 1
except Exception:
Expand All @@ -91,27 +104,36 @@ def bad():


def good():
from logging import error, exception

try:
a = 1
except Exception:
exception("Context message here")


def fine():
from logging import error, exception

try:
a = 1
except Exception:
error("Context message here", exc_info=True)


def fine():
from logging import error, exception
import sys

try:
a = 1
except Exception:
error("Context message here", exc_info=sys.exc_info())


def nested():
from logging import error, exception

try:
a = 1
except Exception:
Expand Down
@@ -1,41 +1,40 @@
---
source: crates/ruff_linter/src/rules/flake8_logging/mod.rs
---
LOG009.py:3:1: LOG009 [*] Use of undocumented `logging.WARN` constant
LOG009.py:4:5: LOG009 [*] Use of undocumented `logging.WARN` constant
|
1 | import logging
2 |
3 | logging.WARN # LOG009
| ^^^^^^^^^^^^ LOG009
4 | logging.WARNING # OK
2 | import logging
3 |
4 | logging.WARN # LOG009
| ^^^^^^^^^^^^ LOG009
5 | logging.WARNING # OK
|
= help: Replace `logging.WARN` with `logging.WARNING`

Safe fix
1 1 | import logging
2 2 |
3 |-logging.WARN # LOG009
3 |+logging.WARNING # LOG009
4 4 | logging.WARNING # OK
5 5 |
6 6 | from logging import WARN, WARNING

LOG009.py:8:1: LOG009 [*] Use of undocumented `logging.WARN` constant
|
6 | from logging import WARN, WARNING
7 |
8 | WARN # LOG009
| ^^^^ LOG009
9 | WARNING # OK
|
= help: Replace `logging.WARN` with `logging.WARNING`

Safe fix
5 5 |
6 6 | from logging import WARN, WARNING
1 1 | def func():
2 2 | import logging
3 3 |
4 |- logging.WARN # LOG009
4 |+ logging.WARNING # LOG009
5 5 | logging.WARNING # OK
6 6 |
7 7 |
8 |-WARN # LOG009
8 |+logging.WARNING # LOG009
9 9 | WARNING # OK

LOG009.py:11:5: LOG009 [*] Use of undocumented `logging.WARN` constant
|
9 | from logging import WARN, WARNING
10 |
11 | WARN # LOG009
| ^^^^ LOG009
12 | WARNING # OK
|
= help: Replace `logging.WARN` with `logging.WARNING`

Safe fix
8 8 | def func():
9 9 | from logging import WARN, WARNING
10 10 |
11 |- WARN # LOG009
11 |+ WARNING # LOG009
12 12 | WARNING # OK

0 comments on commit bc9b457

Please sign in to comment.