Hello everyone, I'm starting a new blog where I'm trying to mix my passion and experience for safe programming in critical contexts, and my (over)use of Python, and other techs that are used in... less safe contexts. The "investment hypothesis" if you will is that pieces of tech used daily in critical systems could see a broader use if they stopped being hidden behind mumbo jumbo, bad UX, and general lack of consideration for the common developper. In this blog I'll try to go and discuss fuzzing, contracts, why not some amount of lightweight proofing... and to mix them with application that are hopefully fun and nice to study.
This first post is about counting sheeps, with a design-by-contract twist.
Let me know what you guys think, it's my first blog at all, so I'm a taker for all matters of feedback, as long as it comes from the heart that is ;)
One of the most 'nice' thing about contract systems is automating blame checking in higher-order code. They handle the lambda/method param wrapping and blame direction assignment for you, which is annoying to do via manual assertions.
I didn't see a link to DBC, is that in there? Or some other use of contracts that is hard via just asserts, like in test amplification?
We are always looking for ways to improve our Python codebase, and I hadn't expected to see modern investment here!
[deleted]
Ah yeah unfortunate, afaict it does not (yet?) support lambdas, which is where imo this starts supporting flows that are hard via manual asserts
I was hoping something like a more modern https://dl.acm.org/doi/10.1145/581478.581484
Cool stuff! Might be fun to integrate with a type validation library like Pydantic or Msgspec to provide in-line coercion/assertion.
What is the performance hit like? I could see these getting pretty expensive (but correctness is invaluable). Seems like it would be great for something like aws lambda in python where you have already decided performance isn't an utmost priority and scrutability is difficult, so any correctness you can bolt on is a boon.
Value types with contracts should be the focus here. Specifically, the story should not be of type str, but rather of type story that is only allowed to exist when it meets certain conditions.
This approach ensures only a single point of validation, a lower mental overhead as you are certain it is valid everywhere, and fast failure when it's not - by contract, even.
There are a few places where this concept is discussed, but the most concise phrase is: “Parse, don’t validate.”
Zod (TypeScript) is a good example of a library like this, as it is oriented around types. I’m not sure if Python has something similar.
However, overvalidation can make your code overly verbose, which is something I’ve fallen into before. Use it sparingly.
Python shouldn't need special lib to design by contract, `assert cond, "reason"` and `if __debug__` work very well for that.
Unfortunately, people don't know they are made to be stripped in prod with `-OO` so that the perf hit is zero. This means you can never be sure a 3rd party lib you depend on is not using an assert somewhere for a very important check you are going to disable.
https://www.bitecode.dev/p/the-best-python-feature-you-canno...
This isn't meant as a dig, I'm genuinely curious: how is this not simply imposing static typing in python?
The pre and post conditions are checked at runtime. Also, typically static type sytems are not expressive enough to statically check more than relatively basic pre and post conditions, even in languages with advanced type systems like Haskell or Scala.
You can have preconditions that check stuff not related to typing (e.g: check that a connection is open before calling the function).
It kind of is, but pre/post-conditions can be more than that. Also, I'd consider it bad form to have type signatures (which they have) and runtime checking the same types. The whole point of having static typing is decreasing the need for the latter, but you have to actually run a type checker for it to be useful.
Can this be disabled at runtime?
At this point just use Java instead.
The assurance you get from the examples in the article are pretty basic, but there are contracts you’ll have a lot of trouble encoding in the type system, like “arguments are integers in ascending order.”