Do stubs have to be valid Python?
Hi all I'm guessing the answer to my question in the subject line is "yes", but I'm hoping its "not necessarily". I'm working on stubs for Pandas. Pandas Series have a bunch of methods for which there is an "in place" argument. If True, the method will return None; if False, it will return a new DataFrame. The way I thought of trying to handle this is by doing something like this: @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., *inplace: Literal[True]*, limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ...,* inplace: Optional[Literal[False]] = ...*, limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: .. The problem is that in the first case I am making the optional argument mandatory, and it lies in the middle of other optional arguments. I don't want to move it positionally because there is plenty of existing code out there that would then break. My guess is that this is not okay, but is there an alternative solution? Thanks Graham
You're right, that doesn't parse, so it's not valid. (Have you tried it with mypy yet?) The only suggestion I have is to move it to the end and make it a mandatory keyword arg, like so: def foo(a, b, c=..., d=..., *, foo=..., baz): ... (but with type annotations). On Mon, Apr 27, 2020 at 11:10 AM Graham Wheeler <gram@geekraver.com> wrote:
Hi all
I'm guessing the answer to my question in the subject line is "yes", but I'm hoping its "not necessarily".
I'm working on stubs for Pandas. Pandas Series have a bunch of methods for which there is an "in place" argument. If True, the method will return None; if False, it will return a new DataFrame.
The way I thought of trying to handle this is by doing something like this:
@overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., *inplace: Literal[True]*, limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ...,* inplace: Optional[Literal[False]] = ...*, limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: ..
The problem is that in the first case I am making the optional argument mandatory, and it lies in the middle of other optional arguments. I don't want to move it positionally because there is plenty of existing code out there that would then break.
My guess is that this is not okay, but is there an alternative solution?
Thanks Graham
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Thanks Guido, that suggestion of yours works for me. On Mon, Apr 27, 2020 at 11:40 AM Guido van Rossum <guido@python.org> wrote:
You're right, that doesn't parse, so it's not valid. (Have you tried it with mypy yet?)
The only suggestion I have is to move it to the end and make it a mandatory keyword arg, like so:
def foo(a, b, c=..., d=..., *, foo=..., baz): ...
(but with type annotations).
On Mon, Apr 27, 2020 at 11:10 AM Graham Wheeler <gram@geekraver.com> wrote:
Hi all
I'm guessing the answer to my question in the subject line is "yes", but I'm hoping its "not necessarily".
I'm working on stubs for Pandas. Pandas Series have a bunch of methods for which there is an "in place" argument. If True, the method will return None; if False, it will return a new DataFrame.
The way I thought of trying to handle this is by doing something like this:
@overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., *inplace: Literal[True]*, limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ...,* inplace: Optional[Literal[False]] = ...*, limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: ..
The problem is that in the first case I am making the optional argument mandatory, and it lies in the middle of other optional arguments. I don't want to move it positionally because there is plenty of existing code out there that would then break.
My guess is that this is not okay, but is there an alternative solution?
Thanks Graham
_______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/
-- --Guido van Rossum (python.org/~guido) *Pronouns: he/him **(why is my pronoun here?)* <http://feministing.com/2015/02/03/how-using-they-as-a-singular-pronoun-can-change-the-world/>
Am 27.04.20 um 18:57 schrieb Graham Wheeler:
@overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Optional[Literal[False]] = ..., limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: ..
You can make this work using multiple overloads: @overload def replace(self, to_replace: Optional[Any], value: Optional[Any], inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any], *, value: Optional[Any] = ..., inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, *, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ...,inplace: Optional[Literal[False]] = ..., limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: .. Not particularly elegant, but it should work. - Sebastian
Thanks Guido, Sebastian , let me give these a try. On Mon, Apr 27, 2020 at 12:35 PM Sebastian Rittau <srittau@rittau.biz> wrote:
Am 27.04.20 um 18:57 schrieb Graham Wheeler:
@overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Optional[Literal[False]] = ..., limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: ..
You can make this work using multiple overloads: @overload def replace(self, to_replace: Optional[Any], value: Optional[Any], inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any], *, value: Optional[Any] = ..., inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, *, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Literal[True], limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> None: ... @overload def replace(self, to_replace: Optional[Any] = ..., value: Optional[Any] = ..., inplace: Optional[Literal[False]] = ..., limit: Optional[int] = ..., regex: _Regex = ..., method: _str = ...) -> DataFrame: ..
Not particularly elegant, but it should work.
- Sebastian _______________________________________________ Typing-sig mailing list -- typing-sig@python.org To unsubscribe send an email to typing-sig-leave@python.org https://mail.python.org/mailman3/lists/typing-sig.python.org/
participants (3)
-
Graham Wheeler
-
Guido van Rossum
-
Sebastian Rittau