ets-labs / python-dependency-injector

Dependency injection framework for Python
https://python-dependency-injector.ets-labs.org/
BSD 3-Clause "New" or "Revised" License
3.9k stars 304 forks source link

Recursion Error during injection #824

Open jamesra opened 4 hours ago

jamesra commented 4 hours ago

I'm getting a recursion error when an object is instantiated using an overridden container with this rough form. Any thoughts on what the cause might be?

I'm new to dependency injection so I hope the structure is correct. I have a window that displays a transformed image, and I want the mouse to behave differently depending on the type of transform.

class ControlPointAction(enum.Flag):
    """Possible interactions for control point(s)"""
    NONE = 0
    CREATE = 1
    DELETE = 2
    TRANSLATE = 4

class TransformType(enum.Enum): 
    RIGID = 'Rigid'
    GRID = 'Grid'
    MESH = 'Mesh'
    RBF = 'RBF'

ControlPointActionCommandMapType = Dict[ControlPointAction, Factory[ICommand]]

class Container(containers.DeclarativeContainer):
# We want a different set of transform commands for each type of transform
    action_command_map = providers.Dependency(
        instance_of=providers.Dict[TransformType, ControlPointActionCommandMapType])

@containers.override(Container)
class StosContainer(containers.DeclarativeContainer):
    action_command_map = providers.Dict[TransformType, ControlPointActionCommandMapType]({
        TransformType.GRID: providers.Dict({
            ControlPointAction.NONE: providers.Factory(DefaultTransformCommand),
            ControlPointAction.TRANSLATE: providers.Factory(TranslateControlPointCommand),
        }),
        TransformType.MESH: providers.Dict({
            ControlPointAction.NONE: providers.Factory(DefaultTransformCommand),
            ControlPointAction.TRANSLATE: providers.Factory(TranslateControlPointCommand),
        }),
        TransformType.RBF: providers.Dict({
            ControlPointAction.NONE: providers.Factory(DefaultTransformCommand),
            ControlPointAction.TRANSLATE: providers.Factory(TranslateControlPointCommand),
        }),
        TransformType.RIGID: providers.Dict({
            ControlPointAction.NONE: providers.Factory(DefaultTransformCommand),
            ControlPointAction.TRANSLATE: providers.Factory(TranslateControlPointCommand),
        })
    })

class Command:
   @inject
   def __init__(transform_type_to_command_action_map: Dict[TransformType, ControlPointActionCommandMapType] = Provide[Container.action_command_map]):
   """Infinite recursion occurs when constructor is invoked"""
        pass
Original exception was:
object address  : 000001FE1B806CE0
object refcount : 2
object type     : 00007FFE0495A730
object type name: RecursionError
object repr     : 
lost sys.stderr
Traceback (most recent call last):
  File "src/dependency_injector/providers.pxd", line 445, in dependency_injector.providers.__provide_keyword_args
  File "src/dependency_injector/providers.pxd", line 365, in dependency_injector.providers.__get_value
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 2689, in dependency_injector.providers.Factory._provide
  File "src/dependency_injector/providers.pxd", line 650, in dependency_injector.providers.__factory_call
  File "src/dependency_injector/providers.pxd", line 608, in dependency_injector.providers.__call
  File "src/dependency_injector/_cwiring.pyx", line 26, in dependency_injector._cwiring._get_sync_patched._patched
  File "src/dependency_injector/providers.pyx", line 811, in dependency_injector.providers.Dependency.__call__
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 3634, in dependency_injector.providers.Dict._provide
  File "src/dependency_injector/providers.pxd", line 445, in dependency_injector.providers.__provide_keyword_args
  File "src/dependency_injector/providers.pxd", line 365, in dependency_injector.providers.__get_value
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 3634, in dependency_injector.providers.Dict._provide
  File "src/dependency_injector/providers.pxd", line 445, in dependency_injector.providers.__provide_keyword_args
  File "src/dependency_injector/providers.pxd", line 365, in dependency_injector.providers.__get_value
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 2689, in dependency_injector.providers.Factory._provide
  File "src/dependency_injector/providers.pxd", line 650, in dependency_injector.providers.__factory_call
  File "src/dependency_injector/providers.pxd", line 608, in dependency_injector.providers.__call
  File "src/dependency_injector/_cwiring.pyx", line 26, in dependency_injector._cwiring._get_sync_patched._patched
  File "src/dependency_injector/providers.pyx", line 811, in dependency_injector.providers.Dependency.__call__
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 3634, in dependency_injector.providers.Dict._provide
  File "src/dependency_injector/providers.pxd", line 445, in dependency_injector.providers.__provide_keyword_args
  File "src/dependency_injector/providers.pxd", line 365, in dependency_injector.providers.__get_value
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 3634, in dependency_injector.providers.Dict._provide
  File "src/dependency_injector/providers.pxd", line 445, in dependency_injector.providers.__provide_keyword_args
  File "src/dependency_injector/providers.pxd", line 365, in dependency_injector.providers.__get_value
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 2689, in dependency_injector.providers.Factory._provide
  File "src/dependency_injector/providers.pxd", line 650, in dependency_injector.providers.__factory_call
  File "src/dependency_injector/providers.pxd", line 608, in dependency_injector.providers.__call
  File "src/dependency_injector/_cwiring.pyx", line 26, in dependency_injector._cwiring._get_sync_patched._patched
  File "src/dependency_injector/providers.pyx", line 811, in dependency_injector.providers.Dependency.__call__
  File "src/dependency_injector/providers.pyx", line 225, in dependency_injector.providers.Provider.__call__
  File "src/dependency_injector/providers.pyx", line 3634, in dependency_injector.providers.Dict._provide
  File "src/dependency_injector/providers.pxd", line 445, in dependency_injector.providers.__provide_keyword_args
  File "src/dependency_injector/providers.pxd", line 365, in dependency_injector.providers.__get_value
  ...
jamesra commented 4 hours ago

Version of dependency-injector is 4.42 Python 3.11.8