If you run a type checker like ty or pyright they're not decorative — you'll get clear diagnostics for that particular example [1], and any other type errors you might have. You can set up CI so that e.g. blocks PRs from being merged, just like any other test failure.
If you mean types not being checked at runtime, the consensus is that most users don't want to pay the cost of the checks every time the program is run. It's more cost-effective to do those checks at development/test/CI time using a type checker, as described above. But if you _do_ want that, you can opt in to that using something like beartype [2].
[1] https://play.ty.dev/905db656-e271-4a3a-b27d-18a4dd45f5da
int x = "thing"
is perfectly valid. It means reserve a spot for a 32 bit int and then shove the pointer to the string "thing" at the address of x. It will do the wrong thing and also overflow memory but you could generate code for it. The type checker is what stops you. It's the same in Python, if you make type checking a build breaker then the annotations mean something. Types aren't checked at runtime but C doesn't check them either.I'd be surprised if a compiler with -Wall -Werror accepts to compile this.
Trying to cast back the int to a char* might work if the pointers are the same size as int on the target platform, but it's actually Undefined Behaviour IIRC.
No type system will allow for the dynamism that Python supports. It's not a question of how you annotate types, it's about how you resolve types.
My teammates who were writing untyped Python previously don't seem to mind it. It's a good addition to the ecosystem!
From https://news.ycombinator.com/item?id=14246095 (2017) :
> PyContracts supports runtime type-checking and value constraints/assertions (as @contract decorators, annotations, and docstrings).
> Unfortunately, there's yet no unifying syntax between PyContracts and the newer python type annotations which MyPy checks at compile-type.
Or beartype.
Pycontracts has: https://andreacensi.github.io/contracts/ :
@contract
def my_function(a : 'int,>0', b : 'list[N],N>0') -> 'list[N]':
@contract(image='array[HxWx3](uint8),H>10,W>10')
def recolor(image):
For icontract, there's icontract-hyothesis.parquery/icontract: https://github.com/Parquery/icontract :
> There exist a couple of contract libraries. However, at the time of this writing (September 2018), they all required the programmer either to learn a new syntax (PyContracts) or to write redundant condition descriptions ( e.g., contracts, covenant, deal, dpcontracts, pyadbc and pcd).
@icontract.require(lambda x: x > 3, "x must not be small")
def some_func(x: int, y: int = 5) -> None:
icontract with numpy array types: @icontract.require(lambda arr: isinstance(arr, np.ndarray))
@icontract.require(lambda arr: arr.shape == (3, 3))
@icontract.require(lambda arr: np.all(arr >= 0), "All elements must be non-negative")
def process_matrix(arr: np.ndarray):
return np.sum(arr)
invalid_matrix = np.array([[1, -2, 3], [4, 5, 6], [7, 8, 9]])
process_matrix(invalid_matrix)
# Raises icontract.ViolationErrorLooks like I will be converting to pyright. No disrespect to the astral team, I think they have been pretty careful to note that ty is still in early days. I'm sure I will return to it at some point - uv and ruff are excellent.
persedes•4h ago
(glad they include ty now)