aboutsummaryrefslogtreecommitdiff
path: root/mesonbuild/dependencies/python.py
diff options
context:
space:
mode:
authorEli Schwartz <eschwartz@archlinux.org>2023-02-13 19:50:03 -0500
committerDylan Baker <dylan@pnwbakers.com>2023-02-22 10:32:09 -0800
commit9fa4da3ba94cd1bd41917c93742396bd3f94330f (patch)
tree2da865455ef0f451b8955c1b7a7aa88763eec1cd /mesonbuild/dependencies/python.py
parent6719724c7c6ddecba60cc27f60a07862bb707615 (diff)
downloadmeson-9fa4da3ba94cd1bd41917c93742396bd3f94330f.zip
meson-9fa4da3ba94cd1bd41917c93742396bd3f94330f.tar.gz
meson-9fa4da3ba94cd1bd41917c93742396bd3f94330f.tar.bz2
python module/dependency: move the specialized external program
In preparation for handling more work inside dependencies.*, we need to be able to run a PythonExternalProgram from the python dependency. Move most of the definition -- but only the parts that have no interest in a ModuleState -- and subclass a bit of sanity checking that we need to handle specially when used in the module.
Diffstat (limited to 'mesonbuild/dependencies/python.py')
-rw-r--r--mesonbuild/dependencies/python.py81
1 files changed, 79 insertions, 2 deletions
diff --git a/mesonbuild/dependencies/python.py b/mesonbuild/dependencies/python.py
index 06dd700..f3a8444 100644
--- a/mesonbuild/dependencies/python.py
+++ b/mesonbuild/dependencies/python.py
@@ -13,18 +13,95 @@
# limitations under the License.
from __future__ import annotations
+import json, sysconfig
from pathlib import Path
-import sysconfig
import typing as T
-from .. import mlog
+from .. import mesonlib, mlog
from .base import DependencyMethods, SystemDependency
from .factory import DependencyFactory
from ..environment import detect_cpu_family
+from ..programs import ExternalProgram
if T.TYPE_CHECKING:
+ from typing_extensions import TypedDict
+
from ..environment import Environment
+ class PythonIntrospectionDict(TypedDict):
+
+ install_paths: T.Dict[str, str]
+ is_pypy: bool
+ is_venv: bool
+ link_libpython: bool
+ sysconfig_paths: T.Dict[str, str]
+ paths: T.Dict[str, str]
+ platform: str
+ suffix: str
+ variables: T.Dict[str, str]
+ version: str
+
+
+class BasicPythonExternalProgram(ExternalProgram):
+ def __init__(self, name: str, command: T.Optional[T.List[str]] = None,
+ ext_prog: T.Optional[ExternalProgram] = None):
+ if ext_prog is None:
+ super().__init__(name, command=command, silent=True)
+ else:
+ self.name = name
+ self.command = ext_prog.command
+ self.path = ext_prog.path
+
+ # We want strong key values, so we always populate this with bogus data.
+ # Otherwise to make the type checkers happy we'd have to do .get() for
+ # everycall, even though we know that the introspection data will be
+ # complete
+ self.info: 'PythonIntrospectionDict' = {
+ 'install_paths': {},
+ 'is_pypy': False,
+ 'is_venv': False,
+ 'link_libpython': False,
+ 'sysconfig_paths': {},
+ 'paths': {},
+ 'platform': 'sentinal',
+ 'suffix': 'sentinel',
+ 'variables': {},
+ 'version': '0.0',
+ }
+ self.pure: bool = True
+
+ def _check_version(self, version: str) -> bool:
+ if self.name == 'python2':
+ return mesonlib.version_compare(version, '< 3.0')
+ elif self.name == 'python3':
+ return mesonlib.version_compare(version, '>= 3.0')
+ return True
+
+ def sanity(self) -> bool:
+ # Sanity check, we expect to have something that at least quacks in tune
+
+ import importlib.resources
+
+ with importlib.resources.path('mesonbuild.scripts', 'python_info.py') as f:
+ cmd = self.get_command() + [str(f)]
+ p, stdout, stderr = mesonlib.Popen_safe(cmd)
+
+ try:
+ info = json.loads(stdout)
+ except json.JSONDecodeError:
+ info = None
+ mlog.debug('Could not introspect Python (%s): exit code %d' % (str(p.args), p.returncode))
+ mlog.debug('Program stdout:\n')
+ mlog.debug(stdout)
+ mlog.debug('Program stderr:\n')
+ mlog.debug(stderr)
+
+ if info is not None and self._check_version(info['version']):
+ self.info = T.cast('PythonIntrospectionDict', info)
+ return True
+ else:
+ return False
+
class Python3DependencySystem(SystemDependency):
def __init__(self, name: str, environment: 'Environment', kwargs: T.Dict[str, T.Any]) -> None: