From 236bc006e5947f594bc78ca56a025ed9e69d746b Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 14:44:11 -0400 Subject: [PATCH 01/14] Extract method. --- .../python/parser/PythonModuleParser.java | 66 +++++++++++++++++++ 1 file changed, 66 insertions(+) diff --git a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java index 75aedefb..71e66f3b 100644 --- a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java +++ b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java @@ -97,6 +97,35 @@ public CAstNode visitImport(Import imp) throws Exception { return super.visitImport(imp); } + private CAstNode createImportNode(List importNames, String moduleName) { + return createImportNode(importNames, moduleName, false); + } + + private CAstNode createImportNode( + List importNames, String moduleName, boolean useInitializationFile) { + moduleName = adjustModuleName(moduleName, useInitializationFile); + + String yuck = moduleName; + return Ast.makeNode( + CAstNode.BLOCK_STMT, + importNames.stream() + .map(alias::getInternalName) + .map( + n -> { + n = n.split("\\.")[0]; + + return Ast.makeNode( + CAstNode.DECL_STMT, + Ast.makeConstant(new CAstSymbolImpl(n, PythonCAstToIRTranslator.Any)), + Ast.makeNode( + CAstNode.PRIMITIVE, + Ast.makeConstant("import"), + Ast.makeConstant(yuck), + Ast.makeConstant(n))); + }) + .collect(Collectors.toList())); + } + /** * Returns an import {@link CAstNode} with the given {@link List} of {@link alias}s as import * names within the given module. @@ -193,6 +222,43 @@ public CAstNode visitImportFrom(ImportFrom importFrom) throws Exception { return super.visitImportFrom(importFrom); } + private String adjustModuleName(String moduleName) { + return adjustModuleName(moduleName, false); + } + + private String adjustModuleName(String moduleName, boolean useInitializationFile) { + List pythonPath = PythonModuleParser.this.getPythonPath(); + LOGGER.info("PYTHONPATH is: " + pythonPath); + + // If there is a PYTHONPATH specified. + if (pythonPath != null && !pythonPath.isEmpty()) { + // Adjust the module name per the PYTHONPATH. + Optional localModule = getLocalModule(moduleName); + + for (File pathEntry : pythonPath) { + Path modulePath = getPath(localModule); + + if (modulePath.startsWith(pathEntry.toPath())) { + // Found it. + Path scriptRelativePath = pathEntry.toPath().relativize(modulePath); + LOGGER.finer("Relativized path is: " + scriptRelativePath); + + // Remove the file extension if it exists. + moduleName = scriptRelativePath.toString().replaceFirst("\\.py$", ""); + + if (useInitializationFile) + // Use the beginning segment initialization file. + moduleName = moduleName.split("/")[0] + "/" + MODULE_INITIALIZATION_ENTITY_NAME; + + LOGGER.fine("Using module name: " + moduleName); + break; + } + } + } + + return moduleName; + } + /** * Adjust the given module name relative to the PYTHONPATH. * From f9a787f110c5a5d8d531fcc3a940e0eaa5a46a98 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 14:47:45 -0400 Subject: [PATCH 02/14] Fix refactoring. --- .../com/ibm/wala/cast/python/parser/PythonModuleParser.java | 4 ---- 1 file changed, 4 deletions(-) diff --git a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java index 71e66f3b..c984d130 100644 --- a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java +++ b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java @@ -222,10 +222,6 @@ public CAstNode visitImportFrom(ImportFrom importFrom) throws Exception { return super.visitImportFrom(importFrom); } - private String adjustModuleName(String moduleName) { - return adjustModuleName(moduleName, false); - } - private String adjustModuleName(String moduleName, boolean useInitializationFile) { List pythonPath = PythonModuleParser.this.getPythonPath(); LOGGER.info("PYTHONPATH is: " + pythonPath); From 9e9facfb367cfb2ad9eb474be1353fe58bd90966 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 14:55:18 -0400 Subject: [PATCH 03/14] Add javadoc. --- .../python/parser/PythonModuleParser.java | 26 +++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java index c984d130..548ba7c2 100644 --- a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java +++ b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java @@ -97,10 +97,29 @@ public CAstNode visitImport(Import imp) throws Exception { return super.visitImport(imp); } + /** + * Returns an import {@link CAstNode} with the given {@link List} of {@link alias}s as import + * names within the given module. + * + * @param importNames The names to import. + * @param moduleName The name of the containing module. + * @return Sn import {@link CAstNode} with the given {@link List} of {@link alias}s as import + * names within the given module. + */ private CAstNode createImportNode(List importNames, String moduleName) { return createImportNode(importNames, moduleName, false); } + /** + * Returns an import {@link CAstNode} with the given {@link List} of {@link alias}s as import + * names within the given module. + * + * @param importNames The names to import. + * @param moduleName The name of the containing module. + * @param useInitializationFile Whether to use the `__init__.py` file. + * @return Sn import {@link CAstNode} with the given {@link List} of {@link alias}s as import + * names within the given module. + */ private CAstNode createImportNode( List importNames, String moduleName, boolean useInitializationFile) { moduleName = adjustModuleName(moduleName, useInitializationFile); @@ -222,6 +241,13 @@ public CAstNode visitImportFrom(ImportFrom importFrom) throws Exception { return super.visitImportFrom(importFrom); } + /** + * Adjust the given module name relative to the PYTHONPATH. + * + * @param moduleName The module name to adjust. + * @param useInitializationFile Whether to use the `__init__.py` file. + * @return The given module's name potentially adjusted per the PYTHONPATH. + */ private String adjustModuleName(String moduleName, boolean useInitializationFile) { List pythonPath = PythonModuleParser.this.getPythonPath(); LOGGER.info("PYTHONPATH is: " + pythonPath); From dd62d54afb6e54539bf758098196455fd534f97b Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 16:38:09 -0400 Subject: [PATCH 04/14] Add tests. --- .../python/ml/test/TestTensorflow2Model.java | 12 +++++++++++ .../data/tf2_test_abstract_method.py | 20 ++++++++++++++++++ .../data/tf2_test_abstract_method2.py | 21 +++++++++++++++++++ 3 files changed, 53 insertions(+) create mode 100644 com.ibm.wala.cast.python.test/data/tf2_test_abstract_method.py create mode 100644 com.ibm.wala.cast.python.test/data/tf2_test_abstract_method2.py 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 79f910cd..fbbec66a 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 @@ -3608,6 +3608,18 @@ public void testClassMethod5() throws ClassHierarchyException, CancelException, expectedNumberOfTensorVariables, 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, 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 00000000..e6e58f55 --- /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 00000000..1c126fa2 --- /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)) + From 50d3e274031b312354681e65993580f531c0462c Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 17:02:13 -0400 Subject: [PATCH 05/14] Format. --- .../com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 fbbec66a..55650af5 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 @@ -3608,7 +3608,7 @@ public void testClassMethod5() throws ClassHierarchyException, CancelException, expectedNumberOfTensorVariables, expectedTensorParameterValueNumbers); } - + @Test public void testAbstractMethod() throws ClassHierarchyException, CancelException, IOException { test("tf2_test_abstract_method.py", "D.f", 1, 1, 3); From 8346d817b09119e48fa444c1dabad0e72ee50ddd Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 30 Apr 2024 13:22:58 -0400 Subject: [PATCH 06/14] Remove explicit super call. It's called implicitly. --- .../ipa/callgraph/PythonMethodTrampolineTargetSelector.java | 1 - 1 file changed, 1 deletion(-) 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 fcfc539d..64861d3d 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; } From b21be2a0c9e9e2276d0ed7b6784e5fd5e469638d Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 30 Apr 2024 13:26:53 -0400 Subject: [PATCH 07/14] Capitalize constant. --- ...thonInstanceMethodTrampolineTargetSelector.java | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) 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 90cb5fe9..ac5c5c9c 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()); /** @@ -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; } /** From e9f858c0679c2446cd28d9c29597f3ac20936e29 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 30 Apr 2024 13:53:14 -0400 Subject: [PATCH 08/14] Shorten name. --- .../PythonInstanceMethodTrampolineTargetSelector.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) 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 ac5c5c9c..2b9e85ab 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 @@ -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 From 5dd105f061987102e3740fc5a2bb252a43d060c5 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Tue, 30 Apr 2024 14:03:08 -0400 Subject: [PATCH 09/14] Fix comments. --- com.ibm.wala.cast.python/data/flask.xml | 2 +- com.ibm.wala.cast.python/data/pytest.xml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/com.ibm.wala.cast.python/data/flask.xml b/com.ibm.wala.cast.python/data/flask.xml index 2f02b8ad..2b96277a 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 f9ae7f2a..b84a73c2 100644 --- a/com.ibm.wala.cast.python/data/pytest.xml +++ b/com.ibm.wala.cast.python/data/pytest.xml @@ -1,6 +1,6 @@ - + From e51fe807adeb21ec7e98feea5ceeed815f1bf908 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 14:47:45 -0400 Subject: [PATCH 10/14] Fix refactoring. --- .../python/parser/PythonModuleParser.java | 47 ------------------- 1 file changed, 47 deletions(-) diff --git a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java index 548ba7c2..f46e449a 100644 --- a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java +++ b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java @@ -241,53 +241,6 @@ public CAstNode visitImportFrom(ImportFrom importFrom) throws Exception { return super.visitImportFrom(importFrom); } - /** - * Adjust the given module name relative to the PYTHONPATH. - * - * @param moduleName The module name to adjust. - * @param useInitializationFile Whether to use the `__init__.py` file. - * @return The given module's name potentially adjusted per the PYTHONPATH. - */ - private String adjustModuleName(String moduleName, boolean useInitializationFile) { - List pythonPath = PythonModuleParser.this.getPythonPath(); - LOGGER.info("PYTHONPATH is: " + pythonPath); - - // If there is a PYTHONPATH specified. - if (pythonPath != null && !pythonPath.isEmpty()) { - // Adjust the module name per the PYTHONPATH. - Optional localModule = getLocalModule(moduleName); - - for (File pathEntry : pythonPath) { - Path modulePath = getPath(localModule); - - if (modulePath.startsWith(pathEntry.toPath())) { - // Found it. - Path scriptRelativePath = pathEntry.toPath().relativize(modulePath); - LOGGER.finer("Relativized path is: " + scriptRelativePath); - - // Remove the file extension if it exists. - moduleName = scriptRelativePath.toString().replaceFirst("\\.py$", ""); - - if (useInitializationFile) - // Use the beginning segment initialization file. - moduleName = moduleName.split("/")[0] + "/" + MODULE_INITIALIZATION_ENTITY_NAME; - - LOGGER.fine("Using module name: " + moduleName); - break; - } - } - } - - return moduleName; - } - - /** - * Adjust the given module name relative to the PYTHONPATH. - * - * @param moduleName The module name to adjust. - * @param useInitializationFile Whether to use the `__init__.py` file. - * @return The given module's name potentially adjusted per the PYTHONPATH. - */ private String adjustModuleName(String moduleName, boolean useInitializationFile) { List pythonPath = PythonModuleParser.this.getPythonPath(); LOGGER.info("PYTHONPATH is: " + pythonPath); From 76d8d6a8cad013e4106b195a7a3c4d455e4d05a1 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 14:55:18 -0400 Subject: [PATCH 11/14] Add javadoc. --- .../python/parser/PythonModuleParser.java | 55 +++---------------- 1 file changed, 7 insertions(+), 48 deletions(-) diff --git a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java index f46e449a..75aedefb 100644 --- a/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java +++ b/com.ibm.wala.cast.python.jython3/source/com/ibm/wala/cast/python/parser/PythonModuleParser.java @@ -145,54 +145,6 @@ private CAstNode createImportNode( .collect(Collectors.toList())); } - /** - * Returns an import {@link CAstNode} with the given {@link List} of {@link alias}s as import - * names within the given module. - * - * @param importNames The names to import. - * @param moduleName The name of the containing module. - * @return Sn import {@link CAstNode} with the given {@link List} of {@link alias}s as import - * names within the given module. - */ - private CAstNode createImportNode(List importNames, String moduleName) { - return createImportNode(importNames, moduleName, false); - } - - /** - * Returns an import {@link CAstNode} with the given {@link List} of {@link alias}s as import - * names within the given module. - * - * @param importNames The names to import. - * @param moduleName The name of the containing module. - * @param useInitializationFile Whether to use the `__init__.py` file. - * @return Sn import {@link CAstNode} with the given {@link List} of {@link alias}s as import - * names within the given module. - */ - private CAstNode createImportNode( - List importNames, String moduleName, boolean useInitializationFile) { - moduleName = adjustModuleName(moduleName, useInitializationFile); - - String yuck = moduleName; - return Ast.makeNode( - CAstNode.BLOCK_STMT, - importNames.stream() - .map(alias::getInternalName) - .map( - n -> { - n = n.split("\\.")[0]; - - return Ast.makeNode( - CAstNode.DECL_STMT, - Ast.makeConstant(new CAstSymbolImpl(n, PythonCAstToIRTranslator.Any)), - Ast.makeNode( - CAstNode.PRIMITIVE, - Ast.makeConstant("import"), - Ast.makeConstant(yuck), - Ast.makeConstant(n))); - }) - .collect(Collectors.toList())); - } - /** * Returns the {@link Path} corresponding to the given {@link SourceModule}. If a {@link * SourceModule} is not supplied, an {@link IllegalStateException} is thrown. @@ -241,6 +193,13 @@ public CAstNode visitImportFrom(ImportFrom importFrom) throws Exception { return super.visitImportFrom(importFrom); } + /** + * Adjust the given module name relative to the PYTHONPATH. + * + * @param moduleName The module name to adjust. + * @param useInitializationFile Whether to use the `__init__.py` file. + * @return The given module's name potentially adjusted per the PYTHONPATH. + */ private String adjustModuleName(String moduleName, boolean useInitializationFile) { List pythonPath = PythonModuleParser.this.getPythonPath(); LOGGER.info("PYTHONPATH is: " + pythonPath); From c09979e6046386c5fb0c4e7b3c0d628e6982f2d1 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 16:38:09 -0400 Subject: [PATCH 12/14] Add tests. --- .../cast/python/ml/test/TestTensorflow2Model.java | 12 ++++++++++++ 1 file changed, 12 insertions(+) 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 55650af5..00c113b2 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 @@ -3615,6 +3615,18 @@ public void testAbstractMethod() throws ClassHierarchyException, CancelException 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); + } + + @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); From 4d0fecfbb533253488f5ecf220bdd5f111e5f0a2 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 25 Apr 2024 17:02:13 -0400 Subject: [PATCH 13/14] Format. --- .../com/ibm/wala/cast/python/ml/test/TestTensorflow2Model.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) 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 00c113b2..0144c5ac 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 @@ -3620,7 +3620,7 @@ public void testAbstractMethod2() throws ClassHierarchyException, CancelExceptio test("tf2_test_abstract_method2.py", "D.f", 1, 1, 3); test("tf2_test_abstract_method2.py", "C.f", 1, 1, 3); } - + @Test public void testAbstractMethod() throws ClassHierarchyException, CancelException, IOException { test("tf2_test_abstract_method.py", "D.f", 1, 1, 3); From 6edcf3a1a9f13cbf2bdfeb47d8aad26ad2d43123 Mon Sep 17 00:00:00 2001 From: Raffi Khatchadourian Date: Thu, 2 May 2024 12:02:04 -0400 Subject: [PATCH 14/14] Remove duplicate tests. Bad cherry-pick? --- .../cast/python/ml/test/TestTensorflow2Model.java | 12 ------------ 1 file changed, 12 deletions(-) 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 0144c5ac..55650af5 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 @@ -3621,18 +3621,6 @@ public void testAbstractMethod2() throws ClassHierarchyException, CancelExceptio test("tf2_test_abstract_method2.py", "C.f", 1, 1, 3); } - @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,