File tree Expand file tree Collapse file tree 4 files changed +34
-4
lines changed
experimental/dataflow/typetracking
library-tests/ApiGraphs/py3 Expand file tree Collapse file tree 4 files changed +34
-4
lines changed Original file line number Diff line number Diff line change 1+ ---
2+ category : minorAnalysis
3+ ---
4+ * Change ` .getASubclass() ` on ` API::Node ` so it allows to follow subclasses even if the class has a class decorator.
Original file line number Diff line number Diff line change @@ -680,8 +680,16 @@ module API {
680680 or
681681 // Subclassing a node
682682 lbl = Label:: subclass ( ) and
683- exists ( DataFlow:: Node superclass | pred .flowsTo ( superclass ) |
684- ref .asExpr ( ) .( PY:: ClassExpr ) .getABase ( ) = superclass .asExpr ( )
683+ exists ( PY:: ClassExpr clsExpr , DataFlow:: Node superclass | pred .flowsTo ( superclass ) |
684+ clsExpr .getABase ( ) = superclass .asExpr ( ) and
685+ // Potentially a class decorator could do anything, but we assume they are
686+ // "benign" and let subclasses edges flow through anyway.
687+ // see example in https://github.com/django/django/blob/c2250cfb80e27cdf8d098428824da2800a18cadf/tests/auth_tests/test_views.py#L40-L46
688+ (
689+ ref .asExpr ( ) = clsExpr
690+ or
691+ ref .asExpr ( ) = clsExpr .getADecoratorCall ( )
692+ )
685693 )
686694 or
687695 // awaiting
Original file line number Diff line number Diff line change @@ -65,6 +65,9 @@ def foo():
6565 also_x = foo () # $ MISSING: tracked
6666 print (also_x ) # $ MISSING: tracked
6767
68+ # ------------------------------------------------------------------------------
69+ # Function decorator
70+ # ------------------------------------------------------------------------------
6871
6972def my_decorator (func ):
7073 # This part doesn't make any sense in a normal decorator, but just shows how we
@@ -135,7 +138,7 @@ def meth3(self):
135138 def track_self (self ): # $ tracked_self
136139 self .meth1 () # $ tracked_self
137140 super ().meth2 ()
138- super (Bar , self ).foo3 () # $ tracked_self
141+ super (Bar , self ).meth3 () # $ tracked_self
139142
140143# ------------------------------------------------------------------------------
141144# Tracking of attribute lookup after "long" import chain
Original file line number Diff line number Diff line change @@ -16,4 +16,19 @@ class IntMyView(View): #$ use=moduleImport("pflask").getMember("views").getMembe
1616 def my_internal_method (self ): #$ def=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getMember("my_internal_method")
1717 pass
1818
19- int_instance = IntMyView () #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getReturn()
19+ int_instance = IntMyView () #$ use=moduleImport("pflask").getMember("views").getMember("View").getASubclass().getReturn()
20+
21+ # ------------------------------------------------------------------------------
22+ # Class decorator
23+ # ------------------------------------------------------------------------------
24+
25+ def my_class_decorator (cls ):
26+ print ("dummy decorator" )
27+ return cls
28+
29+ @my_class_decorator
30+ class MyViewWithDecorator (View ): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass()
31+ pass
32+
33+ class SubclassFromDecorated (MyViewWithDecorator ): #$ use=moduleImport("flask").getMember("views").getMember("View").getASubclass().getASubclass()
34+ pass
You can’t perform that action at this time.
0 commit comments