Skip to content
Advertisement

“Expected type” warning from changing dictionary value from None type to str type within a function (Pycharm IDE)

I have a dictionary for which the key "name" is initialized to None (as this be easily used in if name: blocks) if a name is read in it is then assigned to name.

All of this works fine but Pycharm throws a warning when “name” is changed due to the change in type. While this isn’t the end of the world it’s a pain for debugging (and could be a pain for maintaining the code). Does anyone know if there is a way either to provide something akin to a type hint to the dictionary or failing that to tell Pycharm the change of type is intended?

code replicating issue:

from copy import deepcopy

test = {
    "name": None,
    "other_variables": "Something"
}


def read_info():
    test_2 = deepcopy(test)
    test_2["name"] = "this is the name"  # Pycharm shows warning
    return test_2["name"]

ideal solution:

from copy import deepcopy

test = {
    "name": None type=str,
    "other_variables": "Something"
}


def read_info():
    test_2 = deepcopy(test)
    test_2["name"] = "this is the name"  # no warning
    return test_2["name"]

Note: I know that setting the default value to "" would behave the same but a) it’s handy having it print out “None” if name is printed before assignment and b) I find it slightly more readable to have None instead of "".

Note_2: I am unaware why (it may be a bug or intended for some reason I don’t understand) but Pycharm only gives a wanrning if the code shown above is found within a function. i.e. replacing the read_info() function with the lines:

test_2 = deepcopy(test)
test_2["name"] = "this is the name"  # Pycharm shows warning

Does not give a warning

Advertisement

Answer

Type hinting that dictionary with dict[str, None | str] (Python 3.10+, older versions need to use typing.Dict[str, typing.Optional[str]]) seems to fix this:

from copy import deepcopy

test: dict[str, None | str] = {
    "name": None,
    "other_variables": "Something"
}


def read_info():
    test_2 = deepcopy(test)
    test_2["name"] = "this is the name"  # no warning
    return test_2["name"]

As noticed by @Tomerikoo simply type hinting as dict also works (this should work on all? Python versions that support type hints too):

test: dict = {
    "name": None,
    "other_variables": "Something"
}
User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement