diff --git a/com.ibm.wala.cast.python.ml.test/source/com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java b/com.ibm.wala.cast.python.ml.test/source/com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java index 79f910cdd..55650af55 100644 --- a/com.ibm.wala.cast.python.ml.test/source/com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java +++ b/com.ibm.wala.cast.python.ml.test/source/com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java @@ -3609,6 +3609,18 @@ public void testClassMethod5() throws ClassHierarchyException, CancelException, expectedTensorParameterValueNumbers); } + @Test + public void testAbstractMethod() throws ClassHierarchyException, CancelException, IOException { + test("tf2_test_abstract_method.py", "D.f", 1, 1, 3); + test("tf2_test_abstract_method.py", "C.f", 1, 1, 3); + } + + @Test + public void testAbstractMethod2() throws ClassHierarchyException, CancelException, IOException { + test("tf2_test_abstract_method2.py", "D.f", 1, 1, 3); + test("tf2_test_abstract_method2.py", "C.f", 1, 1, 3); + } + private void test( String filename, String functionName, diff --git a/com.ibm.wala.cast.python.test/data/tf2_test_abstract_method.py b/com.ibm.wala.cast.python.test/data/tf2_test_abstract_method.py new file mode 100644 index 000000000..e6e58f55d --- /dev/null +++ b/com.ibm.wala.cast.python.test/data/tf2_test_abstract_method.py @@ -0,0 +1,20 @@ +# From https://blog.teclado.com/python-abc-abstract-base-classes/#introducing-abstract-classes. +import tensorflow as tf +from abc import ABC, abstractmethod + + +class C: + + def f(self, x): + assert isinstance(x, tf.Tensor) + + +class D(C): + + def f(self, x): + super(D, self).f(x) + + +c = D() +c.f(tf.constant(1)) + diff --git a/com.ibm.wala.cast.python.test/data/tf2_test_abstract_method2.py b/com.ibm.wala.cast.python.test/data/tf2_test_abstract_method2.py new file mode 100644 index 000000000..1c126fa26 --- /dev/null +++ b/com.ibm.wala.cast.python.test/data/tf2_test_abstract_method2.py @@ -0,0 +1,21 @@ +# From https://blog.teclado.com/python-abc-abstract-base-classes/#introducing-abstract-classes. +import tensorflow as tf +from abc import ABC, abstractmethod + + +class C(ABC): + + @abstractmethod + def f(self, x): + assert isinstance(x, tf.Tensor) + + +class D(C): + + def f(self, x): + super(D, self).f(x) + + +c = D() +c.f(tf.constant(1)) + diff --git a/com.ibm.wala.cast.python/data/flask.xml b/com.ibm.wala.cast.python/data/flask.xml index 2f02b8adf..2b96277a1 100644 --- a/com.ibm.wala.cast.python/data/flask.xml +++ b/com.ibm.wala.cast.python/data/flask.xml @@ -1,6 +1,6 @@ - + diff --git a/com.ibm.wala.cast.python/data/pytest.xml b/com.ibm.wala.cast.python/data/pytest.xml index f9ae7f2a7..b84a73c2e 100644 --- a/com.ibm.wala.cast.python/data/pytest.xml +++ b/com.ibm.wala.cast.python/data/pytest.xml @@ -1,6 +1,6 @@ - + diff --git a/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonInstanceMethodTrampolineTargetSelector.java b/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonInstanceMethodTrampolineTargetSelector.java index 90cb5fe97..2b9e85abe 100644 --- a/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonInstanceMethodTrampolineTargetSelector.java +++ b/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonInstanceMethodTrampolineTargetSelector.java @@ -49,7 +49,7 @@ public class PythonInstanceMethodTrampolineTargetSelector extends PythonMethodTrampolineTargetSelector { - private static final Logger logger = + private static final Logger LOGGER = Logger.getLogger(PythonInstanceMethodTrampolineTargetSelector.class.getName()); /** @@ -73,9 +73,9 @@ public class PythonInstanceMethodTrampolineTargetSelector private PythonAnalysisEngine engine; public PythonInstanceMethodTrampolineTargetSelector( - MethodTargetSelector base, PythonAnalysisEngine pythonAnalysisEngine) { + MethodTargetSelector base, PythonAnalysisEngine engine) { super(base); - this.engine = pythonAnalysisEngine; + this.engine = engine; } @Override @@ -88,7 +88,7 @@ protected boolean shouldProcess(CGNode caller, CallSiteReference site, IClass re @Override public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass receiver) { if (isCallable(receiver)) { - logger.fine("Encountered callable."); + LOGGER.fine("Encountered callable."); PythonInvokeInstruction call = this.getCall(caller, site); @@ -96,7 +96,7 @@ public IMethod getCalleeTarget(CGNode caller, CallSiteReference site, IClass rec receiver = getCallable(caller, receiver.getClassHierarchy(), call); if (receiver == null) return null; // not found. - else logger.fine("Substituting the receiver with one derived from a callable."); + else LOGGER.fine("Substituting the receiver with one derived from a callable."); } return super.getCalleeTarget(caller, site, receiver); @@ -243,7 +243,7 @@ private IClass getCallable(CGNode caller, IClassHierarchy cha, PythonInvokeInstr if (callable == null) { // try the workaround for https://github.com/wala/ML/issues/106. NOTE: We cannot verify // that the super class is tf.keras.Model due to https://github.com/wala/ML/issues/118. - logger.fine("Attempting callable workaround for https://github.com/wala/ML/issues/118."); + LOGGER.fine("Attempting callable workaround for https://github.com/wala/ML/issues/118."); callable = cha.lookupClass( @@ -251,7 +251,7 @@ private IClass getCallable(CGNode caller, IClassHierarchy cha, PythonInvokeInstr classLoaderReference, packageName, CALLABLE_METHOD_NAME_FOR_KERAS_MODELS)); if (callable != null) - logger.info("Applying callable workaround for https://github.com/wala/ML/issues/118."); + LOGGER.info("Applying callable workaround for https://github.com/wala/ML/issues/118."); } if (callable != null) return callable; @@ -315,7 +315,7 @@ private static AllocationSiteInNode getAllocationSiteInNode(ConstantKey const Object value = constantKey.getValue(); if (value == null) { - logger.warning("Can't extract AllocationSiteInNode from: " + constantKey + "."); + LOGGER.warning("Can't extract AllocationSiteInNode from: " + constantKey + "."); return null; } else throw new IllegalArgumentException( @@ -332,7 +332,7 @@ public PythonAnalysisEngine getEngine() { @Override protected Logger getLogger() { - return logger; + return LOGGER; } /** diff --git a/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonMethodTrampolineTargetSelector.java b/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonMethodTrampolineTargetSelector.java index fcfc539d1..64861d3d4 100644 --- a/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonMethodTrampolineTargetSelector.java +++ b/com.ibm.wala.cast.python/source/com/ibm/wala/cast/python/ipa/callgraph/PythonMethodTrampolineTargetSelector.java @@ -23,7 +23,6 @@ public abstract class PythonMethodTrampolineTargetSelector implements MethodT protected final Map, IMethod> codeBodies = HashMapFactory.make(); public PythonMethodTrampolineTargetSelector(MethodTargetSelector base) { - super(); this.base = base; }