On Thu, 19 Oct 2023 at 10:11, Matthew Carruth via Python-list <python-list@python.org> wrote: > > We have the `Optional[T]` type as a short-hand for Union[T | None] and > telling us that said argument may not be present. > > However, I find that a majority of the time, we also want to set a default > value of None on the argument so that it can be evaluated without doing a > getattr() check first. > > iow, a lot of `foo: Optional[str] = None` in method signatures. > > I'd love to see a companion to the Optional type, I'll call it Default, so > that it can take a default value as a second arg, with a default of that > being None. > > For example: > > foo: Default[str] would be equivalent to foo: Optional[str] = None > foo: Default[str, "bar"] would be equivalent to foo: Optional[str] = "bar" > > or something like that. Basically, any way to avoid writing `= None` over and > over again.
Fundamentally no, at least not without some shenanigans. Type hints do not affect the regular running of the code, so they can't add defaults. You could do it the other way around and have the default imply that it is optional, and I believe that used to be the way that MyPy calculated things, but it was ultimately rejected. (I may have the details wrong on that though, don't quote me.) Ahh, but shenanigans? What kind of shenanigans is that? Glad you asked! So, uhh, you could decorate a function and mess with its defaults. >>> from typing import Optional >>> def spam(n: Optional[int]): ... if n is None: print("Default spamminess") ... else: print("Spam " * n) ... >>> spam(5) Spam Spam Spam Spam Spam >>> spam(None) Default spamminess >>> spam() Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: spam() missing 1 required positional argument: 'n' >>> spam.__defaults__ = (None,) >>> spam() Default spamminess So you could design a decorator that goes through all the arguments, finds the ones that say "Optional", and adds a default of None if one wasn't specified. Good luck with it though. First, you'll have to deal with the difficulties of aligning arguments (not insurmountable but a lot of work; don't forget that there are posonly and kwonly args to consider). Then, you'll have to deal with the much bigger difficulties of convincing people that this is a good thing. BTW, rather than a decorator, you could do this by iterating over every function in a module or class. That might work out easier. Not sure. Just be aware that, while Python provides you with all the tools necessary to shoot yourself in the foot, that isn't a guarantee that holes in feet are worthwhile. ChrisA -- https://mail.python.org/mailman/listinfo/python-list