Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions docs/markdown/snippets/python-installation-pure.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
## python.find_installation() now accepts pure argument

The default value of `pure:` for `py.install_sources()` and
`py.get_install_dir()` can now be changed by explicitly passing a `pure:` kwarg
to `find_installation()`.

This can be used to ensure that multiple `install_sources()` invocations do not
forget to specify the kwarg each time.
17 changes: 13 additions & 4 deletions mesonbuild/modules/python.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
from __future__ import annotations

from pathlib import Path
import copy
import functools
import json
import os
Expand Down Expand Up @@ -67,14 +68,15 @@ class PythonIntrospectionDict(TypedDict):

class PyInstallKw(TypedDict):

pure: bool
pure: T.Optional[bool]
subdir: str
install_tag: T.Optional[str]

class FindInstallationKw(ExtractRequired):

disabler: bool
modules: T.List[str]
pure: T.Optional[bool]

_Base = ExternalDependency
else:
Expand Down Expand Up @@ -409,6 +411,7 @@ def __init__(self, name: str, command: T.Optional[T.List[str]] = None,
'variables': {},
'version': '0.0',
}
self.pure: bool = True

def _check_version(self, version: str) -> bool:
if self.name == 'python2':
Expand Down Expand Up @@ -472,7 +475,7 @@ def _get_path(self, state: T.Optional['ModuleState'], key: str) -> None:
return rel_path


_PURE_KW = KwargInfo('pure', bool, default=True)
_PURE_KW = KwargInfo('pure', (bool, NoneType))
Copy link
Member

@dcbaker dcbaker Sep 9, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need to update the TypedDict annotations as well, and there are two, bot the PytInstallKw is now wrong because pure is Optional, and the FindInstallationKw needs the pure kw added

_SUBDIR_KW = KwargInfo('subdir', str, default='')


Expand All @@ -485,6 +488,7 @@ def __init__(self, python: 'PythonExternalProgram', interpreter: 'Interpreter'):
self.variables = info['variables']
self.suffix = info['suffix']
self.paths = info['paths']
self.pure = python.pure
self.platlib_install_path = os.path.join(prefix, python.platlib)
self.purelib_install_path = os.path.join(prefix, python.purelib)
self.version = info['version']
Expand Down Expand Up @@ -599,7 +603,8 @@ def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') ->
def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File]]],
kwargs: 'PyInstallKw') -> 'Data':
tag = kwargs['install_tag'] or 'runtime'
install_dir = self._get_install_dir_impl(kwargs['pure'], kwargs['subdir'])
pure = kwargs['pure'] if kwargs['pure'] is not None else self.pure
install_dir = self._get_install_dir_impl(pure, kwargs['subdir'])
return self.interpreter.install_data_impl(
self.interpreter.source_strings_to_files(args[0]),
install_dir,
Expand All @@ -610,7 +615,8 @@ def install_sources_method(self, args: T.Tuple[T.List[T.Union[str, mesonlib.File
@noPosargs
@typed_kwargs('python_installation.install_dir', _PURE_KW, _SUBDIR_KW)
def get_install_dir_method(self, args: T.List['TYPE_var'], kwargs: 'PyInstallKw') -> str:
return self._get_install_dir_impl(kwargs['pure'], kwargs['subdir'])
pure = kwargs['pure'] if kwargs['pure'] is not None else self.pure
return self._get_install_dir_impl(pure, kwargs['subdir'])

def _get_install_dir_impl(self, pure: bool, subdir: str) -> P_OBJ.OptionString:
if pure:
Expand Down Expand Up @@ -733,6 +739,7 @@ def _find_installation_impl(self, state: 'ModuleState', display_name: str, name_
KwargInfo('required', (bool, UserFeatureOption), default=True),
KwargInfo('disabler', bool, default=False, since='0.49.0'),
KwargInfo('modules', ContainerTypeInfo(list, str), listify=True, default=[], since='0.51.0'),
_PURE_KW.evolve(default=True, since='0.64.0'),
)
def find_installation(self, state: 'ModuleState', args: T.Tuple[T.Optional[str]],
kwargs: 'FindInstallationKw') -> ExternalProgram:
Expand Down Expand Up @@ -797,6 +804,8 @@ def find_installation(self, state: 'ModuleState', args: T.Tuple[T.Optional[str]]
raise mesonlib.MesonException('{} is missing modules: {}'.format(name_or_path or 'python', ', '.join(missing_modules)))
return NonExistingExternalProgram()
else:
python = copy.copy(python)
python.pure = kwargs['pure']
return python

raise mesonlib.MesonBugException('Unreachable code was reached (PythonModule.find_installation).')
Expand Down
8 changes: 8 additions & 0 deletions test cases/python/7 install path/meson.build
Original file line number Diff line number Diff line change
Expand Up @@ -8,5 +8,13 @@ project('install path',
py = import('python').find_installation()
py.install_sources('test.py')
py.install_sources('test.py', pure: false)
install_data('test.py', install_dir: py.get_install_dir() / 'data')
install_data('test.py', install_dir: py.get_install_dir(pure: false) / 'data')

py_plat = import('python').find_installation(pure: false)
py_plat.install_sources('test.py', subdir: 'kw')
py_plat.install_sources('test.py', pure: true, subdir: 'kwrevert')
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

May be good to add a test file using get_install_dir as well?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@eli-schwartz I just discovered that this PR in its current state actually breaks get_install_dir(pure: false). To reproduce:

$ # use current SciPy `main`
$ meson setup build --prefix=$PWD/build-install
$ grep purelib build/meson-info/intro-install_plan.json | wc -l
# will give 0 with meson master, and 1 with this PR

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, that was dumb of me and happened because I didn't fully revert my first attempt.

install_data('test.py', install_dir: py_plat.get_install_dir() / 'kw/data')
install_data('test.py', install_dir: py_plat.get_install_dir(pure: true) / 'kwrevert/data')

subdir('structured')
8 changes: 7 additions & 1 deletion test cases/python/7 install path/test.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@
{"type": "file", "file": "pure/alpha/two.py"},
{"type": "file", "file": "pure/alpha/three.py"},
{"type": "file", "file": "pure/beta/one.py"},
{"type": "file", "file": "plat/kw/test.py"},
{"type": "file", "file": "pure/kwrevert/test.py"},
{"type": "file", "file": "plat/test.py"},
{"type": "file", "file": "pure/test.py"}
{"type": "file", "file": "pure/test.py"},
{"type": "file", "file": "plat/data/test.py"},
{"type": "file", "file": "pure/data/test.py"},
{"type": "file", "file": "plat/kw/data/test.py"},
{"type": "file", "file": "pure/kwrevert/data/test.py"}
]
}