Here are some examples of things that major other type checkers (mypy, pyright, pyrefly, ty) catch, but Basilisk does not.
-
Assigning a string to an integer variable.
-
Calling an integer.
nonsense = 123
nonsense()
-
Putting a string into a list of integers.
numbers: list[int] = []
numbers[0] = "three"
-
Using an integer key in a string-keyed dictionary.
config: dict[str, int] = {}
config[0] = 3
-
Passing a string to a method that expects an integer.
class C:
def square(self, x: int) -> int:
return x * x
c = C()
c.square("hello")
-
Calling len with the wrong number of arguments.
-
Missing a required integer return value.
def f() -> int:
print("hello")
-
Awaiting an integer.
async def main() -> None:
await 1
-
Unpacking an integer.
-
Assigning a nonexistent attribute on object.
obj = object()
obj.non_existing = 1
-
Indexing a list with a string.
numbers: list[int] = []
numbers["zero"] = 3
-
Storing a string in an integer-valued dictionary.
config: dict[str, int] = {}
config["retries"] = "three"
-
Unpacking too many values.
-
Unpacking too few values.
-
Iterating over an integer.
nonsense = 123
for x in nonsense:
pass
-
Passing an integer to json.loads.
import json
json.loads(5)
-
Passing a string to an integer keyword parameter.
def foo(x: int, y: int, *, z: int = 0) -> int:
return x * y * z
foo(1, 2, z="hello")
-
Using an object without context-manager methods in with.
class Manager:
...
with Manager():
pass
-
Indexing an object without __getitem__.
class NotSubscriptable:
...
a = NotSubscriptable()[0]
-
Assigning through a subscript without __setitem__.
class NoSetitem:
...
a = NoSetitem()
a[0] = 0
-
Assigning a string to an integer through a walrus expression.
-
Declaring an existing integer variable as a string.
-
Replacing a class with an integer.
-
Calling type without arguments.
-
Passing a string among integer variadic arguments.
def foo(*numbers: int) -> int:
return len(numbers)
foo(1, 2, 3, "hello", 5)
-
Passing a string among integer keyword arguments.
def foo(**numbers: int) -> int:
return len(numbers)
foo(a=1, b=2, c=3, d="hello", e=5)
-
Assigning to a read-only property.
class DontAssignToMe:
@property
def immutable(self):
...
DontAssignToMe().immutable = "changed"
-
Using yield from on an integer.
from typing import Generator
def generator() -> Generator[None]:
yield from 42
-
Using invalid string slice bounds.
def invalid_slice_bounds(s: str, start: float, end: float) -> str:
return s[start:end]
"foo"["bar":"baz"]
-
Using async with on an object without async context-manager methods.
class Manager:
...
async def main():
async with Manager():
pass
Here are some examples of things that major other type checkers (mypy, pyright, pyrefly, ty) catch, but Basilisk does not.
Assigning a string to an integer variable.
Calling an integer.
Putting a string into a list of integers.
Using an integer key in a string-keyed dictionary.
Passing a string to a method that expects an integer.
Calling
lenwith the wrong number of arguments.Missing a required integer return value.
Awaiting an integer.
Unpacking an integer.
Assigning a nonexistent attribute on
object.Indexing a list with a string.
Storing a string in an integer-valued dictionary.
Unpacking too many values.
Unpacking too few values.
Iterating over an integer.
Passing an integer to
json.loads.Passing a string to an integer keyword parameter.
Using an object without context-manager methods in
with.Indexing an object without
__getitem__.Assigning through a subscript without
__setitem__.Assigning a string to an integer through a walrus expression.
Declaring an existing integer variable as a string.
Replacing a class with an integer.
Calling
typewithout arguments.type()Passing a string among integer variadic arguments.
Passing a string among integer keyword arguments.
Assigning to a read-only property.
Using
yield fromon an integer.Using invalid string slice bounds.
Using
async withon an object without async context-manager methods.