@@ -196,7 +196,7 @@ def _factory():
196196
197197# Pre-defined set of builtin_function_or_method instances that can be
198198# serialized.
199- _BUILTIN_TYPE_ATTRS = {
199+ _BUILTIN_TYPE_CONSTRUCTORS = {
200200 dict .__new__ : _get_dict_new ,
201201 frozenset .__new__ : _get_frozenset_new ,
202202 set .__new__ : _get_set_new ,
@@ -332,6 +332,18 @@ def save_function(self, obj, name=None):
332332 Determines what kind of function obj is (e.g. lambda, defined at
333333 interactive prompt, etc) and handles the pickling appropriately.
334334 """
335+ if obj in _BUILTIN_TYPE_CONSTRUCTORS :
336+ # We keep a special-cased cache of built-in type constructors at
337+ # global scope, because these functions are structured very
338+ # differently in different python versions and implementations (for
339+ # example, they're instances of types.BuiltinFunctionType in
340+ # CPython, but they're ordinary types.FunctionType instances in
341+ # PyPy).
342+ #
343+ # If the function we've received is in that cache, we just
344+ # serialize it as a lookup into the cache.
345+ return self .save_reduce (_BUILTIN_TYPE_CONSTRUCTORS [obj ], (), obj = obj )
346+
335347 write = self .write
336348
337349 if name is None :
@@ -358,7 +370,7 @@ def save_function(self, obj, name=None):
358370 return self .save_global (obj , name )
359371
360372 # a builtin_function_or_method which comes in as an attribute of some
361- # object (e.g., object.__new__, itertools.chain.from_iterable) will end
373+ # object (e.g., itertools.chain.from_iterable) will end
362374 # up with modname "__main__" and so end up here. But these functions
363375 # have no __code__ attribute in CPython, so the handling for
364376 # user-defined functions below will fail.
@@ -605,8 +617,6 @@ def extract_func_data(self, func):
605617 def save_builtin_function (self , obj ):
606618 if obj .__module__ == "__builtin__" :
607619 return self .save_global (obj )
608- elif obj in _BUILTIN_TYPE_ATTRS :
609- return self .save_reduce (_BUILTIN_TYPE_ATTRS [obj ], (), obj = obj )
610620 return self .save_function (obj )
611621 dispatch [types .BuiltinFunctionType ] = save_builtin_function
612622
0 commit comments