cloudpickle.py 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384
  1. """
  2. This class is defined to override standard pickle functionality
  3. The goals of it follow:
  4. -Serialize lambdas and nested functions to compiled byte code
  5. -Deal with main module correctly
  6. -Deal with other non-serializable objects
  7. It does not include an unpickler, as standard python unpickling suffices.
  8. This module was extracted from the `cloud` package, developed by `PiCloud, Inc.
  9. <https://web.archive.org/web/20140626004012/http://www.picloud.com/>`_.
  10. Copyright (c) 2012, Regents of the University of California.
  11. Copyright (c) 2009 `PiCloud, Inc. <https://web.archive.org/web/20140626004012/http://www.picloud.com/>`_.
  12. All rights reserved.
  13. Redistribution and use in source and binary forms, with or without
  14. modification, are permitted provided that the following conditions
  15. are met:
  16. * Redistributions of source code must retain the above copyright
  17. notice, this list of conditions and the following disclaimer.
  18. * Redistributions in binary form must reproduce the above copyright
  19. notice, this list of conditions and the following disclaimer in the
  20. documentation and/or other materials provided with the distribution.
  21. * Neither the name of the University of California, Berkeley nor the
  22. names of its contributors may be used to endorse or promote
  23. products derived from this software without specific prior written
  24. permission.
  25. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  26. "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  27. LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  28. A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  29. HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  30. SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
  31. TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  32. PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
  33. LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
  34. NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
  35. SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  36. """
  37. from __future__ import print_function
  38. import abc
  39. import builtins
  40. import dis
  41. import io
  42. import itertools
  43. import logging
  44. import opcode
  45. import operator
  46. import pickle
  47. import platform
  48. import struct
  49. import sys
  50. import types
  51. import weakref
  52. import uuid
  53. import threading
  54. import typing
  55. from enum import Enum
  56. from typing import Generic, Union, Tuple, Callable
  57. from pickle import _Pickler as Pickler
  58. from pickle import _getattribute
  59. from io import BytesIO
  60. from importlib._bootstrap import _find_spec
  61. try: # pragma: no branch
  62. import typing_extensions as _typing_extensions
  63. from typing_extensions import Literal, Final
  64. except ImportError:
  65. _typing_extensions = Literal = Final = None
  66. if sys.version_info >= (3, 5, 3):
  67. from typing import ClassVar
  68. else: # pragma: no cover
  69. ClassVar = None
  70. # cloudpickle is meant for inter process communication: we expect all
  71. # communicating processes to run the same Python version hence we favor
  72. # communication speed over compatibility:
  73. DEFAULT_PROTOCOL = pickle.HIGHEST_PROTOCOL
  74. # Track the provenance of reconstructed dynamic classes to make it possible to
  75. # recontruct instances from the matching singleton class definition when
  76. # appropriate and preserve the usual "isinstance" semantics of Python objects.
  77. _DYNAMIC_CLASS_TRACKER_BY_CLASS = weakref.WeakKeyDictionary()
  78. _DYNAMIC_CLASS_TRACKER_BY_ID = weakref.WeakValueDictionary()
  79. _DYNAMIC_CLASS_TRACKER_LOCK = threading.Lock()
  80. PYPY = platform.python_implementation() == "PyPy"
  81. builtin_code_type = None
  82. if PYPY:
  83. # builtin-code objects only exist in pypy
  84. builtin_code_type = type(float.__new__.__code__)
  85. _extract_code_globals_cache = weakref.WeakKeyDictionary()
  86. def _get_or_create_tracker_id(class_def):
  87. with _DYNAMIC_CLASS_TRACKER_LOCK:
  88. class_tracker_id = _DYNAMIC_CLASS_TRACKER_BY_CLASS.get(class_def)
  89. if class_tracker_id is None:
  90. class_tracker_id = uuid.uuid4().hex
  91. _DYNAMIC_CLASS_TRACKER_BY_CLASS[class_def] = class_tracker_id
  92. _DYNAMIC_CLASS_TRACKER_BY_ID[class_tracker_id] = class_def
  93. return class_tracker_id
  94. def _lookup_class_or_track(class_tracker_id, class_def):
  95. if class_tracker_id is not None:
  96. with _DYNAMIC_CLASS_TRACKER_LOCK:
  97. class_def = _DYNAMIC_CLASS_TRACKER_BY_ID.setdefault(
  98. class_tracker_id, class_def)
  99. _DYNAMIC_CLASS_TRACKER_BY_CLASS[class_def] = class_tracker_id
  100. return class_def
  101. def _whichmodule(obj, name):
  102. """Find the module an object belongs to.
  103. This function differs from ``pickle.whichmodule`` in two ways:
  104. - it does not mangle the cases where obj's module is __main__ and obj was
  105. not found in any module.
  106. - Errors arising during module introspection are ignored, as those errors
  107. are considered unwanted side effects.
  108. """
  109. if sys.version_info[:2] < (3, 7) and isinstance(obj, typing.TypeVar): # pragma: no branch # noqa
  110. # Workaround bug in old Python versions: prior to Python 3.7,
  111. # T.__module__ would always be set to "typing" even when the TypeVar T
  112. # would be defined in a different module.
  113. #
  114. # For such older Python versions, we ignore the __module__ attribute of
  115. # TypeVar instances and instead exhaustively lookup those instances in
  116. # all currently imported modules.
  117. module_name = None
  118. else:
  119. module_name = getattr(obj, '__module__', None)
  120. if module_name is not None:
  121. return module_name
  122. # Protect the iteration by using a copy of sys.modules against dynamic
  123. # modules that trigger imports of other modules upon calls to getattr or
  124. # other threads importing at the same time.
  125. for module_name, module in sys.modules.copy().items():
  126. # Some modules such as coverage can inject non-module objects inside
  127. # sys.modules
  128. if (
  129. module_name == '__main__' or
  130. module is None or
  131. not isinstance(module, types.ModuleType)
  132. ):
  133. continue
  134. try:
  135. if _getattribute(module, name)[0] is obj:
  136. return module_name
  137. except Exception:
  138. pass
  139. return None
  140. def _is_importable_by_name(obj, name=None):
  141. """Determine if obj can be pickled as attribute of a file-backed module"""
  142. return _lookup_module_and_qualname(obj, name=name) is not None
  143. def _lookup_module_and_qualname(obj, name=None):
  144. if name is None:
  145. name = getattr(obj, '__qualname__', None)
  146. if name is None: # pragma: no cover
  147. # This used to be needed for Python 2.7 support but is probably not
  148. # needed anymore. However we keep the __name__ introspection in case
  149. # users of cloudpickle rely on this old behavior for unknown reasons.
  150. name = getattr(obj, '__name__', None)
  151. module_name = _whichmodule(obj, name)
  152. if module_name is None:
  153. # In this case, obj.__module__ is None AND obj was not found in any
  154. # imported module. obj is thus treated as dynamic.
  155. return None
  156. if module_name == "__main__":
  157. return None
  158. module = sys.modules.get(module_name, None)
  159. if module is None:
  160. # The main reason why obj's module would not be imported is that this
  161. # module has been dynamically created, using for example
  162. # types.ModuleType. The other possibility is that module was removed
  163. # from sys.modules after obj was created/imported. But this case is not
  164. # supported, as the standard pickle does not support it either.
  165. return None
  166. # module has been added to sys.modules, but it can still be dynamic.
  167. if _is_dynamic(module):
  168. return None
  169. try:
  170. obj2, parent = _getattribute(module, name)
  171. except AttributeError:
  172. # obj was not found inside the module it points to
  173. return None
  174. if obj2 is not obj:
  175. return None
  176. return module, name
  177. def _extract_code_globals(co):
  178. """
  179. Find all globals names read or written to by codeblock co
  180. """
  181. out_names = _extract_code_globals_cache.get(co)
  182. if out_names is None:
  183. names = co.co_names
  184. out_names = {names[oparg] for _, oparg in _walk_global_ops(co)}
  185. # Declaring a function inside another one using the "def ..."
  186. # syntax generates a constant code object corresonding to the one
  187. # of the nested function's As the nested function may itself need
  188. # global variables, we need to introspect its code, extract its
  189. # globals, (look for code object in it's co_consts attribute..) and
  190. # add the result to code_globals
  191. if co.co_consts:
  192. for const in co.co_consts:
  193. if isinstance(const, types.CodeType):
  194. out_names |= _extract_code_globals(const)
  195. _extract_code_globals_cache[co] = out_names
  196. return out_names
  197. def _find_imported_submodules(code, top_level_dependencies):
  198. """
  199. Find currently imported submodules used by a function.
  200. Submodules used by a function need to be detected and referenced for the
  201. function to work correctly at depickling time. Because submodules can be
  202. referenced as attribute of their parent package (``package.submodule``), we
  203. need a special introspection technique that does not rely on GLOBAL-related
  204. opcodes to find references of them in a code object.
  205. Example:
  206. ```
  207. import concurrent.futures
  208. import cloudpickle
  209. def func():
  210. x = concurrent.futures.ThreadPoolExecutor
  211. if __name__ == '__main__':
  212. cloudpickle.dumps(func)
  213. ```
  214. The globals extracted by cloudpickle in the function's state include the
  215. concurrent package, but not its submodule (here, concurrent.futures), which
  216. is the module used by func. Find_imported_submodules will detect the usage
  217. of concurrent.futures. Saving this module alongside with func will ensure
  218. that calling func once depickled does not fail due to concurrent.futures
  219. not being imported
  220. """
  221. subimports = []
  222. # check if any known dependency is an imported package
  223. for x in top_level_dependencies:
  224. if (isinstance(x, types.ModuleType) and
  225. hasattr(x, '__package__') and x.__package__):
  226. # check if the package has any currently loaded sub-imports
  227. prefix = x.__name__ + '.'
  228. # A concurrent thread could mutate sys.modules,
  229. # make sure we iterate over a copy to avoid exceptions
  230. for name in list(sys.modules):
  231. # Older versions of pytest will add a "None" module to
  232. # sys.modules.
  233. if name is not None and name.startswith(prefix):
  234. # check whether the function can address the sub-module
  235. tokens = set(name[len(prefix):].split('.'))
  236. if not tokens - set(code.co_names):
  237. subimports.append(sys.modules[name])
  238. return subimports
  239. def cell_set(cell, value):
  240. """Set the value of a closure cell.
  241. The point of this function is to set the cell_contents attribute of a cell
  242. after its creation. This operation is necessary in case the cell contains a
  243. reference to the function the cell belongs to, as when calling the
  244. function's constructor
  245. ``f = types.FunctionType(code, globals, name, argdefs, closure)``,
  246. closure will not be able to contain the yet-to-be-created f.
  247. In Python3.7, cell_contents is writeable, so setting the contents of a cell
  248. can be done simply using
  249. >>> cell.cell_contents = value
  250. In earlier Python3 versions, the cell_contents attribute of a cell is read
  251. only, but this limitation can be worked around by leveraging the Python 3
  252. ``nonlocal`` keyword.
  253. In Python2 however, this attribute is read only, and there is no
  254. ``nonlocal`` keyword. For this reason, we need to come up with more
  255. complicated hacks to set this attribute.
  256. The chosen approach is to create a function with a STORE_DEREF opcode,
  257. which sets the content of a closure variable. Typically:
  258. >>> def inner(value):
  259. ... lambda: cell # the lambda makes cell a closure
  260. ... cell = value # cell is a closure, so this triggers a STORE_DEREF
  261. (Note that in Python2, A STORE_DEREF can never be triggered from an inner
  262. function. The function g for example here
  263. >>> def f(var):
  264. ... def g():
  265. ... var += 1
  266. ... return g
  267. will not modify the closure variable ``var```inplace, but instead try to
  268. load a local variable var and increment it. As g does not assign the local
  269. variable ``var`` any initial value, calling f(1)() will fail at runtime.)
  270. Our objective is to set the value of a given cell ``cell``. So we need to
  271. somewhat reference our ``cell`` object into the ``inner`` function so that
  272. this object (and not the smoke cell of the lambda function) gets affected
  273. by the STORE_DEREF operation.
  274. In inner, ``cell`` is referenced as a cell variable (an enclosing variable
  275. that is referenced by the inner function). If we create a new function
  276. cell_set with the exact same code as ``inner``, but with ``cell`` marked as
  277. a free variable instead, the STORE_DEREF will be applied on its closure -
  278. ``cell``, which we can specify explicitly during construction! The new
  279. cell_set variable thus actually sets the contents of a specified cell!
  280. Note: we do not make use of the ``nonlocal`` keyword to set the contents of
  281. a cell in early python3 versions to limit possible syntax errors in case
  282. test and checker libraries decide to parse the whole file.
  283. """
  284. if sys.version_info[:2] >= (3, 7): # pragma: no branch
  285. cell.cell_contents = value
  286. else:
  287. _cell_set = types.FunctionType(
  288. _cell_set_template_code, {}, '_cell_set', (), (cell,),)
  289. _cell_set(value)
  290. def _make_cell_set_template_code():
  291. def _cell_set_factory(value):
  292. lambda: cell
  293. cell = value
  294. co = _cell_set_factory.__code__
  295. _cell_set_template_code = types.CodeType(
  296. co.co_argcount,
  297. co.co_kwonlyargcount, # Python 3 only argument
  298. co.co_nlocals,
  299. co.co_stacksize,
  300. co.co_flags,
  301. co.co_code,
  302. co.co_consts,
  303. co.co_names,
  304. co.co_varnames,
  305. co.co_filename,
  306. co.co_name,
  307. co.co_firstlineno,
  308. co.co_lnotab,
  309. co.co_cellvars, # co_freevars is initialized with co_cellvars
  310. (), # co_cellvars is made empty
  311. )
  312. return _cell_set_template_code
  313. if sys.version_info[:2] < (3, 7):
  314. _cell_set_template_code = _make_cell_set_template_code()
  315. # relevant opcodes
  316. STORE_GLOBAL = opcode.opmap['STORE_GLOBAL']
  317. DELETE_GLOBAL = opcode.opmap['DELETE_GLOBAL']
  318. LOAD_GLOBAL = opcode.opmap['LOAD_GLOBAL']
  319. GLOBAL_OPS = (STORE_GLOBAL, DELETE_GLOBAL, LOAD_GLOBAL)
  320. HAVE_ARGUMENT = dis.HAVE_ARGUMENT
  321. EXTENDED_ARG = dis.EXTENDED_ARG
  322. _BUILTIN_TYPE_NAMES = {}
  323. for k, v in types.__dict__.items():
  324. if type(v) is type:
  325. _BUILTIN_TYPE_NAMES[v] = k
  326. def _builtin_type(name):
  327. if name == "ClassType": # pragma: no cover
  328. # Backward compat to load pickle files generated with cloudpickle
  329. # < 1.3 even if loading pickle files from older versions is not
  330. # officially supported.
  331. return type
  332. return getattr(types, name)
  333. def _walk_global_ops(code):
  334. """
  335. Yield (opcode, argument number) tuples for all
  336. global-referencing instructions in *code*.
  337. """
  338. for instr in dis.get_instructions(code):
  339. op = instr.opcode
  340. if op in GLOBAL_OPS:
  341. yield op, instr.arg
  342. def _extract_class_dict(cls):
  343. """Retrieve a copy of the dict of a class without the inherited methods"""
  344. clsdict = dict(cls.__dict__) # copy dict proxy to a dict
  345. if len(cls.__bases__) == 1:
  346. inherited_dict = cls.__bases__[0].__dict__
  347. else:
  348. inherited_dict = {}
  349. for base in reversed(cls.__bases__):
  350. inherited_dict.update(base.__dict__)
  351. to_remove = []
  352. for name, value in clsdict.items():
  353. try:
  354. base_value = inherited_dict[name]
  355. if value is base_value:
  356. to_remove.append(name)
  357. except KeyError:
  358. pass
  359. for name in to_remove:
  360. clsdict.pop(name)
  361. return clsdict
  362. if sys.version_info[:2] < (3, 7): # pragma: no branch
  363. def _is_parametrized_type_hint(obj):
  364. # This is very cheap but might generate false positives.
  365. # general typing Constructs
  366. is_typing = getattr(obj, '__origin__', None) is not None
  367. # typing_extensions.Literal
  368. is_litteral = getattr(obj, '__values__', None) is not None
  369. # typing_extensions.Final
  370. is_final = getattr(obj, '__type__', None) is not None
  371. # typing.Union/Tuple for old Python 3.5
  372. is_union = getattr(obj, '__union_params__', None) is not None
  373. is_tuple = getattr(obj, '__tuple_params__', None) is not None
  374. is_callable = (
  375. getattr(obj, '__result__', None) is not None and
  376. getattr(obj, '__args__', None) is not None
  377. )
  378. return any((is_typing, is_litteral, is_final, is_union, is_tuple,
  379. is_callable))
  380. def _create_parametrized_type_hint(origin, args):
  381. return origin[args]
  382. class CloudPickler(Pickler):
  383. dispatch = Pickler.dispatch.copy()
  384. def __init__(self, file, protocol=None):
  385. if protocol is None:
  386. protocol = DEFAULT_PROTOCOL
  387. Pickler.__init__(self, file, protocol=protocol)
  388. # map ids to dictionary. used to ensure that functions can share global env
  389. self.globals_ref = {}
  390. def dump(self, obj):
  391. self.inject_addons()
  392. try:
  393. return Pickler.dump(self, obj)
  394. except RuntimeError as e:
  395. if 'recursion' in e.args[0]:
  396. msg = """Could not pickle object as excessively deep recursion required."""
  397. raise pickle.PicklingError(msg)
  398. else:
  399. raise
  400. def save_typevar(self, obj):
  401. self.save_reduce(*_typevar_reduce(obj), obj=obj)
  402. dispatch[typing.TypeVar] = save_typevar
  403. def save_memoryview(self, obj):
  404. self.save(obj.tobytes())
  405. dispatch[memoryview] = save_memoryview
  406. def save_module(self, obj):
  407. """
  408. Save a module as an import
  409. """
  410. if _is_dynamic(obj):
  411. obj.__dict__.pop('__builtins__', None)
  412. self.save_reduce(dynamic_subimport, (obj.__name__, vars(obj)),
  413. obj=obj)
  414. else:
  415. self.save_reduce(subimport, (obj.__name__,), obj=obj)
  416. dispatch[types.ModuleType] = save_module
  417. def save_codeobject(self, obj):
  418. """
  419. Save a code object
  420. """
  421. if hasattr(obj, "co_posonlyargcount"): # pragma: no branch
  422. args = (
  423. obj.co_argcount, obj.co_posonlyargcount,
  424. obj.co_kwonlyargcount, obj.co_nlocals, obj.co_stacksize,
  425. obj.co_flags, obj.co_code, obj.co_consts, obj.co_names,
  426. obj.co_varnames, obj.co_filename, obj.co_name,
  427. obj.co_firstlineno, obj.co_lnotab, obj.co_freevars,
  428. obj.co_cellvars
  429. )
  430. else:
  431. args = (
  432. obj.co_argcount, obj.co_kwonlyargcount, obj.co_nlocals,
  433. obj.co_stacksize, obj.co_flags, obj.co_code, obj.co_consts,
  434. obj.co_names, obj.co_varnames, obj.co_filename,
  435. obj.co_name, obj.co_firstlineno, obj.co_lnotab,
  436. obj.co_freevars, obj.co_cellvars
  437. )
  438. self.save_reduce(types.CodeType, args, obj=obj)
  439. dispatch[types.CodeType] = save_codeobject
  440. def save_function(self, obj, name=None):
  441. """ Registered with the dispatch to handle all function types.
  442. Determines what kind of function obj is (e.g. lambda, defined at
  443. interactive prompt, etc) and handles the pickling appropriately.
  444. """
  445. if _is_importable_by_name(obj, name=name):
  446. return Pickler.save_global(self, obj, name=name)
  447. elif PYPY and isinstance(obj.__code__, builtin_code_type):
  448. return self.save_pypy_builtin_func(obj)
  449. else:
  450. return self.save_function_tuple(obj)
  451. dispatch[types.FunctionType] = save_function
  452. def save_pypy_builtin_func(self, obj):
  453. """Save pypy equivalent of builtin functions.
  454. PyPy does not have the concept of builtin-functions. Instead,
  455. builtin-functions are simple function instances, but with a
  456. builtin-code attribute.
  457. Most of the time, builtin functions should be pickled by attribute. But
  458. PyPy has flaky support for __qualname__, so some builtin functions such
  459. as float.__new__ will be classified as dynamic. For this reason only,
  460. we created this special routine. Because builtin-functions are not
  461. expected to have closure or globals, there is no additional hack
  462. (compared the one already implemented in pickle) to protect ourselves
  463. from reference cycles. A simple (reconstructor, newargs, obj.__dict__)
  464. tuple is save_reduced.
  465. Note also that PyPy improved their support for __qualname__ in v3.6, so
  466. this routing should be removed when cloudpickle supports only PyPy 3.6
  467. and later.
  468. """
  469. rv = (types.FunctionType, (obj.__code__, {}, obj.__name__,
  470. obj.__defaults__, obj.__closure__),
  471. obj.__dict__)
  472. self.save_reduce(*rv, obj=obj)
  473. def _save_dynamic_enum(self, obj, clsdict):
  474. """Special handling for dynamic Enum subclasses
  475. Use a dedicated Enum constructor (inspired by EnumMeta.__call__) as the
  476. EnumMeta metaclass has complex initialization that makes the Enum
  477. subclasses hold references to their own instances.
  478. """
  479. members = dict((e.name, e.value) for e in obj)
  480. self.save_reduce(
  481. _make_skeleton_enum,
  482. (obj.__bases__, obj.__name__, obj.__qualname__,
  483. members, obj.__module__, _get_or_create_tracker_id(obj), None),
  484. obj=obj
  485. )
  486. # Cleanup the clsdict that will be passed to _rehydrate_skeleton_class:
  487. # Those attributes are already handled by the metaclass.
  488. for attrname in ["_generate_next_value_", "_member_names_",
  489. "_member_map_", "_member_type_",
  490. "_value2member_map_"]:
  491. clsdict.pop(attrname, None)
  492. for member in members:
  493. clsdict.pop(member)
  494. def save_dynamic_class(self, obj):
  495. """Save a class that can't be stored as module global.
  496. This method is used to serialize classes that are defined inside
  497. functions, or that otherwise can't be serialized as attribute lookups
  498. from global modules.
  499. """
  500. clsdict = _extract_class_dict(obj)
  501. clsdict.pop('__weakref__', None)
  502. if issubclass(type(obj), abc.ABCMeta):
  503. # If obj is an instance of an ABCMeta subclass, dont pickle the
  504. # cache/negative caches populated during isinstance/issubclass
  505. # checks, but pickle the list of registered subclasses of obj.
  506. clsdict.pop('_abc_cache', None)
  507. clsdict.pop('_abc_negative_cache', None)
  508. clsdict.pop('_abc_negative_cache_version', None)
  509. registry = clsdict.pop('_abc_registry', None)
  510. if registry is None:
  511. # in Python3.7+, the abc caches and registered subclasses of a
  512. # class are bundled into the single _abc_impl attribute
  513. clsdict.pop('_abc_impl', None)
  514. (registry, _, _, _) = abc._get_dump(obj)
  515. clsdict["_abc_impl"] = [subclass_weakref()
  516. for subclass_weakref in registry]
  517. else:
  518. # In the above if clause, registry is a set of weakrefs -- in
  519. # this case, registry is a WeakSet
  520. clsdict["_abc_impl"] = [type_ for type_ in registry]
  521. # On PyPy, __doc__ is a readonly attribute, so we need to include it in
  522. # the initial skeleton class. This is safe because we know that the
  523. # doc can't participate in a cycle with the original class.
  524. type_kwargs = {'__doc__': clsdict.pop('__doc__', None)}
  525. if "__slots__" in clsdict:
  526. type_kwargs['__slots__'] = obj.__slots__
  527. # pickle string length optimization: member descriptors of obj are
  528. # created automatically from obj's __slots__ attribute, no need to
  529. # save them in obj's state
  530. if isinstance(obj.__slots__, str):
  531. clsdict.pop(obj.__slots__)
  532. else:
  533. for k in obj.__slots__:
  534. clsdict.pop(k, None)
  535. # If type overrides __dict__ as a property, include it in the type
  536. # kwargs. In Python 2, we can't set this attribute after construction.
  537. # XXX: can this ever happen in Python 3? If so add a test.
  538. __dict__ = clsdict.pop('__dict__', None)
  539. if isinstance(__dict__, property):
  540. type_kwargs['__dict__'] = __dict__
  541. save = self.save
  542. write = self.write
  543. # We write pickle instructions explicitly here to handle the
  544. # possibility that the type object participates in a cycle with its own
  545. # __dict__. We first write an empty "skeleton" version of the class and
  546. # memoize it before writing the class' __dict__ itself. We then write
  547. # instructions to "rehydrate" the skeleton class by restoring the
  548. # attributes from the __dict__.
  549. #
  550. # A type can appear in a cycle with its __dict__ if an instance of the
  551. # type appears in the type's __dict__ (which happens for the stdlib
  552. # Enum class), or if the type defines methods that close over the name
  553. # of the type, (which is common for Python 2-style super() calls).
  554. # Push the rehydration function.
  555. save(_rehydrate_skeleton_class)
  556. # Mark the start of the args tuple for the rehydration function.
  557. write(pickle.MARK)
  558. # Create and memoize an skeleton class with obj's name and bases.
  559. if Enum is not None and issubclass(obj, Enum):
  560. # Special handling of Enum subclasses
  561. self._save_dynamic_enum(obj, clsdict)
  562. else:
  563. # "Regular" class definition:
  564. tp = type(obj)
  565. self.save_reduce(_make_skeleton_class,
  566. (tp, obj.__name__, _get_bases(obj), type_kwargs,
  567. _get_or_create_tracker_id(obj), None),
  568. obj=obj)
  569. # Now save the rest of obj's __dict__. Any references to obj
  570. # encountered while saving will point to the skeleton class.
  571. save(clsdict)
  572. # Write a tuple of (skeleton_class, clsdict).
  573. write(pickle.TUPLE)
  574. # Call _rehydrate_skeleton_class(skeleton_class, clsdict)
  575. write(pickle.REDUCE)
  576. def save_function_tuple(self, func):
  577. """ Pickles an actual func object.
  578. A func comprises: code, globals, defaults, closure, and dict. We
  579. extract and save these, injecting reducing functions at certain points
  580. to recreate the func object. Keep in mind that some of these pieces
  581. can contain a ref to the func itself. Thus, a naive save on these
  582. pieces could trigger an infinite loop of save's. To get around that,
  583. we first create a skeleton func object using just the code (this is
  584. safe, since this won't contain a ref to the func), and memoize it as
  585. soon as it's created. The other stuff can then be filled in later.
  586. """
  587. if is_tornado_coroutine(func):
  588. self.save_reduce(_rebuild_tornado_coroutine, (func.__wrapped__,),
  589. obj=func)
  590. return
  591. save = self.save
  592. write = self.write
  593. code, f_globals, defaults, closure_values, dct, base_globals = self.extract_func_data(func)
  594. save(_fill_function) # skeleton function updater
  595. write(pickle.MARK) # beginning of tuple that _fill_function expects
  596. # Extract currently-imported submodules used by func. Storing these
  597. # modules in a smoke _cloudpickle_subimports attribute of the object's
  598. # state will trigger the side effect of importing these modules at
  599. # unpickling time (which is necessary for func to work correctly once
  600. # depickled)
  601. submodules = _find_imported_submodules(
  602. code,
  603. itertools.chain(f_globals.values(), closure_values or ()),
  604. )
  605. # create a skeleton function object and memoize it
  606. save(_make_skel_func)
  607. save((
  608. code,
  609. len(closure_values) if closure_values is not None else -1,
  610. base_globals,
  611. ))
  612. write(pickle.REDUCE)
  613. self.memoize(func)
  614. # save the rest of the func data needed by _fill_function
  615. state = {
  616. 'globals': f_globals,
  617. 'defaults': defaults,
  618. 'dict': dct,
  619. 'closure_values': closure_values,
  620. 'module': func.__module__,
  621. 'name': func.__name__,
  622. 'doc': func.__doc__,
  623. '_cloudpickle_submodules': submodules
  624. }
  625. if hasattr(func, '__annotations__'):
  626. state['annotations'] = func.__annotations__
  627. if hasattr(func, '__qualname__'):
  628. state['qualname'] = func.__qualname__
  629. if hasattr(func, '__kwdefaults__'):
  630. state['kwdefaults'] = func.__kwdefaults__
  631. save(state)
  632. write(pickle.TUPLE)
  633. write(pickle.REDUCE) # applies _fill_function on the tuple
  634. def extract_func_data(self, func):
  635. """
  636. Turn the function into a tuple of data necessary to recreate it:
  637. code, globals, defaults, closure_values, dict
  638. """
  639. code = func.__code__
  640. # extract all global ref's
  641. func_global_refs = _extract_code_globals(code)
  642. # process all variables referenced by global environment
  643. f_globals = {}
  644. for var in func_global_refs:
  645. if var in func.__globals__:
  646. f_globals[var] = func.__globals__[var]
  647. # defaults requires no processing
  648. defaults = func.__defaults__
  649. # process closure
  650. closure = (
  651. list(map(_get_cell_contents, func.__closure__))
  652. if func.__closure__ is not None
  653. else None
  654. )
  655. # save the dict
  656. dct = func.__dict__
  657. # base_globals represents the future global namespace of func at
  658. # unpickling time. Looking it up and storing it in globals_ref allow
  659. # functions sharing the same globals at pickling time to also
  660. # share them once unpickled, at one condition: since globals_ref is
  661. # an attribute of a Cloudpickler instance, and that a new CloudPickler is
  662. # created each time pickle.dump or pickle.dumps is called, functions
  663. # also need to be saved within the same invokation of
  664. # cloudpickle.dump/cloudpickle.dumps (for example: cloudpickle.dumps([f1, f2])). There
  665. # is no such limitation when using Cloudpickler.dump, as long as the
  666. # multiple invokations are bound to the same Cloudpickler.
  667. base_globals = self.globals_ref.setdefault(id(func.__globals__), {})
  668. if base_globals == {}:
  669. # Add module attributes used to resolve relative imports
  670. # instructions inside func.
  671. for k in ["__package__", "__name__", "__path__", "__file__"]:
  672. # Some built-in functions/methods such as object.__new__ have
  673. # their __globals__ set to None in PyPy
  674. if func.__globals__ is not None and k in func.__globals__:
  675. base_globals[k] = func.__globals__[k]
  676. return (code, f_globals, defaults, closure, dct, base_globals)
  677. def save_getset_descriptor(self, obj):
  678. return self.save_reduce(getattr, (obj.__objclass__, obj.__name__))
  679. dispatch[types.GetSetDescriptorType] = save_getset_descriptor
  680. def save_global(self, obj, name=None, pack=struct.pack):
  681. """
  682. Save a "global".
  683. The name of this method is somewhat misleading: all types get
  684. dispatched here.
  685. """
  686. if obj is type(None):
  687. return self.save_reduce(type, (None,), obj=obj)
  688. elif obj is type(Ellipsis):
  689. return self.save_reduce(type, (Ellipsis,), obj=obj)
  690. elif obj is type(NotImplemented):
  691. return self.save_reduce(type, (NotImplemented,), obj=obj)
  692. elif obj in _BUILTIN_TYPE_NAMES:
  693. return self.save_reduce(
  694. _builtin_type, (_BUILTIN_TYPE_NAMES[obj],), obj=obj)
  695. if sys.version_info[:2] < (3, 7) and _is_parametrized_type_hint(obj): # noqa # pragma: no branch
  696. # Parametrized typing constructs in Python < 3.7 are not compatible
  697. # with type checks and ``isinstance`` semantics. For this reason,
  698. # it is easier to detect them using a duck-typing-based check
  699. # (``_is_parametrized_type_hint``) than to populate the Pickler's
  700. # dispatch with type-specific savers.
  701. self._save_parametrized_type_hint(obj)
  702. elif name is not None:
  703. Pickler.save_global(self, obj, name=name)
  704. elif not _is_importable_by_name(obj, name=name):
  705. self.save_dynamic_class(obj)
  706. else:
  707. Pickler.save_global(self, obj, name=name)
  708. dispatch[type] = save_global
  709. def save_instancemethod(self, obj):
  710. # Memoization rarely is ever useful due to python bounding
  711. if obj.__self__ is None:
  712. self.save_reduce(getattr, (obj.im_class, obj.__name__))
  713. else:
  714. self.save_reduce(types.MethodType, (obj.__func__, obj.__self__), obj=obj)
  715. dispatch[types.MethodType] = save_instancemethod
  716. def save_property(self, obj):
  717. # properties not correctly saved in python
  718. self.save_reduce(property, (obj.fget, obj.fset, obj.fdel, obj.__doc__),
  719. obj=obj)
  720. dispatch[property] = save_property
  721. def save_classmethod(self, obj):
  722. orig_func = obj.__func__
  723. self.save_reduce(type(obj), (orig_func,), obj=obj)
  724. dispatch[classmethod] = save_classmethod
  725. dispatch[staticmethod] = save_classmethod
  726. def save_itemgetter(self, obj):
  727. """itemgetter serializer (needed for namedtuple support)"""
  728. class Dummy:
  729. def __getitem__(self, item):
  730. return item
  731. items = obj(Dummy())
  732. if not isinstance(items, tuple):
  733. items = (items,)
  734. return self.save_reduce(operator.itemgetter, items)
  735. if type(operator.itemgetter) is type:
  736. dispatch[operator.itemgetter] = save_itemgetter
  737. def save_attrgetter(self, obj):
  738. """attrgetter serializer"""
  739. class Dummy(object):
  740. def __init__(self, attrs, index=None):
  741. self.attrs = attrs
  742. self.index = index
  743. def __getattribute__(self, item):
  744. attrs = object.__getattribute__(self, "attrs")
  745. index = object.__getattribute__(self, "index")
  746. if index is None:
  747. index = len(attrs)
  748. attrs.append(item)
  749. else:
  750. attrs[index] = ".".join([attrs[index], item])
  751. return type(self)(attrs, index)
  752. attrs = []
  753. obj(Dummy(attrs))
  754. return self.save_reduce(operator.attrgetter, tuple(attrs))
  755. if type(operator.attrgetter) is type:
  756. dispatch[operator.attrgetter] = save_attrgetter
  757. def save_file(self, obj):
  758. """Save a file"""
  759. if not hasattr(obj, 'name') or not hasattr(obj, 'mode'):
  760. raise pickle.PicklingError("Cannot pickle files that do not map to an actual file")
  761. if obj is sys.stdout:
  762. return self.save_reduce(getattr, (sys, 'stdout'), obj=obj)
  763. if obj is sys.stderr:
  764. return self.save_reduce(getattr, (sys, 'stderr'), obj=obj)
  765. if obj is sys.stdin:
  766. raise pickle.PicklingError("Cannot pickle standard input")
  767. if obj.closed:
  768. raise pickle.PicklingError("Cannot pickle closed files")
  769. if hasattr(obj, 'isatty') and obj.isatty():
  770. raise pickle.PicklingError("Cannot pickle files that map to tty objects")
  771. if 'r' not in obj.mode and '+' not in obj.mode:
  772. raise pickle.PicklingError("Cannot pickle files that are not opened for reading: %s" % obj.mode)
  773. name = obj.name
  774. # TODO: also support binary mode files with io.BytesIO
  775. retval = io.StringIO()
  776. try:
  777. # Read the whole file
  778. curloc = obj.tell()
  779. obj.seek(0)
  780. contents = obj.read()
  781. obj.seek(curloc)
  782. except IOError:
  783. raise pickle.PicklingError("Cannot pickle file %s as it cannot be read" % name)
  784. retval.write(contents)
  785. retval.seek(curloc)
  786. retval.name = name
  787. self.save(retval)
  788. self.memoize(obj)
  789. def save_ellipsis(self, obj):
  790. self.save_reduce(_gen_ellipsis, ())
  791. def save_not_implemented(self, obj):
  792. self.save_reduce(_gen_not_implemented, ())
  793. dispatch[io.TextIOWrapper] = save_file
  794. dispatch[type(Ellipsis)] = save_ellipsis
  795. dispatch[type(NotImplemented)] = save_not_implemented
  796. def save_weakset(self, obj):
  797. self.save_reduce(weakref.WeakSet, (list(obj),))
  798. dispatch[weakref.WeakSet] = save_weakset
  799. def save_logger(self, obj):
  800. self.save_reduce(logging.getLogger, (obj.name,), obj=obj)
  801. dispatch[logging.Logger] = save_logger
  802. def save_root_logger(self, obj):
  803. self.save_reduce(logging.getLogger, (), obj=obj)
  804. dispatch[logging.RootLogger] = save_root_logger
  805. if hasattr(types, "MappingProxyType"): # pragma: no branch
  806. def save_mappingproxy(self, obj):
  807. self.save_reduce(types.MappingProxyType, (dict(obj),), obj=obj)
  808. dispatch[types.MappingProxyType] = save_mappingproxy
  809. """Special functions for Add-on libraries"""
  810. def inject_addons(self):
  811. """Plug in system. Register additional pickling functions if modules already loaded"""
  812. pass
  813. if sys.version_info < (3, 7): # pragma: no branch
  814. def _save_parametrized_type_hint(self, obj):
  815. # The distorted type check sematic for typing construct becomes:
  816. # ``type(obj) is type(TypeHint)``, which means "obj is a
  817. # parametrized TypeHint"
  818. if type(obj) is type(Literal): # pragma: no branch
  819. initargs = (Literal, obj.__values__)
  820. elif type(obj) is type(Final): # pragma: no branch
  821. initargs = (Final, obj.__type__)
  822. elif type(obj) is type(ClassVar):
  823. initargs = (ClassVar, obj.__type__)
  824. elif type(obj) is type(Generic):
  825. parameters = obj.__parameters__
  826. if len(obj.__parameters__) > 0:
  827. # in early Python 3.5, __parameters__ was sometimes
  828. # preferred to __args__
  829. initargs = (obj.__origin__, parameters)
  830. else:
  831. initargs = (obj.__origin__, obj.__args__)
  832. elif type(obj) is type(Union):
  833. if sys.version_info < (3, 5, 3): # pragma: no cover
  834. initargs = (Union, obj.__union_params__)
  835. else:
  836. initargs = (Union, obj.__args__)
  837. elif type(obj) is type(Tuple):
  838. if sys.version_info < (3, 5, 3): # pragma: no cover
  839. initargs = (Tuple, obj.__tuple_params__)
  840. else:
  841. initargs = (Tuple, obj.__args__)
  842. elif type(obj) is type(Callable):
  843. if sys.version_info < (3, 5, 3): # pragma: no cover
  844. args = obj.__args__
  845. result = obj.__result__
  846. if args != Ellipsis:
  847. if isinstance(args, tuple):
  848. args = list(args)
  849. else:
  850. args = [args]
  851. else:
  852. (*args, result) = obj.__args__
  853. if len(args) == 1 and args[0] is Ellipsis:
  854. args = Ellipsis
  855. else:
  856. args = list(args)
  857. initargs = (Callable, (args, result))
  858. else: # pragma: no cover
  859. raise pickle.PicklingError(
  860. "Cloudpickle Error: Unknown type {}".format(type(obj))
  861. )
  862. self.save_reduce(_create_parametrized_type_hint, initargs, obj=obj)
  863. # Tornado support
  864. def is_tornado_coroutine(func):
  865. """
  866. Return whether *func* is a Tornado coroutine function.
  867. Running coroutines are not supported.
  868. """
  869. if 'tornado.gen' not in sys.modules:
  870. return False
  871. gen = sys.modules['tornado.gen']
  872. if not hasattr(gen, "is_coroutine_function"):
  873. # Tornado version is too old
  874. return False
  875. return gen.is_coroutine_function(func)
  876. def _rebuild_tornado_coroutine(func):
  877. from tornado import gen
  878. return gen.coroutine(func)
  879. # Shorthands for legacy support
  880. def dump(obj, file, protocol=None):
  881. """Serialize obj as bytes streamed into file
  882. protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to
  883. pickle.HIGHEST_PROTOCOL. This setting favors maximum communication speed
  884. between processes running the same Python version.
  885. Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure
  886. compatibility with older versions of Python.
  887. """
  888. CloudPickler(file, protocol=protocol).dump(obj)
  889. def dumps(obj, protocol=None):
  890. """Serialize obj as a string of bytes allocated in memory
  891. protocol defaults to cloudpickle.DEFAULT_PROTOCOL which is an alias to
  892. pickle.HIGHEST_PROTOCOL. This setting favors maximum communication speed
  893. between processes running the same Python version.
  894. Set protocol=pickle.DEFAULT_PROTOCOL instead if you need to ensure
  895. compatibility with older versions of Python.
  896. """
  897. file = BytesIO()
  898. try:
  899. cp = CloudPickler(file, protocol=protocol)
  900. cp.dump(obj)
  901. return file.getvalue()
  902. finally:
  903. file.close()
  904. # including pickles unloading functions in this namespace
  905. load = pickle.load
  906. loads = pickle.loads
  907. # hack for __import__ not working as desired
  908. def subimport(name):
  909. __import__(name)
  910. return sys.modules[name]
  911. def dynamic_subimport(name, vars):
  912. mod = types.ModuleType(name)
  913. mod.__dict__.update(vars)
  914. mod.__dict__['__builtins__'] = builtins.__dict__
  915. return mod
  916. def _gen_ellipsis():
  917. return Ellipsis
  918. def _gen_not_implemented():
  919. return NotImplemented
  920. def _get_cell_contents(cell):
  921. try:
  922. return cell.cell_contents
  923. except ValueError:
  924. # sentinel used by ``_fill_function`` which will leave the cell empty
  925. return _empty_cell_value
  926. def instance(cls):
  927. """Create a new instance of a class.
  928. Parameters
  929. ----------
  930. cls : type
  931. The class to create an instance of.
  932. Returns
  933. -------
  934. instance : cls
  935. A new instance of ``cls``.
  936. """
  937. return cls()
  938. @instance
  939. class _empty_cell_value(object):
  940. """sentinel for empty closures
  941. """
  942. @classmethod
  943. def __reduce__(cls):
  944. return cls.__name__
  945. def _fill_function(*args):
  946. """Fills in the rest of function data into the skeleton function object
  947. The skeleton itself is create by _make_skel_func().
  948. """
  949. if len(args) == 2:
  950. func = args[0]
  951. state = args[1]
  952. elif len(args) == 5:
  953. # Backwards compat for cloudpickle v0.4.0, after which the `module`
  954. # argument was introduced
  955. func = args[0]
  956. keys = ['globals', 'defaults', 'dict', 'closure_values']
  957. state = dict(zip(keys, args[1:]))
  958. elif len(args) == 6:
  959. # Backwards compat for cloudpickle v0.4.1, after which the function
  960. # state was passed as a dict to the _fill_function it-self.
  961. func = args[0]
  962. keys = ['globals', 'defaults', 'dict', 'module', 'closure_values']
  963. state = dict(zip(keys, args[1:]))
  964. else:
  965. raise ValueError('Unexpected _fill_value arguments: %r' % (args,))
  966. # - At pickling time, any dynamic global variable used by func is
  967. # serialized by value (in state['globals']).
  968. # - At unpickling time, func's __globals__ attribute is initialized by
  969. # first retrieving an empty isolated namespace that will be shared
  970. # with other functions pickled from the same original module
  971. # by the same CloudPickler instance and then updated with the
  972. # content of state['globals'] to populate the shared isolated
  973. # namespace with all the global variables that are specifically
  974. # referenced for this function.
  975. func.__globals__.update(state['globals'])
  976. func.__defaults__ = state['defaults']
  977. func.__dict__ = state['dict']
  978. if 'annotations' in state:
  979. func.__annotations__ = state['annotations']
  980. if 'doc' in state:
  981. func.__doc__ = state['doc']
  982. if 'name' in state:
  983. func.__name__ = state['name']
  984. if 'module' in state:
  985. func.__module__ = state['module']
  986. if 'qualname' in state:
  987. func.__qualname__ = state['qualname']
  988. if 'kwdefaults' in state:
  989. func.__kwdefaults__ = state['kwdefaults']
  990. # _cloudpickle_subimports is a set of submodules that must be loaded for
  991. # the pickled function to work correctly at unpickling time. Now that these
  992. # submodules are depickled (hence imported), they can be removed from the
  993. # object's state (the object state only served as a reference holder to
  994. # these submodules)
  995. if '_cloudpickle_submodules' in state:
  996. state.pop('_cloudpickle_submodules')
  997. cells = func.__closure__
  998. if cells is not None:
  999. for cell, value in zip(cells, state['closure_values']):
  1000. if value is not _empty_cell_value:
  1001. cell_set(cell, value)
  1002. return func
  1003. def _make_empty_cell():
  1004. if False:
  1005. # trick the compiler into creating an empty cell in our lambda
  1006. cell = None
  1007. raise AssertionError('this route should not be executed')
  1008. return (lambda: cell).__closure__[0]
  1009. def _make_skel_func(code, cell_count, base_globals=None):
  1010. """ Creates a skeleton function object that contains just the provided
  1011. code and the correct number of cells in func_closure. All other
  1012. func attributes (e.g. func_globals) are empty.
  1013. """
  1014. # This is backward-compatibility code: for cloudpickle versions between
  1015. # 0.5.4 and 0.7, base_globals could be a string or None. base_globals
  1016. # should now always be a dictionary.
  1017. if base_globals is None or isinstance(base_globals, str):
  1018. base_globals = {}
  1019. base_globals['__builtins__'] = __builtins__
  1020. closure = (
  1021. tuple(_make_empty_cell() for _ in range(cell_count))
  1022. if cell_count >= 0 else
  1023. None
  1024. )
  1025. return types.FunctionType(code, base_globals, None, None, closure)
  1026. def _make_skeleton_class(type_constructor, name, bases, type_kwargs,
  1027. class_tracker_id, extra):
  1028. """Build dynamic class with an empty __dict__ to be filled once memoized
  1029. If class_tracker_id is not None, try to lookup an existing class definition
  1030. matching that id. If none is found, track a newly reconstructed class
  1031. definition under that id so that other instances stemming from the same
  1032. class id will also reuse this class definition.
  1033. The "extra" variable is meant to be a dict (or None) that can be used for
  1034. forward compatibility shall the need arise.
  1035. """
  1036. skeleton_class = types.new_class(
  1037. name, bases, {'metaclass': type_constructor},
  1038. lambda ns: ns.update(type_kwargs)
  1039. )
  1040. return _lookup_class_or_track(class_tracker_id, skeleton_class)
  1041. def _rehydrate_skeleton_class(skeleton_class, class_dict):
  1042. """Put attributes from `class_dict` back on `skeleton_class`.
  1043. See CloudPickler.save_dynamic_class for more info.
  1044. """
  1045. registry = None
  1046. for attrname, attr in class_dict.items():
  1047. if attrname == "_abc_impl":
  1048. registry = attr
  1049. else:
  1050. setattr(skeleton_class, attrname, attr)
  1051. if registry is not None:
  1052. for subclass in registry:
  1053. skeleton_class.register(subclass)
  1054. return skeleton_class
  1055. def _make_skeleton_enum(bases, name, qualname, members, module,
  1056. class_tracker_id, extra):
  1057. """Build dynamic enum with an empty __dict__ to be filled once memoized
  1058. The creation of the enum class is inspired by the code of
  1059. EnumMeta._create_.
  1060. If class_tracker_id is not None, try to lookup an existing enum definition
  1061. matching that id. If none is found, track a newly reconstructed enum
  1062. definition under that id so that other instances stemming from the same
  1063. class id will also reuse this enum definition.
  1064. The "extra" variable is meant to be a dict (or None) that can be used for
  1065. forward compatibility shall the need arise.
  1066. """
  1067. # enums always inherit from their base Enum class at the last position in
  1068. # the list of base classes:
  1069. enum_base = bases[-1]
  1070. metacls = enum_base.__class__
  1071. classdict = metacls.__prepare__(name, bases)
  1072. for member_name, member_value in members.items():
  1073. classdict[member_name] = member_value
  1074. enum_class = metacls.__new__(metacls, name, bases, classdict)
  1075. enum_class.__module__ = module
  1076. enum_class.__qualname__ = qualname
  1077. return _lookup_class_or_track(class_tracker_id, enum_class)
  1078. def _is_dynamic(module):
  1079. """
  1080. Return True if the module is special module that cannot be imported by its
  1081. name.
  1082. """
  1083. # Quick check: module that have __file__ attribute are not dynamic modules.
  1084. if hasattr(module, '__file__'):
  1085. return False
  1086. if module.__spec__ is not None:
  1087. return False
  1088. # In PyPy, Some built-in modules such as _codecs can have their
  1089. # __spec__ attribute set to None despite being imported. For such
  1090. # modules, the ``_find_spec`` utility of the standard library is used.
  1091. parent_name = module.__name__.rpartition('.')[0]
  1092. if parent_name: # pragma: no cover
  1093. # This code handles the case where an imported package (and not
  1094. # module) remains with __spec__ set to None. It is however untested
  1095. # as no package in the PyPy stdlib has __spec__ set to None after
  1096. # it is imported.
  1097. try:
  1098. parent = sys.modules[parent_name]
  1099. except KeyError:
  1100. msg = "parent {!r} not in sys.modules"
  1101. raise ImportError(msg.format(parent_name))
  1102. else:
  1103. pkgpath = parent.__path__
  1104. else:
  1105. pkgpath = None
  1106. return _find_spec(module.__name__, pkgpath, module) is None
  1107. def _make_typevar(name, bound, constraints, covariant, contravariant,
  1108. class_tracker_id):
  1109. tv = typing.TypeVar(
  1110. name, *constraints, bound=bound,
  1111. covariant=covariant, contravariant=contravariant
  1112. )
  1113. if class_tracker_id is not None:
  1114. return _lookup_class_or_track(class_tracker_id, tv)
  1115. else: # pragma: nocover
  1116. # Only for Python 3.5.3 compat.
  1117. return tv
  1118. def _decompose_typevar(obj):
  1119. try:
  1120. class_tracker_id = _get_or_create_tracker_id(obj)
  1121. except TypeError: # pragma: nocover
  1122. # TypeVar instances are not weakref-able in Python 3.5.3
  1123. class_tracker_id = None
  1124. return (
  1125. obj.__name__, obj.__bound__, obj.__constraints__,
  1126. obj.__covariant__, obj.__contravariant__,
  1127. class_tracker_id,
  1128. )
  1129. def _typevar_reduce(obj):
  1130. # TypeVar instances have no __qualname__ hence we pass the name explicitly.
  1131. module_and_name = _lookup_module_and_qualname(obj, name=obj.__name__)
  1132. if module_and_name is None:
  1133. return (_make_typevar, _decompose_typevar(obj))
  1134. return (getattr, module_and_name)
  1135. def _get_bases(typ):
  1136. if hasattr(typ, '__orig_bases__'):
  1137. # For generic types (see PEP 560)
  1138. bases_attr = '__orig_bases__'
  1139. else:
  1140. # For regular class objects
  1141. bases_attr = '__bases__'
  1142. return getattr(typ, bases_attr)