ESBMC
Efficient SMT-based Context-Bounded Model Checker
Loading...
Searching...
No Matches
preprocessor.bound_method_dispatch Namespace Reference

Classes

class  _Dispatch
class  _Replace
class  _Rebound

Functions

 _scope_nodes (scope)
 _reads (node, name)
 _method_binding (node)
 _plain_function (node)
 _bound_value (binding)
 _is_call_of (node, name)
 _calls_of (stmt, name)
 _called_names (module)
 _return_types (module, bindings)
 _own_expressions (stmt)
 _failed_assert (message)
 _refuse_when_run (module, reads, method, message, replacements)
 dispatch_rebound_methods (module, names_bound_by, variables, next_id, module_name)

Variables

tuple _SIMPLE_BINDINGS

Detailed Description

Call the method a name was last bound to, when it is bound at several sites (#8467).

After `if c: f = o.inc` / `else: f = p.dec`, CPython's `f()` calls the
method of whichever binding ran last. Each binding stores its receiver and its
own number in a selector, and each call becomes an if/elif over the bindings
that calls only the method the selector names. The selector starts at 0, whose
arm raises NameError, or UnboundLocalError in a function, as calling an unbound
`f` does.

A call is rewritten only as the whole value of an expression statement, an
assignment or a return, or inside an assert, so each arm evaluates the
statement once, in order.
Any other read of the name fails an assertion just before the statement that
holds it, so a read in code that never runs does not stop verification (#9160).
A plain `def` of the name is one more binding, renamed and called like a
method. A decorated or async `def`, or a class, fails an assertion where it
would run. A binding of another form, or a binding from another scope, is
refused.

A name whose bindings are all simple statements of its scope's body is left
to the per-binding receiver capture instead: there each call is reached only
by the last binding above it in the source.

Function Documentation

◆ _bound_value()

preprocessor.bound_method_dispatch._bound_value ( binding)
protected

◆ _called_names()

preprocessor.bound_method_dispatch._called_names ( module)
protected
The names `module` calls as `name(...)`.

◆ _calls_of()

preprocessor.bound_method_dispatch._calls_of ( stmt,
name )
protected
The calls of `name` when `stmt` is `name(...)`, `targets = name(...)`,
`return name(...)` or an assert holding them, else [].

◆ _failed_assert()

preprocessor.bound_method_dispatch._failed_assert ( message)
protected

◆ _is_call_of()

preprocessor.bound_method_dispatch._is_call_of ( node,
name )
protected

◆ _method_binding()

preprocessor.bound_method_dispatch._method_binding ( node)
protected
`f = obj.attr` with `obj` a name or a call, the form a call of `f` is
rewritten for.

◆ _own_expressions()

preprocessor.bound_method_dispatch._own_expressions ( stmt)
protected
The expressions of `stmt` outside the statements it holds.

◆ _plain_function()

preprocessor.bound_method_dispatch._plain_function ( node)
protected

◆ _reads()

preprocessor.bound_method_dispatch._reads ( node,
name )
protected

◆ _refuse_when_run()

preprocessor.bound_method_dispatch._refuse_when_run ( module,
reads,
method,
message,
replacements )
protected
Make each statement holding one of `reads` fail an assertion first, so
only a read that may run makes the program fail, and read `method` there
so the statement still has a type.

◆ _return_types()

preprocessor.bound_method_dispatch._return_types ( module,
bindings )
protected
The return annotations of the `def` bindings and of the methods the
other bindings name in the classes of `module`, None standing for one
without an annotation; empty if no method is defined.

◆ _scope_nodes()

preprocessor.bound_method_dispatch._scope_nodes ( scope)
protected
The nodes of `scope` outside its nested scopes, which are yielded but not entered.

◆ dispatch_rebound_methods()

preprocessor.bound_method_dispatch.dispatch_rebound_methods ( module,
names_bound_by,
variables,
next_id,
module_name )
Give each name bound to methods at several sites of a scope, and called
somewhere, a selector set by its bindings and read by its calls. Return the
(scope, name) pairs left alone because their bindings run in source order,
the scope None standing for the module.

Variable Documentation

◆ _SIMPLE_BINDINGS

tuple preprocessor.bound_method_dispatch._SIMPLE_BINDINGS
protected
Initial value:
1= (ast.Assign, ast.AnnAssign, ast.AugAssign, ast.Import, ast.ImportFrom,
2 ast.FunctionDef, ast.ClassDef)