python module: cache dependency() lookup between invocations
Modeled similarly after the installations cache, but using the coredata dependency cache because it has a nice mechanism for handling the cache key.
This commit is contained in:
parent
ea952966b4
commit
43c60318fd
|
@ -11,6 +11,7 @@
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
# See the License for the specific language governing permissions and
|
# See the License for the specific language governing permissions and
|
||||||
# limitations under the License.
|
# limitations under the License.
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import functools
|
import functools
|
||||||
|
@ -26,6 +27,7 @@ from ..coredata import UserFeatureOption
|
||||||
from ..build import known_shmod_kwargs
|
from ..build import known_shmod_kwargs
|
||||||
from ..dependencies import DependencyMethods, PkgConfigDependency, NotFoundDependency, SystemDependency, ExtraFrameworkDependency
|
from ..dependencies import DependencyMethods, PkgConfigDependency, NotFoundDependency, SystemDependency, ExtraFrameworkDependency
|
||||||
from ..dependencies.base import process_method_kw
|
from ..dependencies.base import process_method_kw
|
||||||
|
from ..dependencies.detect import get_dep_identifier
|
||||||
from ..environment import detect_cpu_family
|
from ..environment import detect_cpu_family
|
||||||
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
|
from ..interpreter import ExternalProgramHolder, extract_required_kwarg, permitted_dependency_kwargs
|
||||||
from ..interpreter.type_checking import NoneType
|
from ..interpreter.type_checking import NoneType
|
||||||
|
@ -539,31 +541,41 @@ class PythonInstallation(ExternalProgramHolder):
|
||||||
|
|
||||||
return self.interpreter.func_shared_module(None, args, kwargs)
|
return self.interpreter.func_shared_module(None, args, kwargs)
|
||||||
|
|
||||||
|
def _dependency_method_impl(self, kwargs: TYPE_kwargs) -> Dependency:
|
||||||
|
for_machine = self.interpreter.machine_from_native_kwarg(kwargs)
|
||||||
|
identifier = get_dep_identifier(self._full_path(), kwargs)
|
||||||
|
|
||||||
|
dep = self.interpreter.coredata.deps[for_machine].get(identifier)
|
||||||
|
if dep is not None:
|
||||||
|
return dep
|
||||||
|
|
||||||
|
new_kwargs = kwargs.copy()
|
||||||
|
new_kwargs['required'] = False
|
||||||
|
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
|
||||||
|
# it's theoretically (though not practically) possible to not bind dep, let's ensure it is.
|
||||||
|
dep: Dependency = NotFoundDependency('python', self.interpreter.environment)
|
||||||
|
for d in python_factory(self.interpreter.environment, for_machine, new_kwargs, methods, self):
|
||||||
|
dep = d()
|
||||||
|
if dep.found():
|
||||||
|
break
|
||||||
|
|
||||||
|
self.interpreter.coredata.deps[for_machine].put(identifier, dep)
|
||||||
|
return dep
|
||||||
|
|
||||||
@disablerIfNotFound
|
@disablerIfNotFound
|
||||||
@permittedKwargs(permitted_dependency_kwargs | {'embed'})
|
@permittedKwargs(permitted_dependency_kwargs | {'embed'})
|
||||||
@FeatureNewKwargs('python_installation.dependency', '0.53.0', ['embed'])
|
@FeatureNewKwargs('python_installation.dependency', '0.53.0', ['embed'])
|
||||||
@noPosargs
|
@noPosargs
|
||||||
def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> 'Dependency':
|
def dependency_method(self, args: T.List['TYPE_var'], kwargs: 'TYPE_kwargs') -> 'Dependency':
|
||||||
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
|
disabled, required, feature = extract_required_kwarg(kwargs, self.subproject)
|
||||||
# it's theoretically (though not practically) possible for the else clse
|
|
||||||
# to not bind dep, let's ensure it is.
|
|
||||||
dep: 'Dependency' = NotFoundDependency('python', self.interpreter.environment)
|
|
||||||
if disabled:
|
if disabled:
|
||||||
mlog.log('Dependency', mlog.bold('python'), 'skipped: feature', mlog.bold(feature), 'disabled')
|
mlog.log('Dependency', mlog.bold('python'), 'skipped: feature', mlog.bold(feature), 'disabled')
|
||||||
|
return NotFoundDependency('python', self.interpreter.environment)
|
||||||
else:
|
else:
|
||||||
new_kwargs = kwargs.copy()
|
dep = self._dependency_method_impl(kwargs)
|
||||||
new_kwargs['required'] = False
|
|
||||||
methods = process_method_kw({DependencyMethods.PKGCONFIG, DependencyMethods.SYSTEM}, kwargs)
|
|
||||||
for d in python_factory(self.interpreter.environment,
|
|
||||||
MachineChoice.BUILD if kwargs.get('native', False) else MachineChoice.HOST,
|
|
||||||
new_kwargs, methods, self):
|
|
||||||
dep = d()
|
|
||||||
if dep.found():
|
|
||||||
break
|
|
||||||
if required and not dep.found():
|
if required and not dep.found():
|
||||||
raise mesonlib.MesonException('Python dependency not found')
|
raise mesonlib.MesonException('Python dependency not found')
|
||||||
|
return dep
|
||||||
return dep
|
|
||||||
|
|
||||||
@typed_pos_args('install_data', varargs=(str, mesonlib.File))
|
@typed_pos_args('install_data', varargs=(str, mesonlib.File))
|
||||||
@typed_kwargs('python_installation.install_sources', _PURE_KW, _SUBDIR_KW,
|
@typed_kwargs('python_installation.install_sources', _PURE_KW, _SUBDIR_KW,
|
||||||
|
|
Loading…
Reference in New Issue