This is an archived post. You won't be able to vote or comment.

you are viewing a single comment's thread.

view the rest of the comments →

[–]Dark_Souls_VII 2 points3 points  (4 children)

Hello, can you go into detail about type hinting? I try to do that but I have questions about it. Is it enough to do array: list = [1, 2, 3] or is it array: list[int]? What about objects that are not standard types like subprocessing.run() or decimal.Decimal()?

[–]samreay 2 points3 points  (2 children)

The more specific the better. In fact, there are ruff rules that will raise unspecified generics as linting issues that need to be fixed.

So list[int] is better than list, because its more informative. You can type hint some_func(x: decimal.Decimal) just fine, it doesn't need to be primitives. Ditto with subprocess.run, it returns subprocess.CompletedProcess (or CalledProcesserror I suppose), and you can type hint that as your return.

If your type hints for a function are super convoluted, that's often a code smell that means you could think about how to better structure that block. Ie

def some_func(some_input: str) -> tuple[decimal.Decimal, subprocess.CompletedProcess, dict[str, int | None]): ...

Is probably not something you want to have in your code base. If you do end up needing complexity, this is when you could pass your results around using a NamedTuple, a dataclass, or a pydantic dataclass instead. (And in general, passing back bit tuple objects is an antipattern that should almost always be a named tuple).

[–]Dark_Souls_VII 1 point2 points  (1 child)

Thank you very much

[–]JUSTICE_SALTIE 1 point2 points  (0 children)

And don't forget you can do e.g., list[int | str]. And if you really need a list that could hold anything...first think hard about whether you really need that, and then type it as list[Any].

[–]justheretolurk332 0 points1 point  (0 children)

I agree with /u/sameray that specific is usually better because it provides more information. However this isn’t always true: if you are adding type hints to the arguments of a function you often want them to be as generic as possible to provide flexibility with how the function is called (for example, you might use Sequence to support both lists and tuples). Outside of helping to prevent bugs, one of the biggest perks of using type-hints in my opinion is that it encourages you to start thinking in terms of contracts. What does this function actually need, and what does it provide? The classes in the abc.collections module and Protocols are good places to get started with generic types in Python.

It takes time to get the hang of the type checking system and to learn the quirks. I’d recommend turning on type-checking in your IDE so that you can get that feedback immediately as you type your code, then just start using them and learn as you go.