# Licensed under the LGPL: https://www.gnu.org/licenses/old-licenses/lgpl-2.1.en.html
# For details: https://github.com/pylint-dev/astroid/blob/main/LICENSE
# Copyright (c) https://github.com/pylint-dev/astroid/blob/main/CONTRIBUTORS.txt

"""Tests for the astroid builder and rebuilder module."""

import collections
import importlib
import os
import pathlib
import py_compile
import socket
import sys
import tempfile
import textwrap
import unittest
import unittest.mock

import pytest

from astroid import Instance, builder, nodes, test_utils, util
from astroid.const import IS_PYPY, PY38, PY39_PLUS, PYPY_7_3_11_PLUS
from astroid.exceptions import (
    AstroidBuildingError,
    AstroidSyntaxError,
    AttributeInferenceError,
    InferenceError,
    StatementMissing,
)
from astroid.nodes.scoped_nodes import Module

from . import resources


class FromToLineNoTest(unittest.TestCase):
    def setUp(self) -> None:
        self.astroid = resources.build_file("data/format.py")

    def test_callfunc_lineno(self) -> None:
        stmts = self.astroid.body
        # on line 4:
        #    function('aeozrijz\
        #    earzer', hop)
        discard = stmts[0]
        self.assertIsInstance(discard, nodes.Expr)
        self.assertEqual(discard.fromlineno, 4)
        self.assertEqual(discard.tolineno, 5)
        callfunc = discard.value
        self.assertIsInstance(callfunc, nodes.Call)
        self.assertEqual(callfunc.fromlineno, 4)
        self.assertEqual(callfunc.tolineno, 5)
        name = callfunc.func
        self.assertIsInstance(name, nodes.Name)
        self.assertEqual(name.fromlineno, 4)
        self.assertEqual(name.tolineno, 4)
        strarg = callfunc.args[0]
        self.assertIsInstance(strarg, nodes.Const)
        if IS_PYPY:
            self.assertEqual(strarg.fromlineno, 4)
            if not PY39_PLUS:
                self.assertEqual(strarg.tolineno, 4)
            else:
                self.assertEqual(strarg.tolineno, 5)
        else:
            self.assertEqual(strarg.fromlineno, 4)
            self.assertEqual(strarg.tolineno, 5)
        namearg = callfunc.args[1]
        self.assertIsInstance(namearg, nodes.Name)
        self.assertEqual(namearg.fromlineno, 5)
        self.assertEqual(namearg.tolineno, 5)
        # on line 10:
        #    fonction(1,
        #             2,
        #             3,
        #             4)
        discard = stmts[2]
        self.assertIsInstance(discard, nodes.Expr)
        self.assertEqual(discard.fromlineno, 10)
        self.assertEqual(discard.tolineno, 13)
        callfunc = discard.value
        self.assertIsInstance(callfunc, nodes.Call)
        self.assertEqual(callfunc.fromlineno, 10)
        self.assertEqual(callfunc.tolineno, 13)
        name = callfunc.func
        self.assertIsInstance(name, nodes.Name)
        self.assertEqual(name.fromlineno, 10)
        self.assertEqual(name.tolineno, 10)
        for i, arg in enumerate(callfunc.args):
            self.assertIsInstance(arg, nodes.Const)
            self.assertEqual(arg.fromlineno, 10 + i)
            self.assertEqual(arg.tolineno, 10 + i)

    def test_function_lineno(self) -> None:
        stmts = self.astroid.body
        # on line 15:
        #    def definition(a,
        #                   b,
        #                   c):
        #        return a + b + c
        function = stmts[3]
        self.assertIsInstance(function, nodes.FunctionDef)
        self.assertEqual(function.fromlineno, 15)
        self.assertEqual(function.tolineno, 18)
        return_ = function.body[0]
        self.assertIsInstance(return_, nodes.Return)
        self.assertEqual(return_.fromlineno, 18)
        self.assertEqual(return_.tolineno, 18)

    def test_decorated_function_lineno(self) -> None:
        astroid = builder.parse(
            """
            @decorator
            def function(
                arg):
                print (arg)
            """,
            __name__,
        )
        function = astroid["function"]
        # XXX discussable, but that's what is expected by pylint right now, similar to ClassDef
        self.assertEqual(function.fromlineno, 3)
        self.assertEqual(function.tolineno, 5)
        self.assertEqual(function.decorators.fromlineno, 2)
        self.assertEqual(function.decorators.tolineno, 2)

    @staticmethod
    def test_decorated_class_lineno() -> None:
        code = textwrap.dedent(
            """
        class A:  # L2
            ...

        @decorator
        class B:  # L6
            ...

        @deco1
        @deco2(
            var=42
        )
        class C:  # L13
            ...
        """
        )

        ast_module: nodes.Module = builder.parse(code)  # type: ignore[assignment]

        a = ast_module.body[0]
        assert isinstance(a, nodes.ClassDef)
        assert a.fromlineno == 2
        assert a.tolineno == 3

        b = ast_module.body[1]
        assert isinstance(b, nodes.ClassDef)
        assert b.fromlineno == 6
        assert b.tolineno == 7

        c = ast_module.body[2]
        assert isinstance(c, nodes.ClassDef)
        if IS_PYPY and PY38 and not PYPY_7_3_11_PLUS:
            # Not perfect, but best we can do for PyPy 3.8 (< v7.3.11).
            # Can't detect closing bracket on new line.
            assert c.fromlineno == 12
        else:
            assert c.fromlineno == 13
        assert c.tolineno == 14

    @staticmethod
    def test_class_with_docstring() -> None:
        """Test class nodes which only have docstrings."""
        code = textwrap.dedent(
            '''\
        class A:
            """My docstring"""
            var = 1

        class B:
            """My docstring"""

        class C:
            """My docstring
            is long."""

        class D:
            """My docstring
            is long.
            """

        class E:
            ...
        '''
        )

        ast_module = builder.parse(code)

        a = ast_module.body[0]
        assert isinstance(a, nodes.ClassDef)
        assert a.fromlineno == 1
        assert a.tolineno == 3

        b = ast_module.body[1]
        assert isinstance(b, nodes.ClassDef)
        assert b.fromlineno == 5
        assert b.tolineno == 6

        c = ast_module.body[2]
        assert isinstance(c, nodes.ClassDef)
        assert c.fromlineno == 8
        assert c.tolineno == 10

        d = ast_module.body[3]
        assert isinstance(d, nodes.ClassDef)
        assert d.fromlineno == 12
        assert d.tolineno == 15

        e = ast_module.body[4]
        assert isinstance(d, nodes.ClassDef)
        assert e.fromlineno == 17
        assert e.tolineno == 18

    @staticmethod
    def test_function_with_docstring() -> None:
        """Test function defintions with only docstrings."""
        code = textwrap.dedent(
            '''\
        def a():
            """My docstring"""
            var = 1

        def b():
            """My docstring"""

        def c():
            """My docstring
            is long."""

        def d():
            """My docstring
            is long.
            """

        def e(a, b):
            """My docstring
            is long.
            """
        '''
        )

        ast_module = builder.parse(code)

        a = ast_module.body[0]
        assert isinstance(a, nodes.FunctionDef)
        assert a.fromlineno == 1
        assert a.tolineno == 3

        b = ast_module.body[1]
        assert isinstance(b, nodes.FunctionDef)
        assert b.fromlineno == 5
        assert b.tolineno == 6

        c = ast_module.body[2]
        assert isinstance(c, nodes.FunctionDef)
        assert c.fromlineno == 8
        assert c.tolineno == 10

        d = ast_module.body[3]
        assert isinstance(d, nodes.FunctionDef)
        assert d.fromlineno == 12
        assert d.tolineno == 15

        e = ast_module.body[4]
        assert isinstance(e, nodes.FunctionDef)
        assert e.fromlineno == 17
        assert e.tolineno == 20

    def test_class_lineno(self) -> None:
        stmts = self.astroid.body
        # on line 20:
        #    class debile(dict,
        #                 object):
        #       pass
        class_ = stmts[4]
        self.assertIsInstance(class_, nodes.ClassDef)
        self.assertEqual(class_.fromlineno, 20)
        self.assertEqual(class_.tolineno, 22)
        self.assertEqual(class_.blockstart_tolineno, 21)
        pass_ = class_.body[0]
        self.assertIsInstance(pass_, nodes.Pass)
        self.assertEqual(pass_.fromlineno, 22)
        self.assertEqual(pass_.tolineno, 22)

    def test_if_lineno(self) -> None:
        stmts = self.astroid.body
        # on line 20:
        #    if aaaa: pass
        #    else:
        #        aaaa,bbbb = 1,2
        #        aaaa,bbbb = bbbb,aaaa
        if_ = stmts[5]
        self.assertIsInstance(if_, nodes.If)
        self.assertEqual(if_.fromlineno, 24)
        self.assertEqual(if_.tolineno, 27)
        self.assertEqual(if_.blockstart_tolineno, 24)
        self.assertEqual(if_.orelse[0].fromlineno, 26)
        self.assertEqual(if_.orelse[1].tolineno, 27)

    def test_for_while_lineno(self) -> None:
        for code in (
            """
            for a in range(4):
              print (a)
              break
            else:
              print ("bouh")
            """,
            """
            while a:
              print (a)
              break
            else:
              print ("bouh")
            """,
        ):
            astroid = builder.parse(code, __name__)
            stmt = astroid.body[0]
            self.assertEqual(stmt.fromlineno, 2)
            self.assertEqual(stmt.tolineno, 6)
            self.assertEqual(stmt.blockstart_tolineno, 2)
            self.assertEqual(stmt.orelse[0].fromlineno, 6)  # XXX
            self.assertEqual(stmt.orelse[0].tolineno, 6)

    def test_try_except_lineno(self) -> None:
        astroid = builder.parse(
            """
            try:
              print (a)
            except:
              pass
            else:
              print ("bouh")
            """,
            __name__,
        )
        try_ = astroid.body[0]
        self.assertEqual(try_.fromlineno, 2)
        self.assertEqual(try_.tolineno, 7)
        self.assertEqual(try_.blockstart_tolineno, 2)
        self.assertEqual(try_.orelse[0].fromlineno, 7)  # XXX
        self.assertEqual(try_.orelse[0].tolineno, 7)
        hdlr = try_.handlers[0]
        self.assertEqual(hdlr.fromlineno, 4)
        self.assertEqual(hdlr.tolineno, 5)
        self.assertEqual(hdlr.blockstart_tolineno, 4)

    def test_try_finally_lineno(self) -> None:
        astroid = builder.parse(
            """
            try:
              print (a)
            finally:
              print ("bouh")
            """,
            __name__,
        )
        try_ = astroid.body[0]
        self.assertEqual(try_.fromlineno, 2)
        self.assertEqual(try_.tolineno, 5)
        self.assertEqual(try_.blockstart_tolineno, 2)
        self.assertEqual(try_.finalbody[0].fromlineno, 5)  # XXX
        self.assertEqual(try_.finalbody[0].tolineno, 5)

    def test_try_finally_25_lineno(self) -> None:
        astroid = builder.parse(
            """
            try:
              print (a)
            except:
              pass
            finally:
              print ("bouh")
            """,
            __name__,
        )
        try_ = astroid.body[0]
        self.assertEqual(try_.fromlineno, 2)
        self.assertEqual(try_.tolineno, 7)
        self.assertEqual(try_.blockstart_tolineno, 2)
        self.assertEqual(try_.finalbody[0].fromlineno, 7)  # XXX
        self.assertEqual(try_.finalbody[0].tolineno, 7)

    def test_with_lineno(self) -> None:
        astroid = builder.parse(
            """
            from __future__ import with_statement
            with file("/tmp/pouet") as f:
                print (f)
            """,
            __name__,
        )
        with_ = astroid.body[1]
        self.assertEqual(with_.fromlineno, 3)
        self.assertEqual(with_.tolineno, 4)
        self.assertEqual(with_.blockstart_tolineno, 3)


class BuilderTest(unittest.TestCase):
    def setUp(self) -> None:
        self.manager = test_utils.brainless_manager()
        self.builder = builder.AstroidBuilder(self.manager)

    def test_data_build_null_bytes(self) -> None:
        with self.assertRaises(AstroidSyntaxError):
            self.builder.string_build("\x00")

    def test_data_build_invalid_x_escape(self) -> None:
        with self.assertRaises(AstroidSyntaxError):
            self.builder.string_build('"\\x1"')

    def test_data_build_error_filename(self) -> None:
        """Check that error filename is set to modname if given."""
        with pytest.raises(AstroidSyntaxError, match="invalid escape sequence") as ctx:
            self.builder.string_build("'\\d+\\.\\d+'")
        assert isinstance(ctx.value.error, SyntaxError)
        assert ctx.value.error.filename == "<unknown>"

        with pytest.raises(AstroidSyntaxError, match="invalid escape sequence") as ctx:
            self.builder.string_build("'\\d+\\.\\d+'", modname="mymodule")
        assert isinstance(ctx.value.error, SyntaxError)
        assert ctx.value.error.filename == "mymodule"

    def test_missing_newline(self) -> None:
        """Check that a file with no trailing new line is parseable."""
        resources.build_file("data/noendingnewline.py")

    def test_missing_file(self) -> None:
        with self.assertRaises(AstroidBuildingError):
            resources.build_file("data/inexistent.py")

    def test_inspect_build0(self) -> None:
        """Test astroid tree build from a living object."""
        builtin_ast = self.manager.ast_from_module_name("builtins")
        # just check type and object are there
        builtin_ast.getattr("type")
        objectastroid = builtin_ast.getattr("object")[0]
        self.assertIsInstance(objectastroid.getattr("__new__")[0], nodes.FunctionDef)
        # check open file alias
        builtin_ast.getattr("open")
        # check 'help' is there (defined dynamically by site.py)
        builtin_ast.getattr("help")
        # check property has __init__
        pclass = builtin_ast["property"]
        self.assertIn("__init__", pclass)
        self.assertIsInstance(builtin_ast["None"], nodes.Const)
        self.assertIsInstance(builtin_ast["True"], nodes.Const)
        self.assertIsInstance(builtin_ast["False"], nodes.Const)
        self.assertIsInstance(builtin_ast["Exception"], nodes.ClassDef)
        self.assertIsInstance(builtin_ast["NotImplementedError"], nodes.ClassDef)

    def test_inspect_build1(self) -> None:
        time_ast = self.manager.ast_from_module_name("time")
        self.assertTrue(time_ast)
        self.assertEqual(time_ast["time"].args.defaults, None)

    def test_inspect_build3(self) -> None:
        self.builder.inspect_build(unittest)

    def test_inspect_build_type_object(self) -> None:
        builtin_ast = self.manager.ast_from_module_name("builtins")

        inferred = list(builtin_ast.igetattr("object"))
        self.assertEqual(len(inferred), 1)
        inferred = inferred[0]
        self.assertEqual(inferred.name, "object")
        inferred.as_string()  # no crash test

        inferred = list(builtin_ast.igetattr("type"))
        self.assertEqual(len(inferred), 1)
        inferred = inferred[0]
        self.assertEqual(inferred.name, "type")
        inferred.as_string()  # no crash test

    def test_inspect_transform_module(self) -> None:
        # ensure no cached version of the time module
        self.manager._mod_file_cache.pop(("time", None), None)
        self.manager.astroid_cache.pop("time", None)

        def transform_time(node: Module) -> None:
            if node.name == "time":
                node.transformed = True

        self.manager.register_transform(nodes.Module, transform_time)
        try:
            time_ast = self.manager.ast_from_module_name("time")
            self.assertTrue(getattr(time_ast, "transformed", False))
        finally:
            self.manager.unregister_transform(nodes.Module, transform_time)

    def test_package_name(self) -> None:
        """Test base properties and method of an astroid module."""
        datap = resources.build_file("data/__init__.py", "data")
        self.assertEqual(datap.name, "data")
        self.assertEqual(datap.package, 1)
        datap = resources.build_file("data/__init__.py", "data.__init__")
        self.assertEqual(datap.name, "data")
        self.assertEqual(datap.package, 1)
        datap = resources.build_file("data/tmp__init__.py", "data.tmp__init__")
        self.assertEqual(datap.name, "data.tmp__init__")
        self.assertEqual(datap.package, 0)

    def test_yield_parent(self) -> None:
        """Check if we added discard nodes as yield parent (w/ compiler)."""
        code = """
            def yiell(): #@
                yield 0
                if noe:
                    yield more
        """
        func = builder.extract_node(code)
        self.assertIsInstance(func, nodes.FunctionDef)
        stmt = func.body[0]
        self.assertIsInstance(stmt, nodes.Expr)
        self.assertIsInstance(stmt.value, nodes.Yield)
        self.assertIsInstance(func.body[1].body[0], nodes.Expr)
        self.assertIsInstance(func.body[1].body[0].value, nodes.Yield)

    def test_object(self) -> None:
        obj_ast = self.builder.inspect_build(object)
        self.assertIn("__setattr__", obj_ast)

    def test_newstyle_detection(self) -> None:
        data = """
            class A:
                "old style"

            class B(A):
                "old style"

            class C(object):
                "new style"

            class D(C):
                "new style"

            __metaclass__ = type

            class E(A):
                "old style"

            class F:
                "new style"
        """
        mod_ast = builder.parse(data, __name__)
        self.assertTrue(mod_ast["A"].newstyle)
        self.assertTrue(mod_ast["B"].newstyle)
        self.assertTrue(mod_ast["E"].newstyle)
        self.assertTrue(mod_ast["C"].newstyle)
        self.assertTrue(mod_ast["D"].newstyle)
        self.assertTrue(mod_ast["F"].newstyle)

    def test_globals(self) -> None:
        data = """
            CSTE = 1

            def update_global():
                global CSTE
                CSTE += 1

            def global_no_effect():
                global CSTE2
                print (CSTE)
        """
        astroid = builder.parse(data, __name__)
        self.assertEqual(len(astroid.getattr("CSTE")), 2)
        self.assertIsInstance(astroid.getattr("CSTE")[0], nodes.AssignName)
        self.assertEqual(astroid.getattr("CSTE")[0].fromlineno, 2)
        self.assertEqual(astroid.getattr("CSTE")[1].fromlineno, 6)
        with self.assertRaises(AttributeInferenceError):
            astroid.getattr("CSTE2")
        with self.assertRaises(InferenceError):
            next(astroid["global_no_effect"].ilookup("CSTE2"))

    def test_socket_build(self) -> None:
        astroid = self.builder.module_build(socket)
        # XXX just check the first one. Actually 3 objects are inferred (look at
        # the socket module) but the last one as those attributes dynamically
        # set and astroid is missing this.
        for fclass in astroid.igetattr("socket"):
            self.assertIn("connect", fclass)
            self.assertIn("send", fclass)
            self.assertIn("close", fclass)
            break

    def test_gen_expr_var_scope(self) -> None:
        data = "l = list(n for n in range(10))\n"
        astroid = builder.parse(data, __name__)
        # n unavailable outside gen expr scope
        self.assertNotIn("n", astroid)
        # test n is inferable anyway
        n = test_utils.get_name_node(astroid, "n")
        self.assertIsNot(n.scope(), astroid)
        self.assertEqual([i.__class__ for i in n.infer()], [util.Uninferable.__class__])

    def test_no_future_imports(self) -> None:
        mod = builder.parse("import sys")
        self.assertEqual(set(), mod.future_imports)

    def test_future_imports(self) -> None:
        mod = builder.parse("from __future__ import print_function")
        self.assertEqual({"print_function"}, mod.future_imports)

    def test_two_future_imports(self) -> None:
        mod = builder.parse(
            """
            from __future__ import print_function
            from __future__ import absolute_import
            """
        )
        self.assertEqual({"print_function", "absolute_import"}, mod.future_imports)

    def test_inferred_build(self) -> None:
        code = """
            class A: pass
            A.type = "class"

            def A_assign_type(self):
                print (self)
            A.assign_type = A_assign_type
            """
        astroid = builder.parse(code)
        lclass = list(astroid.igetattr("A"))
        self.assertEqual(len(lclass), 1)
        lclass = lclass[0]
        self.assertIn("assign_type", lclass.locals)
        self.assertIn("type", lclass.locals)

    def test_infer_can_assign_regular_object(self) -> None:
        mod = builder.parse(
            """
            class A:
                pass
            a = A()
            a.value = "is set"
            a.other = "is set"
        """
        )
        obj = list(mod.igetattr("a"))
        self.assertEqual(len(obj), 1)
        obj = obj[0]
        self.assertIsInstance(obj, Instance)
        self.assertIn("value", obj.instance_attrs)
        self.assertIn("other", obj.instance_attrs)

    def test_infer_can_assign_has_slots(self) -> None:
        mod = builder.parse(
            """
            class A:
                __slots__ = ('value',)
            a = A()
            a.value = "is set"
            a.other = "not set"
        """
        )
        obj = list(mod.igetattr("a"))
        self.assertEqual(len(obj), 1)
        obj = obj[0]
        self.assertIsInstance(obj, Instance)
        self.assertIn("value", obj.instance_attrs)
        self.assertNotIn("other", obj.instance_attrs)

    def test_infer_can_assign_no_classdict(self) -> None:
        mod = builder.parse(
            """
            a = object()
            a.value = "not set"
        """
        )
        obj = list(mod.igetattr("a"))
        self.assertEqual(len(obj), 1)
        obj = obj[0]
        self.assertIsInstance(obj, Instance)
        self.assertNotIn("value", obj.instance_attrs)

    def test_augassign_attr(self) -> None:
        builder.parse(
            """
            class Counter:
                v = 0
                def inc(self):
                    self.v += 1
            """,
            __name__,
        )
        # TODO: Check self.v += 1 generate AugAssign(AssAttr(...)),
        # not AugAssign(GetAttr(AssName...))

    def test_inferred_dont_pollute(self) -> None:
        code = """
            def func(a=None):
                a.custom_attr = 0
            def func2(a={}):
                a.custom_attr = 0
            """
        builder.parse(code)
        # pylint: disable=no-member
        nonetype = nodes.const_factory(None)
        self.assertNotIn("custom_attr", nonetype.locals)
        self.assertNotIn("custom_attr", nonetype.instance_attrs)
        nonetype = nodes.const_factory({})
        self.assertNotIn("custom_attr", nonetype.locals)
        self.assertNotIn("custom_attr", nonetype.instance_attrs)

    def test_asstuple(self) -> None:
        code = "a, b = range(2)"
        astroid = builder.parse(code)
        self.assertIn("b", astroid.locals)
        code = """
            def visit_if(self, node):
                node.test, body = node.tests[0]
            """
        astroid = builder.parse(code)
        self.assertIn("body", astroid["visit_if"].locals)

    def test_build_constants(self) -> None:
        """Test expected values of constants after rebuilding."""
        code = """
            def func():
                return None
                return
                return 'None'
            """
        astroid = builder.parse(code)
        none, nothing, chain = (ret.value for ret in astroid.body[0].body)
        self.assertIsInstance(none, nodes.Const)
        self.assertIsNone(none.value)
        self.assertIsNone(nothing)
        self.assertIsInstance(chain, nodes.Const)
        self.assertEqual(chain.value, "None")

    def test_not_implemented(self) -> None:
        node = builder.extract_node(
            """
        NotImplemented #@
        """
        )
        inferred = next(node.infer())
        self.assertIsInstance(inferred, nodes.Const)
        self.assertEqual(inferred.value, NotImplemented)

    def test_type_comments_without_content(self) -> None:
        node = builder.parse(
            """
            a = 1 # type: # any comment
        """
        )
        assert node


class FileBuildTest(unittest.TestCase):
    def setUp(self) -> None:
        self.module = resources.build_file("data/module.py", "data.module")

    def test_module_base_props(self) -> None:
        """Test base properties and method of an astroid module."""
        module = self.module
        self.assertEqual(module.name, "data.module")
        assert isinstance(module.doc_node, nodes.Const)
        self.assertEqual(module.doc_node.value, "test module for astroid\n")
        self.assertEqual(module.fromlineno, 0)
        self.assertIsNone(module.parent)
        self.assertEqual(module.frame(), module)
        self.assertEqual(module.frame(), module)
        self.assertEqual(module.root(), module)
        self.assertEqual(module.file, os.path.abspath(resources.find("data/module.py")))
        self.assertEqual(module.pure_python, 1)
        self.assertEqual(module.package, 0)
        self.assertFalse(module.is_statement)
        with self.assertRaises(StatementMissing):
            with pytest.warns(DeprecationWarning) as records:
                self.assertEqual(module.statement(future=True), module)
                assert len(records) == 1
        with self.assertRaises(StatementMissing):
            module.statement()

    def test_module_locals(self) -> None:
        """Test the 'locals' dictionary of an astroid module."""
        module = self.module
        _locals = module.locals
        self.assertIs(_locals, module.globals)
        keys = sorted(_locals.keys())
        should = [
            "MY_DICT",
            "NameNode",
            "YO",
            "YOUPI",
            "__revision__",
            "global_access",
            "modutils",
            "four_args",
            "os",
            "redirect",
        ]
        should.sort()
        self.assertEqual(keys, sorted(should))

    def test_function_base_props(self) -> None:
        """Test base properties and method of an astroid function."""
        module = self.module
        function = module["global_access"]
        self.assertEqual(function.name, "global_access")
        assert isinstance(function.doc_node, nodes.Const)
        self.assertEqual(function.doc_node.value, "function test")
        self.assertEqual(function.fromlineno, 11)
        self.assertTrue(function.parent)
        self.assertEqual(function.frame(), function)
        self.assertEqual(function.parent.frame(), module)
        self.assertEqual(function.frame(), function)
        self.assertEqual(function.parent.frame(), module)
        self.assertEqual(function.root(), module)
        self.assertEqual([n.name for n in function.args.args], ["key", "val"])
        self.assertEqual(function.type, "function")

    def test_function_locals(self) -> None:
        """Test the 'locals' dictionary of an astroid function."""
        _locals = self.module["global_access"].locals
        self.assertEqual(len(_locals), 4)
        keys = sorted(_locals.keys())
        self.assertEqual(keys, ["i", "key", "local", "val"])

    def test_class_base_props(self) -> None:
        """Test base properties and method of an astroid class."""
        module = self.module
        klass = module["YO"]
        self.assertEqual(klass.name, "YO")
        assert isinstance(klass.doc_node, nodes.Const)
        self.assertEqual(klass.doc_node.value, "hehe\n    haha")
        self.assertEqual(klass.fromlineno, 25)
        self.assertTrue(klass.parent)
        self.assertEqual(klass.frame(), klass)
        self.assertEqual(klass.parent.frame(), module)
        self.assertEqual(klass.frame(), klass)
        self.assertEqual(klass.parent.frame(), module)
        self.assertEqual(klass.root(), module)
        self.assertEqual(klass.basenames, [])
        self.assertTrue(klass.newstyle)

    def test_class_locals(self) -> None:
        """Test the 'locals' dictionary of an astroid class."""
        module = self.module
        klass1 = module["YO"]
        locals1 = klass1.locals
        keys = sorted(locals1.keys())
        assert_keys = ["__init__", "__module__", "__qualname__", "a"]
        self.assertEqual(keys, assert_keys)
        klass2 = module["YOUPI"]
        locals2 = klass2.locals
        keys = locals2.keys()
        assert_keys = [
            "__init__",
            "__module__",
            "__qualname__",
            "class_attr",
            "class_method",
            "method",
            "static_method",
        ]
        self.assertEqual(sorted(keys), assert_keys)

    def test_class_instance_attrs(self) -> None:
        module = self.module
        klass1 = module["YO"]
        klass2 = module["YOUPI"]
        self.assertEqual(list(klass1.instance_attrs.keys()), ["yo"])
        self.assertEqual(list(klass2.instance_attrs.keys()), ["member"])

    def test_class_basenames(self) -> None:
        module = self.module
        klass1 = module["YO"]
        klass2 = module["YOUPI"]
        self.assertEqual(klass1.basenames, [])
        self.assertEqual(klass2.basenames, ["YO"])

    def test_method_base_props(self) -> None:
        """Test base properties and method of an astroid method."""
        klass2 = self.module["YOUPI"]
        # "normal" method
        method = klass2["method"]
        self.assertEqual(method.name, "method")
        self.assertEqual([n.name for n in method.args.args], ["self"])
        assert isinstance(method.doc_node, nodes.Const)
        self.assertEqual(method.doc_node.value, "method\n        test")
        self.assertEqual(method.fromlineno, 48)
        self.assertEqual(method.type, "method")
        # class method
        method = klass2["class_method"]
        self.assertEqual([n.name for n in method.args.args], ["cls"])
        self.assertEqual(method.type, "classmethod")
        # static method
        method = klass2["static_method"]
        self.assertEqual(method.args.args, [])
        self.assertEqual(method.type, "staticmethod")

    def test_method_locals(self) -> None:
        """Test the 'locals' dictionary of an astroid method."""
        method = self.module["YOUPI"]["method"]
        _locals = method.locals
        keys = sorted(_locals)
        # ListComp variables are not accessible outside
        self.assertEqual(len(_locals), 3)
        self.assertEqual(keys, ["autre", "local", "self"])

    def test_unknown_encoding(self) -> None:
        with self.assertRaises(AstroidSyntaxError):
            resources.build_file("data/invalid_encoding.py")


def test_module_build_dunder_file() -> None:
    """Test that module_build() can work with modules that have the *__file__*
    attribute.
    """
    module = builder.AstroidBuilder().module_build(collections)
    assert module.path[0] == collections.__file__


@pytest.mark.xfail(
    reason=(
        "The builtin ast module does not fail with a specific error "
        "for syntax error caused by invalid type comments."
    ),
)
def test_parse_module_with_invalid_type_comments_does_not_crash():
    node = builder.parse(
        """
    # op {
    #   name: "AssignAddVariableOp"
    #   input_arg {
    #     name: "resource"
    #     type: DT_RESOURCE
    #   }
    #   input_arg {
    #     name: "value"
    #     type_attr: "dtype"
    #   }
    #   attr {
    #     name: "dtype"
    #     type: "type"
    #   }
    #   is_stateful: true
    # }
    a, b = 2
    """
    )
    assert isinstance(node, nodes.Module)


def test_arguments_of_signature() -> None:
    """Test that arguments is None for function without an inferable signature."""
    node = builder.extract_node("int")
    classdef: nodes.ClassDef = next(node.infer())
    assert all(i.args.args is None for i in classdef.getattr("__dir__"))


class HermeticInterpreterTest(unittest.TestCase):
    """Modeled on https://github.com/pylint-dev/astroid/pull/1207#issuecomment-951455588."""

    @classmethod
    def setUpClass(cls):
        """Simulate a hermetic interpreter environment having no code on the filesystem."""
        with tempfile.TemporaryDirectory() as tmp_dir:
            sys.path.append(tmp_dir)

            # Write a python file and compile it to .pyc
            # To make this test have even more value, we would need to come up with some
            # code that gets inferred differently when we get its "partial representation".
            # This code is too simple for that. But we can't use builtins either, because we would
            # have to delete builtins from the filesystem.  But even if we engineered that,
            # the difference might evaporate over time as inference changes.
            cls.code_snippet = "def func():  return 42"
            with tempfile.NamedTemporaryFile(
                mode="w", dir=tmp_dir, suffix=".py", delete=False
            ) as tmp:
                tmp.write(cls.code_snippet)
                pyc_file = py_compile.compile(tmp.name)
                cls.pyc_name = tmp.name.replace(".py", ".pyc")
            os.remove(tmp.name)
            os.rename(pyc_file, cls.pyc_name)

            # Import the module
            cls.imported_module_path = pathlib.Path(cls.pyc_name)
            cls.imported_module = importlib.import_module(cls.imported_module_path.stem)

            # Delete source code from module object, filesystem, and path
            del cls.imported_module.__file__
            os.remove(cls.imported_module_path)
            sys.path.remove(tmp_dir)

    def test_build_from_live_module_without_source_file(self) -> None:
        """Assert that inspect_build() is not called.

        See comment in module_build() before the call to inspect_build():
            "get a partial representation by introspection"

        This "partial representation" was presumably causing unexpected behavior.
        """
        # Sanity check
        self.assertIsNone(
            self.imported_module.__loader__.get_source(self.imported_module_path.stem)
        )
        with self.assertRaises(AttributeError):
            _ = self.imported_module.__file__

        my_builder = builder.AstroidBuilder()
        with unittest.mock.patch.object(
            self.imported_module.__loader__,
            "get_source",
            return_value=self.code_snippet,
        ):
            with unittest.mock.patch.object(
                my_builder, "inspect_build", side_effect=AssertionError
            ):
                my_builder.module_build(
                    self.imported_module, modname=self.imported_module_path.stem
                )
