Open dseomn opened 2 years ago
There seems to be two places where we get infinite recursion.
The instance wasn't being passed correctly, it is easy to fix by specifying the parameter name like instance=instance
.
The recursion here tries to mock all attributes recursively(if there's a class or object). So in this chain of calls if there's a cycle we end up caught in an infinite recursion.
Possible solutions:
Let me know if anyone has a better solution in mind, I'd be happy to submit a PR implementing the solution that's chosen.
cc: @mariocj89
Right, because "foo.bar.foo.bar.foo" is not the same as "foo.bar.foo" Which I honestly find surprising. Is that something we should fix? Otherwise, this is really infinite and there is no way for seal to handle it, as "foo.bar.foo" is genuinely a different mock from "foo.bar.foo.bar.foo".
If we could fix that we could then have seal check if a mock has been already marked with seal and if so skip it.
Otherwise, I think the only alternative is indeed to just set a limit (at which point we might just go with the current limit by the interpreter). We could capture RecursionError and provide a nicer message.
Otherwise, this is really infinite and there is no way for seal to handle it, as "foo.bar.foo" is genuinely a different mock from "foo.bar.foo.bar.foo".
Is there a technical reason seal couldn't handle it if it really is infinite? Assuming there's some lazy evaluation somewhere, could seal set an attribute on a parent somewhere that's read during lazy evaluation to call seal on a newly evaluated child at that point, instead of seal trying to evaluate all the children right away?
Assuming there's some lazy evaluation somewhere, could seal set an attribute on a parent somewhere that's read during lazy evaluation to call seal on a newly evaluated child at that point
That's indeed a great idea. To check if a mock is sealed, we check itself and its parents. When we set something as sealed we just need to do it in one single place.
Bug report
This code seems to cause infinite recursion in
unittest.mock.seal
:Your environment