keep in mind that, apart from the money throw at js runtime interpreters by google and others, there is also the fact that python - as a language - is way more "dynamic" than javascript.
Even "simple" stuff like field access in python may refer to multiple dynamically-mapped method resolution.
Also, the ffi-bindings of python, while offering a way to extend it with libraries written in c/c++/fortran/... , limit how freely the internals can be changed (see the bug-by-bug compatibility work done for example by pypy, just to name an example, with some constraint that limit some optimizations)
> python - as a language - is way more "dynamic" than javascript
Very true, but IMO the existence of PyPy proves that this doesn't necessarily prevent a fast implementation. I think the reason for CPython's poor performance must be your other point:
> the ffi-bindings of python [...] limit how freely the internals can be changed
See Smalltalk, Self and Common Lisp for highly dynamic languages with good enough JIT, the first two having their research contributed to Hotspot and V8.
Yeah, I don't see how Python is fundamentally different from JavaScript as far as dynamicism goes. Sure Python has operator overloading, but JavaScript would implement those as regular methods. Pyrhon's init & new aren't any more convoluted than JavaScript's constructors. Python may support multiple inheritance but method and attribute resolution just uses the MRO which is no different than JavaScript's prototype chain.
Honestly I don't buy it.
Worse, this is one of the reason I prefer to do "minimal integration tests" instead of unit tests.
Take the example snippet of code
>>> The thing we want to avoid is opening a real file
and then the article goes and goes around patching stdlib stuff etc.
But instead I would suggest the real way to test it is to actually create the damn file, fill it with the "normal" (fixed) content and then run the damn test.
This is because after years of battling against mocks of various sort I find that creating the "real" resource is actually less finicky than monkeypatching stuff around.
Apart from that; yeah, sure the code should be refactored and the paths / resources moved out of the "pure logical" steps, but 1) this is an example and 2) this is the reality of most of the actual code, just 10x more complex and 100x more costly to refactor.
That works fine for files, but what if the integration is with a third party service for example?
You can create an actual mock networked service but it's much more work.
I think this is an example explaining what seems like a good practice for using mocks in python to me, the actual code in the post is barely "supporting cast".
If it's HTTP you can create the fixtures and serve them with a mock server. I'm a frontend dev, so backend APIs are like 3rd parties to me.
I use a browser extension for scraping actual backend responses, which downloads them with a filename convention the mock server understands. I mostly use it for development, but also for setting up screenshot tests. For example,
Both snippets suffer from being too limited. The first, as you point out, catches too many exceptions. But the second.... What happens if the email address is taken? That's hardly exceptional, but it's an exception that the caller has to handle. Your natural response might be to check if the email address is taken before calling register, but that's just a race condition now. So you really need a result-returning function, or to catch some (but probably not all) of the possible exceptions from the method.
The way I usually structure it is that the only exception would be some type of failure to connect. Any actual error thrown by the service comes back as a result.error, and any failure (like email address taken) comes back as result.fail. This way you can separate it into (1) connection problem, (2) backend error/bug/database offline/etc, (3) both of those are fine but the backend doesn't like the input.
I agree, this was just a sample code to show how usually imperative if / else / try / catch code is written. What is also possible is we catch the exception, log it and throw another one.
[1] https://en.wikipedia.org/wiki/Metasyntactic_variable#Italian
reply