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

pybuilder / pybuilder / 17169549308

23 Aug 2025 01:34AM UTC coverage: 84.004% (-0.02%) from 84.026%
17169549308

push

github

arcivanov
Release 0.13.17

2168 of 2672 branches covered (81.14%)

Branch coverage included in aggregate %.

5531 of 6493 relevant lines covered (85.18%)

36.26 hits per line

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

74.19
/src/main/python/pybuilder/extern/__init__.py
1
#   -*- coding: utf-8 -*-
2
#
3
#   This file is part of PyBuilder
4
#
5
#   Copyright 2011-2020 PyBuilder Team
6
#
7
#   Licensed under the Apache License, Version 2.0 (the "License");
8
#   you may not use this file except in compliance with the License.
9
#   You may obtain a copy of the License at
10
#
11
#       http://www.apache.org/licenses/LICENSE-2.0
12
#
13
#   Unless required by applicable law or agreed to in writing, software
14
#   distributed under the License is distributed on an "AS IS" BASIS,
15
#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16
#   See the License for the specific language governing permissions and
17
#   limitations under the License.
18

19
import sys
44✔
20
from importlib import import_module
44✔
21
from importlib.abc import Loader, MetaPathFinder
44✔
22
from importlib.util import spec_from_loader
44✔
23

24
import pybuilder._vendor
44✔
25

26

27
class VendorImporter(Loader, MetaPathFinder):
44✔
28
    """
29
    A PEP 302 meta path importer for finding optionally-vendored
30
    or otherwise naturally-installed packages from root_name.
31
    """
32

33
    def __init__(self, root_name, vendored_names, vendor_pkg):
44✔
34
        self.root_name = root_name
44✔
35
        self.vendored_names = set(vendored_names)
44✔
36
        self.vendor_pkg = vendor_pkg
44✔
37
        self._in_flight_imports = set()
44✔
38

39
    @property
44✔
40
    def search_path(self):
44✔
41
        """
42
        Search first the vendor package then as a natural package.
43
        """
44
        yield self.vendor_pkg + "."
44✔
45

46
    def find_module(self, fullname, path=None):
44✔
47
        """
48
        Return self when fullname starts with root_name and the
49
        target module is one vendored through this importer.
50
        """
51
        root, base, target = fullname.partition(self.root_name + ".")
×
52
        if root == fullname and not base and not target:
×
53
            root = None
×
54
            target = fullname
×
55
        if root:
×
56
            return
×
57
        if not any(map(target.startswith, self.vendored_names)):
×
58
            return
×
59
        return self
×
60

61
    def load_module(self, fullname):
44✔
62
        """
63
        Iterate over the search path to locate and load fullname.
64
        """
65
        root, base, target = fullname.partition(self.root_name + ".")
44✔
66
        if root == fullname and not base and not target:
44!
67
            root = None
44✔
68
            target = fullname
44✔
69
        for prefix in self.search_path:
44!
70
            extant = prefix + target
44✔
71
            if extant not in self._in_flight_imports:
44✔
72
                self._in_flight_imports.add(extant)
44✔
73
                try:
44✔
74
                    mod = import_module(extant)
44✔
75
                finally:
76
                    self._in_flight_imports.remove(extant)
44✔
77
            if extant in sys.modules:
44!
78
                mod = sys.modules[extant]
44✔
79
                sys.modules[fullname] = mod
44✔
80
                return mod
44✔
81
        else:
82
            raise ImportError(
×
83
                "The '{target}' package is required; "
84
                "normally this is bundled with this package so if you get "
85
                "this warning, consult the packager of your "
86
                "distribution.".format(**locals())
87
            )
88

89
    def find_spec(self, fullname, path=None, target=None):
44✔
90
        """Return a module spec for vendored names."""
91
        return (
44✔
92
            spec_from_loader(fullname, self)
93
            if self._module_matches_namespace(fullname) else None
94
        )
95

96
    def _module_matches_namespace(self, fullname):
44✔
97
        """Figure out if the target module is vendored."""
98
        root, base, target = fullname.partition(self.root_name + '.')
44✔
99
        if root == fullname and not base and not target:
44!
100
            root = None
44✔
101
            target = fullname
44✔
102
        return not root and any(map(target.startswith, self.vendored_names))
44✔
103

104
    def _find_distributions(self, context):
44✔
105
        context.path.insert(0, pybuilder._vendor.__file__[:-len("__init__.py") - 1])
44✔
106
        return []
44✔
107

108
    # https://github.com/pybuilder/pybuilder/issues/807
109
    if sys.version_info[:2] == (3, 8):
44!
110
        def find_distributions(self, context):
×
111
            return iter(self._find_distributions(context))
×
112
    else:
113
        find_distributions = _find_distributions
44✔
114

115
    def install(self):
44✔
116
        """
117
        Install this importer into sys.meta_path if not already present.
118
        """
119
        if self not in sys.meta_path:
44!
120
            sys.meta_path.insert(0, self)
44✔
121

122
            for pkg in self.vendored_names:
44✔
123
                for p in list(sys.modules):
44✔
124
                    if p == pkg or p.startswith(pkg + "."):
44✔
125
                        sys.modules.pop(p, None)
26✔
126

127

128
VendorImporter(__name__, pybuilder._vendor.__names__, pybuilder._vendor.__package__).install()
44✔
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

© 2026 Coveralls, Inc