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

Reusing variable name in different scopes #5750

Open
takeda opened this issue Oct 8, 2018 · 5 comments
Open

Reusing variable name in different scopes #5750

takeda opened this issue Oct 8, 2018 · 5 comments

Comments

@takeda
Copy link

takeda commented Oct 8, 2018

I saw that there is a similar bug around redefining a variable, but I believe this one is slightly different problem, here is the code:

#! /usr/bin/env python

from typing import Dict, List, Union

def main(arg):
	# type: (bool) -> Union[Dict[str, str], List[str]]

	if arg:
		var = list()
		var.append('something')
	else:
		var = dict()
		var['key'] = 'something'

	return var


if __name__ == '__main__':
	main(True)

The variable var while it uses the same name, it is technically a different variable, but mypy 0.630 is complaining about it:

$ ../py37/bin/mypy --python-executable ../py27/bin/python test.py
test.py:12: error: Incompatible types in assignment (expression has type "Dict[<nothing>, <nothing>]", variable has type "List[str]")
test.py:13: error: No overload variant of "__setitem__" of "list" matches argument types "str", "str"
test.py:13: note: Possible overload variants:
test.py:13: note:     def __setitem__(self, int, str) -> None
test.py:13: note:     def __setitem__(self, slice, Iterable[str]) -> None

Ideally it should have no problem with it and at the point where there is return statement it should just do an union so the type would be Union[Dict[str, str], List[str]]

@ilevkivskyi
Copy link
Member

OK, let us keep this open, although it is just another aspect of a known problem. @JukkaL is currently exploring possible solutions.

@gvanrossum
Copy link
Member

it is technically a different variable

I beg to differ. In your example, at least, it looks like a single variable, because return var references it. (I would agree that you could argue it's two variables if that return weren't there.)

@takeda
Copy link
Author

takeda commented Oct 8, 2018

The error is still showing up even if I set return to None.

@takeda
Copy link
Author

takeda commented Oct 8, 2018

If I try to treat it as a single variable, and try to define an unified type like this:

                var = list() # type: Union[Dict[str, str], List[str]]

I get this error:

test.py:10: error: Item "Dict[str, str]" of "Union[Dict[str, str], List[str]]" has no attribute "append"

It feels that as far as type checker is concerned it probably would be easier to treat them as two different variables and then do Union at the end of the control block.

I found this pattern in code that works with JSON data if that helps.

@JukkaL
Copy link
Collaborator

JukkaL commented Oct 8, 2018

The feature I'm working on won't support this use case yet, though it would be nice if mypy would support this better. Maybe we need to revisit #2008 at some point.

Here's a workaround that works right now using Python 3.6+ syntax:

    ...
    var: Union[Dict[str, str], List[str]]
    if arg:
        var = list()
        var.append('something')
    else:
        var = dict()
        var['key'] = 'something'
    return var

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants