Live data from Hacker News

Python Type Hints – *args and **kwargs (2021)

adamj.eu

21–30 of 158 posts

Re: Python Type Hints – *args and **kwargs (2021)

#21
post #16

Earlier quoted context omitted.

Sadly a problem with any wrapper function is that it nullifies this kind of information. Use functools.wraps.

My question is that can @warps warp more than 1 function? Maybe in some use case people need to merge 2 functions into 1, I don't know if it can handle this situation.

I'm not sure what it means to "merge two functions into one", can you elaborate?

If you are referring to a type signature for a function that passes through it's arguments to one of two inner functions, each of which has different signatures, such that the outer signature accepts the union of the two inner signatures, well ... you could achieve that with ParamSpecs or similar, but it would be pretty hard to read and indirected. Better, I'd say, to manually express appropriate typing.Union (|) annotations on the outer function, even if that is a little less DRY.

Re: Python Type Hints – *args and **kwargs (2021)

#22

The ability of **kwargs to leave behind no proper documentation and silently swallow any invalid arguments has made us remove them entirely from our codebase. They're almost entirely redundant when you have dataclasses.

What about decorators, or wrappers around third-party code whose contracts change frequently (or even second party code when interacting with functions provided by teams that don't follow explicit argument typing guidelines, if you have that sort of culture)?

Re: Python Type Hints – *args and **kwargs (2021)

#23
post #6

Earlier quoted context omitted.

Your signature requires exactly 3 positional[0] and 3 keyword arguments. The OP allows any number of either. [0] actually 3 positional-or-keyword which is even more widely divergent

But why would you want that doesn't that make for a more confusing api? Would it not be better to just have everything as a kwarg? You would get better types that way

I genuinely don’t understand what you are asking.

Re: Python Type Hints – *args and **kwargs (2021)

#24

For typing **kwargs there are TypedDicts https://peps.python.org/pep-0692/ If your function just wraps another you can use the same type hints as the other function with functools.wraps https://docs.python.org/3/library/functools.html#functools.w...

While functools.wraps does propagate __annotations__ by default, be aware that not all IDE-integrated type checkers handle that properly. It's easy in PyCharm, for example, to use functools.wraps such that the wrapper function is treated by the IDE as untyped.

Underneath, this is because many (most?) type checkers for Python aren't actually running the code in order to access annotation information, and are instead parsing it "from the outside" using complex and fallible techniques of variable reliability. That said, it's a testament to JetBrains' excellent work that PyCharm's checker works as well as it does, given how crazily metaprogrammed even simple Python often turns out to be.

Re: Python Type Hints – *args and **kwargs (2021)

#25

The ability of **kwargs to leave behind no proper documentation and silently swallow any invalid arguments has made us remove them entirely from our codebase. They're almost entirely redundant when you have dataclasses.

What do you do when inheriting from a base class with a defined __init__ ?

Re: Python Type Hints – *args and **kwargs (2021)

#26
post #6

Earlier quoted context omitted.

Your signature requires exactly 3 positional[0] and 3 keyword arguments. The OP allows any number of either. [0] actually 3 positional-or-keyword which is even more widely divergent

But why would you want that doesn't that make for a more confusing api? Would it not be better to just have everything as a kwarg? You would get better types that way

I think what GP is saying is that with explicit kwargs you can't express variadic signatures, i.e. "this function takes one int positional, and then any number of key/value pairs where the values are lists". The variable length is the important bit.

It's certainly debatable whether doing that is better than passing a single argument whose value is a dict with that same type, but many people do prefer the variadic args/kwargs style.

Re: Python Type Hints – *args and **kwargs (2021)

#27

This does restrict all of your keyword arguments to the same type. If you have keyword arguments of different types, you're right back to no type safety.

True, but there are a couple of mitigations available: you can express the types of selected kwargs (by leaving them out of the * residual), and you can use typing.Union/| to express product types for values in the residual as well.

Re: Python Type Hints – *args and **kwargs (2021)

#28

Why do people not just type everything they want passed? def variable(n:str, nn:str, nnn:str, *, a:int, b:int, c:int) Anything after,*, is a kwarg.

> Anything after,*, is a kwarg.

A required positional OR kwarg as you’ve done it. Its closer to an optional kwarg if you expand the type declaration to also allow None and set a None default.

But there are times when you want to leave the number and names of kwargs open (one example is for a dynamic wrapper—a function that wraps another function that can be different across invocations.)

Re: Python Type Hints – *args and **kwargs (2021)

#29
post #20

Although these two comes in handly, people have been using them wrong. Often in scientific open source package, they slap *kwargs in function definition without documentation. How am I suppose to know what to pass in? https://qiskit.org/ecosystem/aer/stubs/qiskit_aer.primitives...

Especially when they don't even leave a doc string so you're forced to track down the packages documentation online just to interact with certain interfaces. I work in a large python codebase, we have almost no usage of `*kwargs` beyond proxy methods because of the nature of how they obfuscate the real interface for other developers.

When I was first starting out, a then senior engineer told me: "friends don't let other friends use kwargs".

That always stuck with me.

Re: Python Type Hints – *args and **kwargs (2021)

#30
post #7

Why do people not just type everything they want passed? def variable(n:str, nn:str, nnn:str, *, a:int, b:int, c:int) Anything after,*, is a kwarg.

It is used when the number of argument can vary, like: def sum(*args: int) -> int: if len(args) == 0: return 0 return args[0] + sum(*args[1:])

It seems altogether surprising that with an empty list or tuple a, a[1] results in index error, yet a[1:] quietly returns an empty list or tuple.
Post reply on HN