opencv-python icon indicating copy to clipboard operation
opencv-python copied to clipboard

Recursion when importing cv2 from debugger

Open impact27 opened this issue 2 years ago • 6 comments

Expected behaviour

No recursion

Actual behaviour

ImportError: ERROR: recursion is detected during loading of "cv2" binary extensions.

Steps to reproduce

  1. pip install "opencv-python>=4.6" (works with 4.5)
  2. ipython
  3. %debug import cv2
  4. n
Python 3.9.12 (main, Mar 26 2022, 15:52:10) 
Type 'copyright', 'credits' or 'license' for more information
IPython 7.34.0 -- An enhanced Interactive Python. Type '?' for help.

In [1]: %debug import cv2
NOTE: Enter 'c' at the ipdb>  prompt to continue execution.
> <string>(1)<module>()

ipdb> n
['/usr/local/bin', '/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python39.zip', '/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9', '/usr/local/Cellar/[email protected]/3.9.12/Frameworks/Python.framework/Versions/3.9/lib/python3.9/lib-dynload', '', '/usr/local/lib/python3.9/site-packages', '/Users/quentinpeter/pyscripts/spyder', '/Users/quentinpeter/pyscripts/spyder/external-deps/qdarkstyle', '/Users/quentinpeter/pyscripts/spyder-kernels', '/usr/local/lib/python3.9/site-packages/IPython/extensions', '/Users/quentinpeter/.ipython']
ImportError: ERROR: recursion is detected during loading of "cv2" binary extensions. Check OpenCV installation.
> <string>(1)<module>()

ipdb> 

  • example code
  • operating system
  • architecture (e.g. x86)
  • opencv-python version
Issue submission checklist
  • [x] This is not a generic OpenCV usage question (looking for help for coding, other usage questions, homework etc.)
  • [x] I have read the README of this repository and understand that this repository provides only an automated build toolchain for OpenCV Python packages (there is no actual OpenCV code here)
  • [ ] The issue is related to the build scripts in this repository, to the pre-built binaries or is a feature request (such as "please enable this additional dependency")
  • [x] I'm using the latest version of opencv-python

impact27 avatar Jul 13 '22 15:07 impact27

See https://github.com/spyder-ide/spyder/issues/18581

impact27 avatar Jul 13 '22 15:07 impact27

I can get it to work by replacing: https://github.com/opencv/opencv/blob/17234f82d025e3bbfbf611089637e5aa2038e7b8/modules/python/package/cv2/init.py#L92 by: l_vars = locals().copy() The doc of locals might give a guess as to why that works:

Return a dictionary containing the current scope's local variables.

NOTE: Whether or not updates to this dictionary will affect name lookups in
the local scope and vice-versa is *implementation dependent* and not
covered by any backwards compatibility guarantees.

impact27 avatar Jul 13 '22 15:07 impact27

Hello @impact27!

I see that this problem happens only with ipython. I've reproduced it in ipython even not in a debug mode, but if to use just python interpreter, it doesn't happen.

If to say about the line in opencv with l_vars = locals(), it was the same even in the previous release.

Maybe something wrong with locals(), it's different in python interpreter and ipython.

  • python interpreter:
>>> print(locals())
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>}
  • ipython:
{'__name__': '__main__', '__doc__': 'Automatically created module for IPython interactive environment', '__package__': None, '__loader__': None, '__spec__': None, '__builtin__': <module 'builtins' (built-in)>, '__builtins__': <module 'builtins' (built-in)>, '_ih': ['', 'print(locals())'], '_oh': {}, '_dh': [PosixPath('/')], 'In': ['', 'print(locals())'], 'Out': {}, 'get_ipython': <bound method InteractiveShell.get_ipython of <IPython.terminal.interactiveshell.TerminalInteractiveShell object at 0x7f081aac3c70>>, 'exit': <IPython.core.autocall.ExitAutocall object at 0x7f081aabdfd0>, 'quit': <IPython.core.autocall.ExitAutocall object at 0x7f081aabdfd0>, '_': '', '__': '', '___': '', '_i': '', '_ii': '', '_iii': '', '_i1': 'print(locals())'}

asenyaev avatar Jul 18 '22 15:07 asenyaev

From the doc (https://docs.python.org/3/library/functions.html#locals): "The contents of this dictionary should not be modified". The way I interpret this is that modifying l_vars is undefined behaviour. I understand that ipython is behaving differently from python, but if this is undefined behaviour, this is not a bug in ipython.

impact27 avatar Jul 18 '22 21:07 impact27

The fix for this issue was merged in 3.4 branch of opencv (https://github.com/opencv/opencv/pull/22269) and will be in 4.x in the next 3.4 -> 4.x merge. The opencv-python package will have this update in the next release.

Thank you @impact27!

asenyaev avatar Jul 20 '22 12:07 asenyaev

Promotion to 4.x: https://github.com/opencv/opencv/pull/22305

asmorkalov avatar Jul 28 '22 11:07 asmorkalov