I'd avoid monkey patching, it can confuse the programmer as to which module is being used. In a small program it's not a big deal but in large systems it can become an issue.
It makes sense in certain situations. For example, if you're using non-blocking i/o with an event loop (using gevent or similar) then as soon as you have one blocking operation, performance suffers dramatically.
Monkeypatching gevent's socket globally allows you to use libraries and drivers like pymongo off the shelf, and they will be non-blocking by default.
While true, this can hardly be considered good engineering. The more complexity in your system, the more likely it is to break. The question is: do you want to take the productivity hit today and fix the socket libraries, or do you want to fix it at some time in the future when you finally realize your code/test/release cycle is twice as slow as your competitors'?
(I've worked on a lot of code that took the second trade-off. The result is almost always a full rewrite. Maintain your codebase or it goes out of control really fast.)
I agree that before monkeypatching, a team should weigh their options. But for many projects, "fixing the socket libraries" could be a lot of work, or not an option at all.
In the example I gave, you'd have to rewrite whatever database drivers you're using, or at least hack them to work in a non-blocking fashion. That could have just as much development cost as monkeypatching.
zodiac is an attempt to address the problems that make monkeypatching such a risky, unpredictable option, by making patches smaller and therefore using more system code. Hopefully, for situations where monkeypatching is necessary, I can make it cleaner and more maintainable.
Easy being defined as "usable by easily confused programmers who don't understand it or the trade offs."
Nice one. That's a deep concept. Programmers and projects generally get themselves into trouble because of a misunderstanding of the trade-offs.
It's rookie programmers who are enamored with a new bit of tech, but don't understand the downsides. It's managers who have an inaccurate estimation of risks and so lack the confidence to make decisive moves.
This is why experience can be so valuable in the programming field. This is the only way to learn about the cost/benefit trade offs.
Maybe "facile" is a better term than "easy" for this, though.
11 comments
[ 4.7 ms ] story [ 34.4 ms ] threadhttp://www.voidspace.org.uk/python/mock/mock.html
Monkeypatching gevent's socket globally allows you to use libraries and drivers like pymongo off the shelf, and they will be non-blocking by default.
Not to mention that if you are using a c-extension monkey patching won't help much.
(I've worked on a lot of code that took the second trade-off. The result is almost always a full rewrite. Maintain your codebase or it goes out of control really fast.)
In the example I gave, you'd have to rewrite whatever database drivers you're using, or at least hack them to work in a non-blocking fashion. That could have just as much development cost as monkeypatching.
zodiac is an attempt to address the problems that make monkeypatching such a risky, unpredictable option, by making patches smaller and therefore using more system code. Hopefully, for situations where monkeypatching is necessary, I can make it cleaner and more maintainable.
Nice one. That's a deep concept. Programmers and projects generally get themselves into trouble because of a misunderstanding of the trade-offs.
It's rookie programmers who are enamored with a new bit of tech, but don't understand the downsides. It's managers who have an inaccurate estimation of risks and so lack the confidence to make decisive moves.
This is why experience can be so valuable in the programming field. This is the only way to learn about the cost/benefit trade offs.
Maybe "facile" is a better term than "easy" for this, though.
with patch('path.to.object') as my_mock: my_mock.method.return_value = ...
also you can patch a module/class with a function.