Limitations
Note: The following limitations apply to the current version of ESBMC-Python. Many are actively being addressed. Check the issue tracker for the latest status.
Control Flow and Loops
forloops support direct iteration overrange(), lists, strings, and generators (functions usingyieldand generator expressions). Iteration over tuples is not yet supported.- List comprehensions and generator expressions are supported. Set comprehensions are not supported (
Unsupported expression SetComp). Dictionary comprehensions are accepted by the parser but produce a dictionary whose subsequent key lookups raiseKeyError. - Iteration over dictionaries via
d.keys(),d.values(), andd.items()is supported insideforloops (see Supported Features — Dictionaries).
Lists
list.sort()does not support thekeyorreversekeyword arguments.sorted()does not support thekeyorreversekeyword arguments.
Sets
- Set methods
.add(),.discard(),.update(),.issubset(),.issuperset(), and.symmetric_difference()are not supported; use binary operators (-,&,|) instead. (.remove()happens to work because sets share the underlying list model.) frozensetis not supported.
Dictionaries
- Supported operations are: literals, subscript access/assignment,
del,in/not in, equality, iteration overkeys()/values()/items(),update(),get(),setdefault(),pop(), andpopitem(). Other methods (e.g.,copy()) are not yet implemented.
Tuples
- Tuple indexing requires constant indices; variable indices (e.g.,
t[i]whereiis a variable) are not supported. - Tuple iteration (
for item in my_tuple:) is not yet supported. - Tuple methods
.count()and.index()are not yet supported. - Tuple concatenation (
+) and repetition (*) are not yet supported. - Tuple slicing is not yet supported.
Complex Numbers
- The
complex()constructor accepts string arguments only when the string is a compile-time constant (e.g.,complex("1+2j")is folded by the frontend). Constructing from a runtime string fails with “Unhandled symbol format in string extraction”. cmath.polar()andcmath.rect()rely on theatan2model; results may differ from CPython in edge cases involving signed zeros and NaN.
Built-in Functions
min()andmax()support two-argument form and single-list form only; thekeyanddefaultkeyword arguments are not supported.any()andall()currently support only list literals as arguments.any()rejects other iterables with a parse-time error;all()may trigger a dereference failure on non-list iterables.sum()supportsintandfloatelement types only; the optionalstartargument is not supported.sorted()supportsint,float, andstrelement types only;keyandreversekeyword arguments are not supported.input()is modelled as a nondeterministic string with a maximum length of 256 characters (under-approximation).print()evaluates all arguments for side effects but does not produce actual output during verification.enumerate()supports standard usage patterns but may have limitations with complex nested iterables or advanced parameter combinations.
Lambda Expressions
- Return type inference is naive and defaults to
double. - Parameter types are assumed to be
doublefor simplicity.
F-Strings
- Complex expressions inside f-strings may have limited support.
- Only basic integer (
:d,:i) and float (:.Nf) format specs are supported; advanced format specs (e.g., string alignment:>10,:<5) are not. - Custom format specifications for user-defined types are not supported.
Union and Any Types
- Union types are resolved to the widest type among their members (
float > int > bool) at verification time; true union semantics are not maintained. - Union types containing types beyond basic primitives (
int,float,bool) may default to pointer types. - Type narrowing based on runtime type checks within Union-typed functions is not tracked.
Anytype inference only supports primitive return types (int,float,bool) and expressions evaluating to those types; string return values are not supported and will produce an error.- Other return types (
objects,arrays,null) are not supported forAny-typed functions; inference defaults todoublewhen no type can be determined.
Regular Expressions (re module)
- Only
re.match(),re.search(), andre.fullmatch()are supported. - Match objects do not expose group-capture methods (
.group(),.groups(),.span()). - Complex patterns beyond the explicitly supported constructs exhibit nondeterministic behavior.
- Not supported: lookahead/lookbehind assertions, backreferences, named groups, conditional patterns, Unicode property escapes.
Random Module
random.choice(),random.shuffle(),random.sample(),random.seed(), and other functions beyondrandom(),uniform(),randint(),getrandbits(), andrandrange()are not yet supported.
Collections Module
defaultdict: Only basic subscript access/assignment is supported. The__missing__hook, type-factory calls (e.g.,defaultdict(list)), and methods beyond__getitem__/__setitem__are not supported.Counter: Only__getitem__,__setitem__,values(), and truthiness are supported.most_common(),elements(),subtract(),update(), and arithmetic operators onCounterare not supported.OrderedDict,deque,namedtuple,ChainMap, and othercollectionstypes are not supported.
Datetime Module
- Only
datetime.datetime(year, month, day)is supported;date,time, andtimedeltaclasses are not. - Date arithmetic, string formatting (
strftime), and parsing (strptime,fromisoformat) are not supported.
Decimal Module
Decimal()supports construction from strings (e.g.,Decimal("10.5")), integers, and no arguments; other forms may not be handled.quantize(), rounding modes, and decimal context operations are not supported.
Heapq Module
heapify()is modelled as a no-op; the heap invariant is not enforced structurally.nlargest(),nsmallest(), andmerge()are not supported.
Time Module
time.time()is modelled as a monotonically increasing counter (increments by 1.0 per call), not real wall-clock time.- Other functions (
monotonic(),perf_counter(),strftime(),gmtime(),localtime(), etc.) are not supported.
NumPy Module
- Arrays are modelled as plain Python lists; array shapes, dtypes, multi-dimensional indexing (
a[i, j]), and broadcasting are not supported. - Most NumPy functions beyond those listed in Supported Features — NumPy are not available.
- Several math stub functions (e.g.,
np.sin,np.sqrt) return constant placeholder values rather than computing the real result; these are suitable only for type-inference testing, not numerical verification. numpy.linalg.detis a 2-scalar stub; general matrix operations are not supported.
Exception Handling
- Core built-in exception types are supported, but not all Python standard library exceptions; custom exception hierarchies with complex inheritance patterns may not be fully handled.
Class Attributes
- Type inference for class attributes requires values with clear, determinable types; complex expressions may require explicit type annotations.
Missing Return Detection
- Does not analyze return statements inside lambda expressions within the main function body.
Concurrency
Lockmodel is invisible to--deadlock-check(#4581).threading.Lock.acquirelowers to__ESBMC_atomic_begin / __ESBMC_assume / __ESBMC_atomic_end, mirroringpthread_mutex_lock_noassert. The deadlock checker only inspects the pthread mutex wait graph, so reverse-order lock acquisition between two Python threads is not reported as a deadlock — ESBMC explores all interleavings and reportsVERIFICATION SUCCESSFUL.Thread(args=(instance,))value-copies object arguments (#4583). When aThreadtarget receives a class instance with non-trivial attributes (e.g. athreading.Lock), the args-capture struct copies the descriptor by value and breaks attribute dereference inside the trampoline body. Workaround: share state via module-level globals instead of instance attributes passed throughargs=.- Symex does not interleave at Python module-global accesses (#4584).
--data-races-checkcorrectly flags W/W races on a module global, but symex’s per-statement scheduler does not insert interleaving points at function-internal reads/writes of these globals. A classic split read-modify-write race (tmp = counter; counter = tmp + 1from two threads) reportsVERIFICATION SUCCESSFULinstead of finding the schedule where both threads readcounter == 0before either writes. The C equivalent of the same program is correctly reported asVERIFICATION FAILED. - Thread shapes refused at parse time with explicit errors:
Threadsubclassing withrunoverride- Lambda or runtime-variable
target= - Positional argument forms (
Thread(f, (a, b))) args=bound to a variable instead of a tuple literal (Thread(target=f, args=payload))daemon=,name=,kwargs=,group=keyword argumentsThreadconstruction inside loops or comprehensionsThreadreassignment within the same scopeThreadas a class attribute (class C: t = Thread(...))targetdefined after the caller in source orderfrom threading import *
- Other
threadingprimitives are not supported:RLock,Semaphore,Condition,Event,Barrier,Timerare refused at parse time.queue.Queueis also unsupported and blocks the existingregression/python/concurrency_failexample. - The CPython Global Interpreter Lock (GIL) is not modelled (#4579). Translated programs execute under sequentially-consistent POSIX semantics rather than GIL-serialised bytecode execution, so the analysis over-approximates the set of feasible interleavings compared to actual CPython execution. This preserves safety but may produce spurious concurrency counterexamples.
Module System
- Built-in variable support is limited to
__name__;__file__,__doc__,__package__, and other built-ins are not yet supported.