from typing import Literal, Union


def func1(arg1: Literal[None]):
    ...


def func2(arg1: Literal[None] | int):
    ...


def func3() -> Literal[None]:
    ...


def func4(arg1: Literal[int, None, float]):
    ...


def func5(arg1: Literal[None, None]):
    ...


def func6(arg1: Literal[
    "hello",
    None  # Comment 1
    , "world"
    ]):
    ...


def func7(arg1: Literal[
    None  # Comment 1
    ]):
    ...


def func8(arg1: Literal[None] | None):
    ...


def func9(arg1: Union[Literal[None], None]):
    ...


# OK
def good_func(arg1: Literal[int] | None):
    ...


# From flake8-pyi
Literal[None]  # Y061 None inside "Literal[]" expression. Replace with "None"
Literal[True, None]  # Y061 None inside "Literal[]" expression. Replace with "Literal[True] | None"

###
# The following rules here are slightly subtle,
# but make sense when it comes to giving the best suggestions to users of flake8-pyi.
###

# If Y061 and Y062 both apply, but all the duplicate members are None,
# only emit Y061...
Literal[None, None]  # Y061 None inside "Literal[]" expression. Replace with "None"
Literal[1, None, "foo", None]  # Y061 None inside "Literal[]" expression. Replace with "Literal[1, 'foo'] | None"

# ... but if Y061 and Y062 both apply
# and there are no None members in the Literal[] slice,
# only emit Y062:
Literal[None, True, None, True]  # Y062 Duplicate "Literal[]" member "True"


# Regression tests for https://github.com/astral-sh/ruff/issues/14567
x: Literal[None] | None
y: None | Literal[None]
z: Union[Literal[None], None]

a: int | Literal[None] | None
b: None | Literal[None] | None
c: (None | Literal[None]) | None
d: None | (Literal[None] | None)
e: None | ((None | Literal[None]) | None) | None

# Test cases for operator precedence issue (https://github.com/astral-sh/ruff/issues/20265)
print(Literal[1, None].__dict__)  # Should become (Literal[1] | None).__dict__
print(Literal[1, None].method())  # Should become (Literal[1] | None).method()
print(Literal[1, None][0])  # Should become (Literal[1] | None)[0]
print(Literal[1, None] + 1)  # Should become (Literal[1] | None) + 1
print(Literal[1, None] * 2)  # Should become (Literal[1] | None) * 2
print((Literal[1, None]).__dict__)  # Should become ((Literal[1] | None)).__dict__

# Regression test for https://github.com/astral-sh/ruff/issues/20729.
# Rewriting this changes `typing.get_args(options)` at runtime, so the fix is unsafe.
options = Literal["foo", "bar", None]
