top | item 28099552

(no title)

vbsteven | 4 years ago

The Spring framework (Java) does the same thing for controller methods. If you need an authenticated user, or a model object, or a path variable, just add it to the method signature and the framework will provide it.

I don’t know if there is a term for this concept. I’ve always seen it as some form of Dependency Injection/IoC but at the method level instead of object creation.

IIRC the Actix web framework in Rust does something similar for handler functions.

discuss

order

idiocratic|4 years ago

The problem with doing this in Python is that there is no typing or interfaces to help you. Basing it purely on naming of arguments breaks the assumption that argument names are local to the function/method. I find this extremely confusing to reason about, let alone the possible unwanted side effects if some developer isn’t aware that a name is magical. It’s also very non Pythonic for good reasons.

ptx|4 years ago

I feel the same way (and mostly use unittest instead) but maybe this technique makes sense as long as its use is limited to test functions?

Test functions are never called explicitly and would otherwise (like unittest TestCase methods) never have any arguments, so in this context maybe it's clear that any arguments they do have must be magical.

simonw|4 years ago

It can actually play really well with Python's optional typing. I should add that to the implementation in Datasette!

EdwardDiego|4 years ago

I've always just called it "spooooky annotation magic".

The decorator pattern seems to fit, from my POV. The framework takes your code, creates a proxy that implements the interface, and then wraps your method in a method that does the stuff you asked for with the annotations before and after your method gets called.