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

kivy / python-for-android / 5152356722

pending completion
5152356722

push

github

web-flow
Bump actions/setup-python and actions/checkout versions, as old ones are deprecated (#2827)

938 of 2268 branches covered (41.36%)

Branch coverage included in aggregate %.

4744 of 7405 relevant lines covered (64.06%)

2.54 hits per line

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

95.65
/pythonforandroid/recipes/hostpython3/__init__.py
1
import sh
4✔
2
import os
4✔
3

4
from multiprocessing import cpu_count
4✔
5
from pathlib import Path
4✔
6
from os.path import join
4✔
7

8
from pythonforandroid.logger import shprint
4✔
9
from pythonforandroid.recipe import Recipe
4✔
10
from pythonforandroid.util import (
4✔
11
    BuildInterruptingException,
12
    current_directory,
13
    ensure_dir,
14
)
15
from pythonforandroid.prerequisites import OpenSSLPrerequisite
4✔
16

17
HOSTPYTHON_VERSION_UNSET_MESSAGE = (
4✔
18
    'The hostpython recipe must have set version'
19
)
20

21
SETUP_DIST_NOT_FIND_MESSAGE = (
4✔
22
    'Could not find Setup.dist or Setup in Python build'
23
)
24

25

26
class HostPython3Recipe(Recipe):
4✔
27
    '''
28
    The hostpython3's recipe.
29

30
    .. versionchanged:: 2019.10.06.post0
31
        Refactored from deleted class ``python.HostPythonRecipe`` into here.
32

33
    .. versionchanged:: 0.6.0
34
        Refactored into  the new class
35
        :class:`~pythonforandroid.python.HostPythonRecipe`
36
    '''
37

38
    version = '3.10.10'
4✔
39
    name = 'hostpython3'
4✔
40

41
    build_subdir = 'native-build'
4✔
42
    '''Specify the sub build directory for the hostpython3 recipe. Defaults
1✔
43
    to ``native-build``.'''
44

45
    url = 'https://www.python.org/ftp/python/{version}/Python-{version}.tgz'
4✔
46
    '''The default url to download our host python recipe. This url will
1✔
47
    change depending on the python version set in attribute :attr:`version`.'''
48

49
    patches = ['patches/pyconfig_detection.patch']
4✔
50

51
    @property
4✔
52
    def _exe_name(self):
3✔
53
        '''
54
        Returns the name of the python executable depending on the version.
55
        '''
56
        if not self.version:
4✔
57
            raise BuildInterruptingException(HOSTPYTHON_VERSION_UNSET_MESSAGE)
4✔
58
        return f'python{self.version.split(".")[0]}'
4✔
59

60
    @property
4✔
61
    def python_exe(self):
3✔
62
        '''Returns the full path of the hostpython executable.'''
63
        return join(self.get_path_to_python(), self._exe_name)
4✔
64

65
    def get_recipe_env(self, arch=None):
4✔
66
        env = os.environ.copy()
4✔
67
        openssl_prereq = OpenSSLPrerequisite()
4✔
68
        if env.get("PKG_CONFIG_PATH", ""):
4!
69
            env["PKG_CONFIG_PATH"] = os.pathsep.join(
4✔
70
                [openssl_prereq.pkg_config_location, env["PKG_CONFIG_PATH"]]
71
            )
72
        else:
73
            env["PKG_CONFIG_PATH"] = openssl_prereq.pkg_config_location
×
74
        return env
4✔
75

76
    def should_build(self, arch):
4✔
77
        if Path(self.python_exe).exists():
4✔
78
            # no need to build, but we must set hostpython for our Context
79
            self.ctx.hostpython = self.python_exe
4✔
80
            return False
4✔
81
        return True
4✔
82

83
    def get_build_container_dir(self, arch=None):
4✔
84
        choices = self.check_recipe_choices()
4✔
85
        dir_name = '-'.join([self.name] + choices)
4✔
86
        return join(self.ctx.build_dir, 'other_builds', dir_name, 'desktop')
4✔
87

88
    def get_build_dir(self, arch=None):
4✔
89
        '''
90
        .. note:: Unlike other recipes, the hostpython build dir doesn't
91
            depend on the target arch
92
        '''
93
        return join(self.get_build_container_dir(), self.name)
4✔
94

95
    def get_path_to_python(self):
4✔
96
        return join(self.get_build_dir(), self.build_subdir)
4✔
97

98
    def build_arch(self, arch):
4✔
99
        env = self.get_recipe_env(arch)
4✔
100

101
        recipe_build_dir = self.get_build_dir(arch.arch)
4✔
102

103
        # Create a subdirectory to actually perform the build
104
        build_dir = join(recipe_build_dir, self.build_subdir)
4✔
105
        ensure_dir(build_dir)
4✔
106

107
        # Configure the build
108
        with current_directory(build_dir):
4✔
109
            if not Path('config.status').exists():
4✔
110
                shprint(sh.Command(join(recipe_build_dir, 'configure')), _env=env)
4✔
111

112
        with current_directory(recipe_build_dir):
4✔
113
            # Create the Setup file. This copying from Setup.dist is
114
            # the normal and expected procedure before Python 3.8, but
115
            # after this the file with default options is already named "Setup"
116
            setup_dist_location = join('Modules', 'Setup.dist')
4✔
117
            if Path(setup_dist_location).exists():
4✔
118
                shprint(sh.cp, setup_dist_location,
4✔
119
                        join(build_dir, 'Modules', 'Setup'))
120
            else:
121
                # Check the expected file does exist
122
                setup_location = join('Modules', 'Setup')
4✔
123
                if not Path(setup_location).exists():
4✔
124
                    raise BuildInterruptingException(
4✔
125
                        SETUP_DIST_NOT_FIND_MESSAGE
126
                    )
127

128
            shprint(sh.make, '-j', str(cpu_count()), '-C', build_dir, _env=env)
4✔
129

130
            # make a copy of the python executable giving it the name we want,
131
            # because we got different python's executable names depending on
132
            # the fs being case-insensitive (Mac OS X, Cygwin...) or
133
            # case-sensitive (linux)...so this way we will have an unique name
134
            # for our hostpython, regarding the used fs
135
            for exe_name in ['python.exe', 'python']:
4!
136
                exe = join(self.get_path_to_python(), exe_name)
4✔
137
                if Path(exe).is_file():
4!
138
                    shprint(sh.cp, exe, self.python_exe)
4✔
139
                    break
4✔
140

141
        self.ctx.hostpython = self.python_exe
4✔
142

143

144
recipe = HostPython3Recipe()
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