def test_member_acces_after_possible_assignment(self): tree = ast.parse( textwrap.dedent( """ def f(): if 0: x = 2 x.y """ ) ) expectedResult = set(['x']) self.assertEqual( expectedResult, PyAstUninstantiatedVariablesAnalysis. collectPossiblyUninitializedLocalVariables(tree) ) self.assertEqual( set(), PyAstFreeVariableAnalyses.getFreeVariables(tree) ) self.assertEqual( set(), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree) )
def test_freeVariablesMemberAccessChain_onFunctionDefNode(self): tree1 = ast.parse( textwrap.dedent(""" def g(arg): if arg < 0: return x + arg return x * h(arg - 1, g) """)) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains( tree1) self.assertEqual(set([('h', ), ('x', )]), res) tree2 = PyAstUtil.functionDefOrLambdaAtLineNumber(tree1, 2) self.assertEqual( set([('h', ), ('x', )]), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains( tree2, False))
def test_call_and_then_member_chain(self): tree = ast.parse( textwrap.dedent(""" def f(): return g(1).__str__() """)) self.assertEqual( set([('g', )]), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree))
def test_freeVariableMemberAccessChains_1(self): tree = ast.parse( textwrap.dedent(""" def f(): x x = 2 def f(x): x.y z.w.q """)) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree) self.assertEqual(set([('z', 'w', 'q')]), res)
def test_call_and_then_member_chain(self): tree = ast.parse( textwrap.dedent( """ def f(): return g(1).__str__() """ ) ) self.assertEqual( set([('g',)]), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree) )
def test_freeVariableMemberAccessChains_2(self): tree = ast.parse( textwrap.dedent(""" def f(): y = 2 class C: def g(self, arg): x.y.z + y + arg x = 2 C.f """)) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree) self.assertEqual(set([('C', 'f')]), res)
def test_freeVariablesMemberAccessChain_onFunctionDefNode(self): tree1 = ast.parse( textwrap.dedent( """ def g(arg): if arg < 0: return x + arg return x * h(arg - 1, g) """ ) ) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree1) self.assertEqual( set([('h',), ('x',)]), res ) tree2 = PyAstUtil.functionDefOrLambdaAtLineNumber(tree1, 2) self.assertEqual( set([('h',), ('x',)]), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree2, False) )
def test_member_acces_after_possible_assignment(self): tree = ast.parse( textwrap.dedent(""" def f(): if 0: x = 2 x.y """)) expectedResult = set(['x']) self.assertEqual( expectedResult, PyAstUninstantiatedVariablesAnalysis. collectPossiblyUninitializedLocalVariables(tree)) self.assertEqual(set(), PyAstFreeVariableAnalyses.getFreeVariables(tree)) self.assertEqual( set(), PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree))
def test_freeVariableMemberAccessChains_1(self): tree = ast.parse( textwrap.dedent( """ def f(): x x = 2 def f(x): x.y z.w.q """ ) ) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree) self.assertEqual( set([('z', 'w', 'q')]), res )
def _freeOrUninitializedMemberAccesChains(self, pyAst): # ATz: just added 'False' as a 2nd argument, but we may need to check # that whenever pyAst is a FunctionDef node, its context is not a class # (i.e., it is not an instance method). In that case, we need to pass # 'True' as the 2nd argument. freeVariableMemberAccessChains = \ PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains( pyAst, isClassContext=False ) possiblyUninitializedVariables = \ PyAstUninstantiatedVariablesAnalysis\ .collectPossiblyUninitializedLocalVariablesInScope( pyAst ) possiblyUninitializedVariablesAsChains = [ (val,) for val in possiblyUninitializedVariables] return freeVariableMemberAccessChains.union( possiblyUninitializedVariablesAsChains)
def test_freeVariableMemberAccessChains_2(self): tree = ast.parse( textwrap.dedent( """ def f(): y = 2 class C: def g(self, arg): x.y.z + y + arg x = 2 C.f """ ) ) res = PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains(tree) self.assertEqual( set([('C', 'f')]), res )
def _freeOrUninitializedMemberAccesChains(self, pyAst): # ATz: just added 'False' as a 2nd argument, but we may need to check # that whenever pyAst is a FunctionDef node, its context is not a class # (i.e., it is not an instance method). In that case, we need to pass # 'True' as the 2nd argument. freeVariableMemberAccessChains = \ PyAstFreeVariableAnalyses.getFreeVariableMemberAccessChains( pyAst, isClassContext=False ) possiblyUninitializedVariables = \ PyAstUninstantiatedVariablesAnalysis\ .collectPossiblyUninitializedLocalVariablesInScope( pyAst ) possiblyUninitializedVariablesAsChains = [ (val, ) for val in possiblyUninitializedVariables ] return freeVariableMemberAccessChains.union( possiblyUninitializedVariablesAsChains)