From 153a7fb33240dc04f459147b418f58e30d448d56 Mon Sep 17 00:00:00 2001 From: Jon Turney Date: Sun, 14 Jan 2018 21:10:51 +0000 Subject: Fix unpickling of dynamic subclasses of ConfigToolDependency This code isn't used as present: the actual objects we use and which get pickled are either static subclasses of ConfigToolDependency, or special purpos subclasses of Dependency which get attributes copied from an instance of a dynamic subclass of ConfigToolDependency which is then discarded. This is fortunate, as it doesn't work: the pickled reduction is a call to the dynamic subclass's constructor, but the superclass constructors rely on the environment object being fully initialized, which hasn't happened yet during unpickling. Avoid this by having a pickled reduction which is just a call to create the dynamic subclass object, and relying on the default __setstate__ behavior to unpickle the object's __dict__. --- mesonbuild/dependencies/base.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/mesonbuild/dependencies/base.py b/mesonbuild/dependencies/base.py index fa50761..20a234d 100644 --- a/mesonbuild/dependencies/base.py +++ b/mesonbuild/dependencies/base.py @@ -236,14 +236,17 @@ class ConfigToolDependency(ExternalDependency): # instantiated and returned. The reduce function (method) is also # attached, since python's pickle module won't be able to do anything # with this dynamically generated class otherwise. - def reduce(_): - return (cls.factory, - (name, environment, language, kwargs, tools, tool_name)) + def reduce(self): + return (cls._unpickle, (), self.__dict__) sub = type('{}Dependency'.format(name.capitalize()), (cls, ), {'tools': tools, 'tool_name': tool_name, '__reduce__': reduce}) return sub(name, environment, language, kwargs) + @classmethod + def _unpickle(cls): + return cls.__new__(cls) + def find_config(self, versions=None): """Helper method that searchs for config tool binaries in PATH and returns the one that best matches the given version requirements. -- cgit v1.1