1313
1414import python
1515
16- predicate understood_attribute ( Attribute attr , ClassObject cls , ClassObject attr_cls ) {
16+ predicate understood_attribute ( Attribute attr , ClassValue cls , ClassValue attr_cls ) {
1717 exists ( string name | attr .getName ( ) = name |
18- attr .getObject ( ) .refersTo ( _ , cls , _ ) and
19- cls .attributeRefersTo ( name , _ , attr_cls , _ )
18+ attr .getObject ( ) .pointsTo ( ) . getClass ( ) = cls and
19+ cls .attr ( name ) . getClass ( ) = attr_cls
2020 )
2121}
2222
2323/* Conservative estimate of whether attribute lookup has a side effect */
2424predicate side_effecting_attribute ( Attribute attr ) {
25- exists ( ClassObject cls , ClassObject attr_cls |
25+ exists ( ClassValue cls , ClassValue attr_cls |
2626 understood_attribute ( attr , cls , attr_cls ) and
2727 side_effecting_descriptor_type ( attr_cls )
2828 )
2929}
3030
3131predicate maybe_side_effecting_attribute ( Attribute attr ) {
32- not understood_attribute ( attr , _, _) and not attr .refersTo ( _)
32+ not understood_attribute ( attr , _, _) and not attr .pointsTo ( _)
3333 or
3434 side_effecting_attribute ( attr )
3535}
3636
37- predicate side_effecting_descriptor_type ( ClassObject descriptor ) {
37+ predicate side_effecting_descriptor_type ( ClassValue descriptor ) {
3838 descriptor .isDescriptorType ( ) and
3939 /*
4040 * Technically all descriptor gets have side effects,
4141 * but some are indicative of a missing call and
4242 * we want to treat them as having no effect.
4343 */
4444
45- not descriptor = thePyFunctionType ( ) and
46- not descriptor = theStaticMethodType ( ) and
47- not descriptor = theClassMethodType ( )
45+ not descriptor = ClassValue :: function ( ) and
46+ not descriptor = ClassValue :: staticmethod ( ) and
47+ not descriptor = ClassValue :: classmethod ( )
4848}
4949
5050/**
5151 * Side effecting binary operators are rare, so we assume they are not
5252 * side-effecting unless we know otherwise.
5353 */
5454predicate side_effecting_binary ( Expr b ) {
55- exists ( Expr sub , ClassObject cls , string method_name |
55+ exists ( Expr sub , ClassValue cls , string method_name |
5656 binary_operator_special_method ( b , sub , cls , method_name )
5757 or
5858 comparison_special_method ( b , sub , cls , method_name )
5959 |
6060 method_name = special_method ( ) and
6161 cls .hasAttribute ( method_name ) and
62- not exists ( ClassObject declaring |
62+ not exists ( ClassValue declaring |
6363 declaring .declaresAttribute ( method_name ) and
64- declaring = cls .getAnImproperSuperType ( ) and
64+ declaring = cls .getASuperType ( ) and
6565 declaring .isBuiltin ( ) and
66- not declaring = theObjectType ( )
66+ not declaring = ClassValue :: object ( )
6767 )
6868 )
6969}
7070
7171pragma [ nomagic]
7272private predicate binary_operator_special_method (
73- BinaryExpr b , Expr sub , ClassObject cls , string method_name
73+ BinaryExpr b , Expr sub , ClassValue cls , string method_name
7474) {
7575 method_name = special_method ( ) and
7676 sub = b .getLeft ( ) and
7777 method_name = b .getOp ( ) .getSpecialMethodName ( ) and
78- sub .refersTo ( _ , cls , _ )
78+ sub .pointsTo ( ) . getClass ( ) = cls
7979}
8080
8181pragma [ nomagic]
82- private predicate comparison_special_method ( Compare b , Expr sub , ClassObject cls , string method_name ) {
82+ private predicate comparison_special_method ( Compare b , Expr sub , ClassValue cls , string method_name ) {
8383 exists ( Cmpop op |
8484 b .compares ( sub , op , _) and
8585 method_name = op .getSpecialMethodName ( )
8686 ) and
87- sub .refersTo ( _ , cls , _ )
87+ sub .pointsTo ( ) . getClass ( ) = cls
8888}
8989
9090private string special_method ( ) {
@@ -102,9 +102,8 @@ predicate is_notebook(File f) {
102102/** Expression (statement) in a jupyter/ipython notebook */
103103predicate in_notebook ( Expr e ) { is_notebook ( e .getScope ( ) .( Module ) .getFile ( ) ) }
104104
105- FunctionObject assertRaises ( ) {
106- result =
107- ModuleObject:: named ( "unittest" ) .attr ( "TestCase" ) .( ClassObject ) .lookupAttribute ( "assertRaises" )
105+ FunctionValue assertRaises ( ) {
106+ result = Value:: named ( "unittest.TestCase" ) .( ClassValue ) .lookup ( "assertRaises" )
108107}
109108
110109/** Holds if expression `e` is in a `with` block that tests for exceptions being raised. */
@@ -124,6 +123,7 @@ predicate python2_print(Expr e) {
124123}
125124
126125predicate no_effect ( Expr e ) {
126+ // strings can be used as comments
127127 not e instanceof StrConst and
128128 not e .hasSideEffects ( ) and
129129 forall ( Expr sub | sub = e .getASubExpression * ( ) |
0 commit comments