Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/ipyparallel/serialize/codeutil.py: 65%

Shortcuts on this page

r m x   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

17 statements  

1"""Utilities to enable code objects to be pickled. 

2 

3Any process that import this module will be able to pickle code objects. This 

4includes the func_code attribute of any function. Once unpickled, new 

5functions can be built using new.function(code, globals()). Eventually 

6we need to automate all of this so that functions themselves can be pickled. 

7 

8Reference: A. Tremols, P Cogolo, "Python Cookbook," p 302-305 

9""" 

10 

11# Copyright (c) IPython Development Team. 

12# Distributed under the terms of the Modified BSD License. 

13import copyreg 

14import inspect 

15import sys 

16import types 

17 

18 

19def code_ctor(*args): 

20 return types.CodeType(*args) 

21 

22 

23# map CodeType constructor args to code co_ attribute names 

24# (they _almost_ all match, and new ones probably will) 

25_code_attr_map = { 

26 "codestring": "code", 

27 "constants": "consts", 

28} 

29# pass every supported arg to the code constructor 

30# this should be more forward-compatible 

31# (broken on pypy: https://github.com/ipython/ipyparallel/issues/845) 

32if sys.version_info >= (3, 10) and not hasattr(sys, "pypy_version_info"): 

33 _code_attr_names = tuple( 

34 _code_attr_map.get(name, name) 

35 for name, param in inspect.signature(types.CodeType).parameters.items() 

36 if param.POSITIONAL_ONLY or param.POSITIONAL_OR_KEYWORD 

37 ) 

38else: 

39 # can't inspect types.CodeType on Python < 3.10 

40 _code_attr_names = [ 

41 "argcount", 

42 "kwonlyargcount", 

43 "nlocals", 

44 "stacksize", 

45 "flags", 

46 "code", 

47 "consts", 

48 "names", 

49 "varnames", 

50 "filename", 

51 "name", 

52 "firstlineno", 

53 "lnotab", 

54 "freevars", 

55 "cellvars", 

56 ] 

57 if hasattr(types.CodeType, "co_posonlyargcount"): 

58 _code_attr_names.insert(1, "posonlyargcount") 

59 

60 _code_attr_names = tuple(_code_attr_names) 

61 

62 

63def reduce_code(obj): 

64 """codeobject reducer""" 

65 return code_ctor, tuple(getattr(obj, f'co_{name}') for name in _code_attr_names) 

66 

67 

68copyreg.pickle(types.CodeType, reduce_code)