Skip to content

Detect cycles on declaration #2

@numberoverzero

Description

@numberoverzero

This isn't very important because it'll fail loud and fast[0] but it might be nice to detect when provider dependencies form a cycle at declaration and raise a well-formed error instead of getting RecursionError on the first di.resolve("something-in-the-cycle") call.

For example, a complex graph could have a cycle that doesn't get pulled in until some heavy objects have already been loaded, which means the user partially creates some expensive resources and then crashes out[1].

Here's the repro[2]:

In [1]: from mainline import Di; di = Di()

In [2]: @di.f("rock")
   ...: @di.i("scissors")
   ...: def rock_factory(scissors):
   ...:     assert scissors == "Hi I'm scissors"
   ...:     return "Yep I'm rock"

In [3]: @di.f("scissors")
   ...: @di.i("paper")
   ...: def scissors_factory(paper):
   ...:     assert paper == "Whoa but I'm paper"
   ...:     return "Hi I'm scissors"

In [4]: @di.f("paper")
   ...: @di.i("rock")
   ...: def paper_factory(rock):
   ...:     assert rock == "Yep I'm rock"
   ...:     return "Whoa but I'm paper"

In [5]: try:
   ...:     di.resolve("rock")
   ...: except RecursionError:
   ...:     print("Ran out of turtles")
Ran out of turtles

[0] Someone would hit this situation what, once ever?
[1] As a highly contrived scenario, someone setting up aws resources doesn't know about the hundreds of other tools available and rolls their own.
[2] You probably didn't need this. Sorry.

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions