Replies: 1 comment 3 replies
-
When a variable or parameter has a declared (annotated) type, it's the job of a type checker to validate that all values assigned to that variable are compatible with the declared type. This is how type checking works in all languages that I'm familiar with. The recommended approach is to use a different variable name if you need a different type. You can choose to declare the type of this other variable or let pyright infer its type. Your example above demonstrates nicely why it's a bad idea to use the same variable name for different uses. The input parameter to This version of the function not only type checks, but it's easier to understand because the variable names reflect their real purpose. def test(config_path: str):
config_path = str(Path(config_path).expanduser())
config = load_config(config_path)
print(config.get("example")) |
Beta Was this translation helpful? Give feedback.
-
In #2374, I asked about a pyright equivalent for mypy's "allow_redefinition". While there was another way to deal with that issue, there's another pattern I sometimes use that doesn't seem as amenable to this. I basically want to convert a variable from one type to another part with through a code block, with the old type applying for the first part of the block and the new type applying for the remainder of it. As an example, consider the case of loading configuration data from a file:
So, the example function is passed the path of where to load the config and it might do some manipulation of that path, but at a certain point in the function it will call load_config(), after which the type of "config" needs to be a Dict rather than a str. This works fine in mypy (with or without 'allow_redefinition'), but pyright gives errors:
I've tried various options using cast() or just declaring the types again, but this doesn't seem to work. Wherever I set the type, it seems to apply to all references to that variable in that scope, both before and after the place where I put the declaration. I'd basically have to break the function in two to make pyright happy.
The simplest answer is "don't reuse the variable", but I have some public APIs that currently work this way, and while I could rename the variable inside each of the API functions that do this, that's a pretty painful change just to make a type checker happy. Is there any way to tell pyright what's happening here?
Beta Was this translation helpful? Give feedback.
All reactions