• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

OpShin / opshin / 865

pending completion
865

push

travis-ci-com

nielstron
Bump opshin version

1 of 1 new or added line in 1 file covered. (100.0%)

3728 of 4026 relevant lines covered (92.6%)

3.7 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

68.85
/opshin/rewrite/rewrite_import.py
1
import ast
4✔
2

3
import importlib
4✔
4
import importlib.util
4✔
5
import pathlib
4✔
6
import typing
4✔
7
import sys
4✔
8
from ast import *
4✔
9

10
from ..util import CompilingNodeTransformer
4✔
11

12
"""
2✔
13
Checks that there was an import of dataclass if there are any class definitions
14
"""
15

16

17
def import_module(name, package=None):
4✔
18
    """An approximate implementation of import."""
19
    absolute_name = importlib.util.resolve_name(name, package)
4✔
20
    try:
4✔
21
        return sys.modules[absolute_name]
4✔
22
    except KeyError:
×
23
        pass
×
24

25
    path = None
×
26
    if "." in absolute_name:
×
27
        parent_name, _, child_name = absolute_name.rpartition(".")
×
28
        parent_module = import_module(parent_name)
×
29
        path = parent_module.__spec__.submodule_search_locations
×
30
    for finder in sys.meta_path:
×
31
        spec = finder.find_spec(absolute_name, path)
×
32
        if spec is not None:
×
33
            break
×
34
    else:
35
        msg = f"No module named {absolute_name!r}"
×
36
        raise ModuleNotFoundError(msg, name=absolute_name)
×
37
    module = importlib.util.module_from_spec(spec)
×
38
    sys.modules[absolute_name] = module
×
39
    spec.loader.exec_module(module)
×
40
    if path is not None:
×
41
        setattr(parent_module, child_name, module)
×
42
    return module
×
43

44

45
class RewriteLocation(CompilingNodeTransformer):
4✔
46
    def __init__(self, orig_node):
4✔
47
        self.orig_node = orig_node
4✔
48

49
    def visit(self, node):
4✔
50
        node = ast.copy_location(node, self.orig_node)
4✔
51
        return super().visit(node)
4✔
52

53

54
class RewriteImport(CompilingNodeTransformer):
4✔
55
    step = "Resolving imports"
4✔
56

57
    def __init__(self, filename=None, package=None):
4✔
58
        self.filename = filename
4✔
59
        self.package = package
4✔
60

61
    def visit_ImportFrom(
4✔
62
        self, node: ImportFrom
63
    ) -> typing.Union[ImportFrom, typing.List[AST]]:
64
        if node.module in ["pycardano", "typing", "dataclasses", "hashlib"]:
4✔
65
            return node
4✔
66
        assert (
4✔
67
            len(node.names) == 1
68
        ), "The import must have the form 'from <pkg> import *'"
69
        assert (
4✔
70
            node.names[0].name == "*"
71
        ), "The import must have the form 'from <pkg> import *'"
72
        assert (
4✔
73
            node.names[0].asname == None
74
        ), "The import must have the form 'from <pkg> import *'"
75
        # TODO set anchor point according to own package
76
        if self.filename:
4✔
77
            sys.path.append(str(pathlib.Path(self.filename).parent.absolute()))
4✔
78
        module = import_module(node.module, self.package)
4✔
79
        if self.filename:
4✔
80
            sys.path.pop()
4✔
81
        module_file = pathlib.Path(module.__file__)
4✔
82
        assert (
4✔
83
            module_file.suffix == ".py"
84
        ), "The import must import a single python file."
85
        # visit the imported file again - make sure that recursive imports are resolved accordingly
86
        with module_file.open("r") as fp:
4✔
87
            module_content = fp.read()
4✔
88
        resolved = parse(module_content, filename=module_file.name)
4✔
89
        # annotate this to point to the original line number!
90
        RewriteLocation(node).visit(resolved)
4✔
91
        # recursively import all statements there
92
        recursively_resolved: Module = RewriteImport(
4✔
93
            filename=str(module_file), package=module.__package__
94
        ).visit(resolved)
95
        return recursively_resolved.body
4✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc