Convention: return value of functions modifying input arguments in place

My question is:

Why do python drawing functions like:

  • cv2.rectangle
  • cv2.putText
  • cv2.line
    and alike
    return the img?

I would argue that it is a bad api design.

argument 1:
It is confusing, because it suggests that a new modified img is returned,
while actually the img given as input argument is modified in place.

argument 2:
In python standard library, there are two ways to sort a list
using sorted() function which returns a new sorted list (leaving the input unmodified),
or using a list.sort() method which modifies the list in place and returns None

argument 3:
In-place operations returning themselves can allow you to perform “method chaining”, however, this is bad practice because you may bury functions with side-effects in the middle of a chain by accident.
source: python - Is making in-place operations return the object a bad idea? - Stack Overflow

So there are ways to fix it:

  • don’t return img, but return None
  • return a new image

Are the maintainers willing to fix it in the library?

OpenCV is C++ first.

that explains those APIs. you don’t sound like you looked into that.

The Python bindings are generated automatically.

if you need this changed, feel free to dig into the source of the bindings generator.

if you’re looking for a debate, I’d recommend a less demanding tone.

listen to why things are as they are.

sucks to be you, but you aren’t paying for this, so maybe manage your expectations?

Hi @adrianstaniec

I agree with you that the API is not very pythonic. But it’s not a bad design.

As @crackwitz said, OpenCV is written in C++, with automatic Python bindings.

One design choice is to use numpy for images instead of Mat, as many Python images libraries do. So, adding methods to numpy, like numpy.rectangle() is out of the question.

These are not bad choices and no one is trying to fix them. Before debating them, this is worth reading:
https://docs.opencv.org/4.x/da/d49/tutorial_py_bindings_basics.html

The developing effort in opencv library is focus on adding features. Automatic bindings is a way to minimize development effort, and yet there still are a lot of opencv classes without Python bindings.

Of course, anyone is welcome to create his own Python bindings and share it with the community.

thank you for responses

I am not trying to be demanding or negative
I only took the effort to write this post because I care about the library and the users
and because I want to understand the choices made about it

so let me start over
because my basic question here is this:


Why does the python version return the img?

img is typed as an “InputOutputArray”, and the bindings generator simply puts everything in the result that is “output”.

in that drawing call, one always has to pass img in. in this case, also returning it wouldn’t be strictly necessary, because the caller already has a reference to it (the result).

however, there are OpenCV APIs that accept no/default arguments for some parameters, for convenience.

consider cvtColor. you don’t have to give it a dst. but you can. if you don’t, cvtColor creates it for you… and if it didn’t return that, you’d have no way to get a hold of the automatically created object.

both APIs call these parameters InputOutputArray. the only difference is that one requires an argument, for the other it’s optional.

the bindings generator does something that works for both cases.

I guess it is conceivable that mandatory-argument InputOutputArray parameters not be returned… but that probably requires more advanced analysis of the C++ code by the bindings generator than anyone as yet found worth the trouble.

1 Like

I doubt that the maintainers will want to change the API and break all existing code which uses it.