Exemple #1
0
def test_works_with_python38(rule_runner: RuleRunner) -> None:
    content = dedent("""\
        is_py38 = True
        if walrus := is_py38:
            print(walrus)

        import demo
        from project.demo import Demo

        __import__("pkg_resources")
        __import__("treat.as.a.regular.import.not.a.string.import")

        importlib.import_module("dep.from.str")
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        constraints=">=3.8",
        expected_imports={
            "demo":
            ImpInfo(lineno=5, weak=False),
            "project.demo.Demo":
            ImpInfo(lineno=6, weak=False),
            "pkg_resources":
            ImpInfo(lineno=8, weak=False),
            "treat.as.a.regular.import.not.a.string.import":
            ImpInfo(lineno=9, weak=False),
            "dep.from.str":
            ImpInfo(lineno=11, weak=True),
        },
    )
Exemple #2
0
def test_works_with_python39(rule_runner: RuleRunner) -> None:
    content = dedent("""\
        # This requires the new PEG parser.
        with (
            open("/dev/null") as f,
        ):
            pass

        import demo
        from project.demo import Demo

        __import__("pkg_resources")
        __import__("treat.as.a.regular.import.not.a.string.import")

        importlib.import_module("dep.from.str")
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        constraints=">=3.9",
        expected_imports={
            "demo":
            ImpInfo(lineno=7, weak=False),
            "project.demo.Demo":
            ImpInfo(lineno=8, weak=False),
            "pkg_resources":
            ImpInfo(lineno=10, weak=False),
            "treat.as.a.regular.import.not.a.string.import":
            ImpInfo(lineno=11, weak=False),
            "dep.from.str":
            ImpInfo(lineno=13, weak=True),
        },
    )
Exemple #3
0
def test_dunder_import_call(rule_runner: RuleRunner) -> None:
    content = dedent("""\
        __import__("pkg_resources")
        __import__("dunder_import_ignored")  # pants: no-infer-dep
        __import__(  # pants: no-infer-dep
            "not_ignored_but_looks_like_it_could_be"
        )
        __import__(
            "ignored"  # pants: no-infer-dep
        )
        __import__(
            "also_not_ignored_but_looks_like_it_could_be"
        )  # pants: no-infer-dep
        __import__(
            "ignored_too" \\
            # pants: no-infer-dep
        )
        __import__(
            "ignored_as_well" \\
        )  # pants: no-infer-dep
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        expected_imports={
            "pkg_resources":
            ImpInfo(lineno=1, weak=False),
            "not_ignored_but_looks_like_it_could_be":
            ImpInfo(lineno=4, weak=False),
            "also_not_ignored_but_looks_like_it_could_be":
            ImpInfo(lineno=10, weak=False),
        },
    )
Exemple #4
0
def test_real_import_beats_tryexcept_import(rule_runner: RuleRunner) -> None:
    assert_deps_parsed(
        rule_runner,
        dedent("""\
                import one.two.three
                try: import one.two.three
                except ImportError: pass
            """),
        expected_imports={"one.two.three": ImpInfo(lineno=1, weak=False)},
    )
Exemple #5
0
def test_relative_imports(rule_runner: RuleRunner, basename: str) -> None:
    content = dedent("""\
        from . import sibling
        from .sibling import Nibling
        from .subdir.child import Child
        from ..parent import Parent
        from ..parent import (
            Parent1,
            Guardian as Parent2
        )
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        filename=f"project/util/{basename}",
        expected_imports={
            "project.util.sibling": ImpInfo(lineno=1, weak=False),
            "project.util.sibling.Nibling": ImpInfo(lineno=2, weak=False),
            "project.util.subdir.child.Child": ImpInfo(lineno=3, weak=False),
            "project.parent.Parent": ImpInfo(lineno=4, weak=False),
            "project.parent.Parent1": ImpInfo(lineno=6, weak=False),
            "project.parent.Guardian": ImpInfo(lineno=7, weak=False),
        },
    )
Exemple #6
0
def test_normal_imports(rule_runner: RuleRunner) -> None:
    content = dedent("""\
        from __future__ import print_function

        import os
        import os  # repeated to test the line number
        import os.path
        from typing import TYPE_CHECKING

        import requests

        import demo
        from project.demo import Demo
        from project.demo import OriginalName as Renamed
        import pragma_ignored  # pants: no-infer-dep
        from also_pragma_ignored import doesnt_matter  # pants: no-infer-dep
        from multiline_import1 import (
            not_ignored1,
            ignored1 as alias1,  # pants: no-infer-dep
            ignored2 as \\
                alias2,  # pants: no-infer-dep
            ignored3 as  # pants: no-infer-dep
                alias3,
            ignored4 as alias4, ignored4,  # pants: no-infer-dep
            not_ignored2, \\
            not_ignored3
        )
        from multiline_import2 import (ignored1,  # pants: no-infer-dep
            not_ignored)

        if TYPE_CHECKING:
            from project.circular_dep import CircularDep
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        expected_imports={
            "__future__.print_function": ImpInfo(lineno=1, weak=False),
            "os": ImpInfo(lineno=3, weak=False),
            "os.path": ImpInfo(lineno=5, weak=False),
            "typing.TYPE_CHECKING": ImpInfo(lineno=6, weak=False),
            "requests": ImpInfo(lineno=8, weak=False),
            "demo": ImpInfo(lineno=10, weak=False),
            "project.demo.Demo": ImpInfo(lineno=11, weak=False),
            "project.demo.OriginalName": ImpInfo(lineno=12, weak=False),
            "multiline_import1.not_ignored1": ImpInfo(lineno=16, weak=False),
            "multiline_import1.not_ignored2": ImpInfo(lineno=23, weak=False),
            "multiline_import1.not_ignored3": ImpInfo(lineno=24, weak=False),
            "multiline_import2.not_ignored": ImpInfo(lineno=27, weak=False),
            "project.circular_dep.CircularDep": ImpInfo(lineno=30, weak=False),
        },
    )
Exemple #7
0
def test_works_with_python2(rule_runner: RuleRunner) -> None:
    content = dedent("""\
        # -*- coding: utf-8 -*-
        print "Python 2 lives on."

        import demo
        from project.demo import Demo

        __import__(u"pkg_resources")
        __import__(b"treat.as.a.regular.import.not.a.string.import")
        __import__(u"{}".format("interpolation"))

        importlib.import_module(b"dep.from.bytes")
        importlib.import_module(u"dep.from.str")
        importlib.import_module(u"dep.from.str_狗")

        b"\\xa0 a non-utf8 string, make sure we ignore it"

        try: import weak1
        except ImportError: import strong1
        else: import strong2
        finally: import strong3
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        constraints="==2.7.*",
        expected_imports={
            "demo":
            ImpInfo(lineno=4, weak=False),
            "project.demo.Demo":
            ImpInfo(lineno=5, weak=False),
            "pkg_resources":
            ImpInfo(lineno=7, weak=False),
            "treat.as.a.regular.import.not.a.string.import":
            ImpInfo(lineno=8, weak=False),
            "dep.from.bytes":
            ImpInfo(lineno=11, weak=True),
            "dep.from.str":
            ImpInfo(lineno=12, weak=True),
            "dep.from.str_狗":
            ImpInfo(lineno=13, weak=True),
            "weak1":
            ImpInfo(lineno=17, weak=True),
            "strong1":
            ImpInfo(lineno=18, weak=False),
            "strong2":
            ImpInfo(lineno=19, weak=False),
            "strong3":
            ImpInfo(lineno=20, weak=False),
        },
    )
Exemple #8
0
def test_real_import_beats_string_import(rule_runner: RuleRunner) -> None:
    assert_deps_parsed(
        rule_runner,
        "import one.two.three; 'one.two.three'",
        expected_imports={"one.two.three": ImpInfo(lineno=1, weak=False)},
    )
Exemple #9
0
def test_imports_from_strings(rule_runner: RuleRunner, min_dots: int) -> None:
    content = dedent("""\
        modules = [
            # Potentially valid strings (depending on min_dots).
            'a.b',
            'a.Foo',
            'a.b.d',
            'a.b2.d',
            'a.b.c.Foo',
            'a.b.c.d.Foo',
            'a.b.c.d.FooBar',
            'a.b.c.d.e.f.g.Baz',
            'a.b_c.d._bar',
            'a.b2.c.D',
            'a.b.c_狗',

            # Definitely invalid strings
            '..a.b.c.d',
            'a.B.d',
            'a.2b.d',
            'a..b..c',
            'a.b.c.d.2Bar',
            'a.b_c.D.bar',
            'a.b_c.D.Bar',
            'a.2b.c.D',
        ]

        for module in modules:
            importlib.import_module(module)
        """)

    potentially_valid = {
        "a.b": ImpInfo(lineno=3, weak=True),
        "a.Foo": ImpInfo(lineno=4, weak=True),
        "a.b.d": ImpInfo(lineno=5, weak=True),
        "a.b2.d": ImpInfo(lineno=6, weak=True),
        "a.b.c.Foo": ImpInfo(lineno=7, weak=True),
        "a.b.c.d.Foo": ImpInfo(lineno=8, weak=True),
        "a.b.c.d.FooBar": ImpInfo(lineno=9, weak=True),
        "a.b.c.d.e.f.g.Baz": ImpInfo(lineno=10, weak=True),
        "a.b_c.d._bar": ImpInfo(lineno=11, weak=True),
        "a.b2.c.D": ImpInfo(lineno=12, weak=True),
        "a.b.c_狗": ImpInfo(lineno=13, weak=True),
    }
    expected = {
        sym: info
        for sym, info in potentially_valid.items()
        if sym.count(".") >= min_dots
    }

    assert_deps_parsed(rule_runner,
                       content,
                       expected_imports=expected,
                       string_imports_min_dots=min_dots)
    assert_deps_parsed(rule_runner,
                       content,
                       string_imports=False,
                       expected_imports={})
Exemple #10
0
def test_try_except(rule_runner: RuleRunner) -> None:
    content = dedent("""\
        try: import strong1
        except AssertionError: pass

        try: import weak1
        except ImportError: pass

        try: import weak2
        except (AssertionError, ImportError): pass

        try: import weak3
        except [AssertionError, ImportError]: pass

        try: import weak4
        except {AssertionError, ImportError}: pass
        except ImportError: pass

        try: import weak5
        except AssertionError: pass
        except ImportError: pass

        try: import weak6
        except AssertionError: import strong2
        except ImportError: import strong3
        else: import strong4
        finally: import strong5

        try: pass
        except AssertionError:
            try: import weak7
            except ImportError: import strong6

        try: import strong7
        # This would be too complicated to try and handle
        except (lambda: ImportError)(): pass

        ImpError = ImportError
        try: import strong8
        # This would be too complicated to try and handle
        except ImpError: pass

        # At least one test with import on its own line
        try:
            import weak8
        except ImportError:
            import strong9
        """)
    assert_deps_parsed(
        rule_runner,
        content,
        expected_imports={
            "strong1": ImpInfo(lineno=1, weak=False),
            "weak1": ImpInfo(lineno=4, weak=True),
            "weak2": ImpInfo(lineno=7, weak=True),
            "weak3": ImpInfo(lineno=10, weak=True),
            "weak4": ImpInfo(lineno=13, weak=True),
            "weak5": ImpInfo(lineno=17, weak=True),
            "weak6": ImpInfo(lineno=21, weak=True),
            "strong2": ImpInfo(lineno=22, weak=False),
            "strong3": ImpInfo(lineno=23, weak=False),
            "strong4": ImpInfo(lineno=24, weak=False),
            "strong5": ImpInfo(lineno=25, weak=False),
            "weak7": ImpInfo(lineno=29, weak=True),
            "strong6": ImpInfo(lineno=30, weak=False),
            "strong7": ImpInfo(lineno=32, weak=False),
            "strong8": ImpInfo(lineno=37, weak=False),
            "weak8": ImpInfo(lineno=43, weak=True),
            "strong9": ImpInfo(lineno=45, weak=False),
        },
    )