Replies: 2 comments 8 replies
-
I agree that Python's handling of default arguments is problematic. When I first encountered Python, I assumed it did what all other languages do and allocated the default argument at call time. I was dismayed to learn that it does so at function declaration time. The challenge with your proposed change is that the Python type system doesn't have a notion of "mutable" vs. "not mutable". A feature like this would need to have a hard-coded "allow list" (or conversely, a "disallow list") of types. That's something we generally try to avoid because such lists are inevitably incomplete resulting in false positive errors. Do you have any thoughts on how such a feature could be implemented without maintaining a hard-coded type list? |
Beta Was this translation helpful? Give feedback.
-
Could Indeed, if this advice is respected: pyright/docs/typed-libraries.md Line 219 in 5422827 a signature like this: def increment(numbers: Iterable[int] = []) -> List[int]:
return [number + 1 for number in numbers] is safe since Pyright already ensures that the numbers argument (and so the default argument too) won't be mutated. Pyright even catches subtler unsafe types: def increment(numbers: Iterable[int], *, value: int = 1) -> List[int]:
return numbers if value == 0 else [number + value for number in numbers] by raising the error:
Allowing safe usage of mutable default arguments like this has some advantages:
What do you think? |
Beta Was this translation helpful? Give feedback.
-
Pyright already warns about function calls in default arguments (
reportCallInDefaultInitializer
), but I would like to suggest that it also warn about mutable default arguments such as:The fact that the default argument expression is evaluated at module load time means that all invocations of the function like
func()
will use the same reference to a single list. Meaning,This came up in this Hacker News thread, and I suggested Pyright thinking it already warns about such cases, but it doesn't.
It might be worth noting that Javascript's default argument implementation evaluates default arguments at call time, further demonstrating the unpopularity of Python's approach.
Beta Was this translation helpful? Give feedback.
All reactions