InsecureSignpost

joined 1 year ago
[–] [email protected] 5 points 1 year ago

In my opinion, it doesn't. I'd rather have foo() and detailed_foo() over foo(detailed: bool = False).

Designing APIs can be hard at times. You have to shift your view to the person that will being using the code instead of the person implementing the code. There is also potential down side of returning a tuple or just a single thing if the single thing shares some of the same API as a tuple. Say the return type is Union[str, tuple[str, str]. Now result[0] can either be the first string or the first character of the returned string depending on how the function was called. This could lead to the failure happening farther away from where the bug is, which makes debugging harder. That being said, if you do want to proceed this way, overload with Literal[True] is the correct way to type this as mentioned in other comments.

I also don't think it's overkill to extract functionality just for 2 functions. I often do that even when it is only used in one function. Maybe the number of lines to implement the block starts to make the primary function too long. Or the logic is a bit complicated, so it easier to give it a clearer name.

[–] [email protected] 3 points 1 year ago (5 children)

Agreed. I avoid having the shape of the return type be determined by arguments. Having the return type be generic is one thing. But this is different as here you are taking about returning 1 object or 2 objects.

[–] [email protected] 3 points 1 year ago

In addition to what others have said, collection literals are also faster. list[str]() performs a function call that technically might not be the built-in list. Where [] is always an empty list and it can be created with less overhead.

[–] [email protected] 5 points 1 year ago (1 children)

For unit tests, I put them within a folder parallel to the source code. The directory in that folder matches the module hierarchy.

A flat structure can work for extremely small projects, but things start to go sideways as the code base grows.

Putting the test files alongside the source files makes it harder work with from a project management perspective:

  • pytest has to check more files when doing discovery, which makes the tests take longer
  • It is significantly harder to configure mypy to a more lenient set of rules for test code.
  • It is harder to package/deploy only the runtime code

If the project is big enough to have integration tests, I prefer to have those in their own folder like the unit test folder. It is possible to mark tests into different categories, but putting them in a dedicated folder makes it is harder for people to forget to mark an integration test.