_objects.py 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533
  1. #!/usr/bin/env python
  2. #
  3. # Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
  4. # Copyright (c) 2008-2016 California Institute of Technology.
  5. # Copyright (c) 2016-2023 The Uncertainty Quantification Foundation.
  6. # License: 3-clause BSD. The full license text is available at:
  7. # - https://github.com/uqfoundation/dill/blob/master/LICENSE
  8. """
  9. all Python Standard Library objects (currently: CH 1-15 @ 2.7)
  10. and some other common objects (i.e. numpy.ndarray)
  11. """
  12. __all__ = ['registered','failures','succeeds']
  13. # helper imports
  14. import warnings; warnings.filterwarnings("ignore", category=DeprecationWarning)
  15. import sys
  16. import queue as Queue
  17. import dbm as anydbm
  18. from io import BytesIO as StringIO
  19. import re
  20. import array
  21. import collections
  22. import codecs
  23. import struct
  24. import dataclasses
  25. import datetime
  26. import calendar
  27. import weakref
  28. import pprint
  29. import decimal
  30. import numbers
  31. import functools
  32. import itertools
  33. import operator
  34. import tempfile
  35. import shelve
  36. import zlib
  37. import gzip
  38. import zipfile
  39. import tarfile
  40. import xdrlib
  41. import csv
  42. import hashlib
  43. import hmac
  44. import os
  45. import logging
  46. import logging.handlers
  47. import optparse
  48. #import __hello__
  49. import threading
  50. import socket
  51. import contextlib
  52. try:
  53. import bz2
  54. import sqlite3
  55. import dbm.ndbm as dbm
  56. HAS_ALL = True
  57. except ImportError: # Ubuntu
  58. HAS_ALL = False
  59. try:
  60. #import curses
  61. #from curses import textpad, panel
  62. HAS_CURSES = True
  63. except ImportError: # Windows
  64. HAS_CURSES = False
  65. try:
  66. import ctypes
  67. HAS_CTYPES = True
  68. # if using `pypy`, pythonapi is not found
  69. IS_PYPY = not hasattr(ctypes, 'pythonapi')
  70. except ImportError: # MacPorts
  71. HAS_CTYPES = False
  72. IS_PYPY = False
  73. # helper objects
  74. class _class:
  75. def _method(self):
  76. pass
  77. # @classmethod
  78. # def _clsmethod(cls): #XXX: test me
  79. # pass
  80. # @staticmethod
  81. # def _static(self): #XXX: test me
  82. # pass
  83. class _class2:
  84. def __call__(self):
  85. pass
  86. _instance2 = _class2()
  87. class _newclass(object):
  88. def _method(self):
  89. pass
  90. # @classmethod
  91. # def _clsmethod(cls): #XXX: test me
  92. # pass
  93. # @staticmethod
  94. # def _static(self): #XXX: test me
  95. # pass
  96. class _newclass2(object):
  97. __slots__ = ['descriptor']
  98. def _function(x): yield x
  99. def _function2():
  100. try: raise
  101. except Exception:
  102. from sys import exc_info
  103. e, er, tb = exc_info()
  104. return er, tb
  105. if HAS_CTYPES:
  106. class _Struct(ctypes.Structure):
  107. pass
  108. _Struct._fields_ = [("_field", ctypes.c_int),("next", ctypes.POINTER(_Struct))]
  109. _filedescrip, _tempfile = tempfile.mkstemp('r') # deleted in cleanup
  110. _tmpf = tempfile.TemporaryFile('w')
  111. # objects used by dill for type declaration
  112. registered = d = {}
  113. # objects dill fails to pickle
  114. failures = x = {}
  115. # all other type objects
  116. succeeds = a = {}
  117. # types module (part of CH 8)
  118. a['BooleanType'] = bool(1)
  119. a['BuiltinFunctionType'] = len
  120. a['BuiltinMethodType'] = a['BuiltinFunctionType']
  121. a['BytesType'] = _bytes = codecs.latin_1_encode('\x00')[0] # bytes(1)
  122. a['ClassType'] = _class
  123. a['ComplexType'] = complex(1)
  124. a['DictType'] = _dict = {}
  125. a['DictionaryType'] = a['DictType']
  126. a['FloatType'] = float(1)
  127. a['FunctionType'] = _function
  128. a['InstanceType'] = _instance = _class()
  129. a['IntType'] = _int = int(1)
  130. a['ListType'] = _list = []
  131. a['NoneType'] = None
  132. a['ObjectType'] = object()
  133. a['StringType'] = _str = str(1)
  134. a['TupleType'] = _tuple = ()
  135. a['TypeType'] = type
  136. a['LongType'] = _int
  137. a['UnicodeType'] = _str
  138. # built-in constants (CH 4)
  139. a['CopyrightType'] = copyright
  140. # built-in types (CH 5)
  141. a['ClassObjectType'] = _newclass # <type 'type'>
  142. a['ClassInstanceType'] = _newclass() # <type 'class'>
  143. a['SetType'] = _set = set()
  144. a['FrozenSetType'] = frozenset()
  145. # built-in exceptions (CH 6)
  146. a['ExceptionType'] = _exception = _function2()[0]
  147. # string services (CH 7)
  148. a['SREPatternType'] = _srepattern = re.compile('')
  149. # data types (CH 8)
  150. a['ArrayType'] = array.array("f")
  151. a['DequeType'] = collections.deque([0])
  152. a['DefaultDictType'] = collections.defaultdict(_function, _dict)
  153. a['TZInfoType'] = datetime.tzinfo()
  154. a['DateTimeType'] = datetime.datetime.today()
  155. a['CalendarType'] = calendar.Calendar()
  156. # numeric and mathematical types (CH 9)
  157. a['DecimalType'] = decimal.Decimal(1)
  158. a['CountType'] = itertools.count(0)
  159. # data compression and archiving (CH 12)
  160. a['TarInfoType'] = tarfile.TarInfo()
  161. # generic operating system services (CH 15)
  162. a['LoggerType'] = _logger = logging.getLogger()
  163. a['FormatterType'] = logging.Formatter() # pickle ok
  164. a['FilterType'] = logging.Filter() # pickle ok
  165. a['LogRecordType'] = logging.makeLogRecord(_dict) # pickle ok
  166. a['OptionParserType'] = _oparser = optparse.OptionParser() # pickle ok
  167. a['OptionGroupType'] = optparse.OptionGroup(_oparser,"foo") # pickle ok
  168. a['OptionType'] = optparse.Option('--foo') # pickle ok
  169. if HAS_CTYPES:
  170. z = x if IS_PYPY else a
  171. z['CCharType'] = _cchar = ctypes.c_char()
  172. z['CWCharType'] = ctypes.c_wchar() # fail == 2.6
  173. z['CByteType'] = ctypes.c_byte()
  174. z['CUByteType'] = ctypes.c_ubyte()
  175. z['CShortType'] = ctypes.c_short()
  176. z['CUShortType'] = ctypes.c_ushort()
  177. z['CIntType'] = ctypes.c_int()
  178. z['CUIntType'] = ctypes.c_uint()
  179. z['CLongType'] = ctypes.c_long()
  180. z['CULongType'] = ctypes.c_ulong()
  181. z['CLongLongType'] = ctypes.c_longlong()
  182. z['CULongLongType'] = ctypes.c_ulonglong()
  183. z['CFloatType'] = ctypes.c_float()
  184. z['CDoubleType'] = ctypes.c_double()
  185. z['CSizeTType'] = ctypes.c_size_t()
  186. del z
  187. a['CLibraryLoaderType'] = ctypes.cdll
  188. a['StructureType'] = _Struct
  189. # if not IS_PYPY:
  190. # a['BigEndianStructureType'] = ctypes.BigEndianStructure()
  191. #NOTE: also LittleEndianStructureType and UnionType... abstract classes
  192. #NOTE: remember for ctypesobj.contents creates a new python object
  193. #NOTE: ctypes.c_int._objects is memberdescriptor for object's __dict__
  194. #NOTE: base class of all ctypes data types is non-public _CData
  195. import fractions
  196. import io
  197. from io import StringIO as TextIO
  198. # built-in functions (CH 2)
  199. a['ByteArrayType'] = bytearray([1])
  200. # numeric and mathematical types (CH 9)
  201. a['FractionType'] = fractions.Fraction()
  202. a['NumberType'] = numbers.Number()
  203. # generic operating system services (CH 15)
  204. a['IOBaseType'] = io.IOBase()
  205. a['RawIOBaseType'] = io.RawIOBase()
  206. a['TextIOBaseType'] = io.TextIOBase()
  207. a['BufferedIOBaseType'] = io.BufferedIOBase()
  208. a['UnicodeIOType'] = TextIO() # the new StringIO
  209. a['LoggerAdapterType'] = logging.LoggerAdapter(_logger,_dict) # pickle ok
  210. if HAS_CTYPES:
  211. z = x if IS_PYPY else a
  212. z['CBoolType'] = ctypes.c_bool(1)
  213. z['CLongDoubleType'] = ctypes.c_longdouble()
  214. del z
  215. import argparse
  216. # data types (CH 8)
  217. a['OrderedDictType'] = collections.OrderedDict(_dict)
  218. a['CounterType'] = collections.Counter(_dict)
  219. if HAS_CTYPES:
  220. z = x if IS_PYPY else a
  221. z['CSSizeTType'] = ctypes.c_ssize_t()
  222. del z
  223. # generic operating system services (CH 15)
  224. a['NullHandlerType'] = logging.NullHandler() # pickle ok # new 2.7
  225. a['ArgParseFileType'] = argparse.FileType() # pickle ok
  226. # -- pickle fails on all below here -----------------------------------------
  227. # types module (part of CH 8)
  228. a['CodeType'] = compile('','','exec')
  229. a['DictProxyType'] = type.__dict__
  230. a['DictProxyType2'] = _newclass.__dict__
  231. a['EllipsisType'] = Ellipsis
  232. a['ClosedFileType'] = open(os.devnull, 'wb', buffering=0).close()
  233. a['GetSetDescriptorType'] = array.array.typecode
  234. a['LambdaType'] = _lambda = lambda x: lambda y: x #XXX: works when not imported!
  235. a['MemberDescriptorType'] = _newclass2.descriptor
  236. if not IS_PYPY:
  237. a['MemberDescriptorType2'] = datetime.timedelta.days
  238. a['MethodType'] = _method = _class()._method #XXX: works when not imported!
  239. a['ModuleType'] = datetime
  240. a['NotImplementedType'] = NotImplemented
  241. a['SliceType'] = slice(1)
  242. a['UnboundMethodType'] = _class._method #XXX: works when not imported!
  243. d['TextWrapperType'] = open(os.devnull, 'r') # same as mode='w','w+','r+'
  244. d['BufferedRandomType'] = open(os.devnull, 'r+b') # same as mode='w+b'
  245. d['BufferedReaderType'] = open(os.devnull, 'rb') # (default: buffering=-1)
  246. d['BufferedWriterType'] = open(os.devnull, 'wb')
  247. try: # oddities: deprecated
  248. from _pyio import open as _open
  249. d['PyTextWrapperType'] = _open(os.devnull, 'r', buffering=-1)
  250. d['PyBufferedRandomType'] = _open(os.devnull, 'r+b', buffering=-1)
  251. d['PyBufferedReaderType'] = _open(os.devnull, 'rb', buffering=-1)
  252. d['PyBufferedWriterType'] = _open(os.devnull, 'wb', buffering=-1)
  253. except ImportError:
  254. pass
  255. # other (concrete) object types
  256. z = d if sys.hexversion < 0x30800a2 else a
  257. z['CellType'] = (_lambda)(0).__closure__[0]
  258. del z
  259. a['XRangeType'] = _xrange = range(1)
  260. a['MethodDescriptorType'] = type.__dict__['mro']
  261. a['WrapperDescriptorType'] = type.__repr__
  262. #a['WrapperDescriptorType2'] = type.__dict__['__module__']#XXX: GetSetDescriptor
  263. a['ClassMethodDescriptorType'] = type.__dict__['__prepare__']
  264. # built-in functions (CH 2)
  265. _methodwrap = (1).__lt__
  266. a['MethodWrapperType'] = _methodwrap
  267. a['StaticMethodType'] = staticmethod(_method)
  268. a['ClassMethodType'] = classmethod(_method)
  269. a['PropertyType'] = property()
  270. d['SuperType'] = super(Exception, _exception)
  271. # string services (CH 7)
  272. _in = _bytes
  273. a['InputType'] = _cstrI = StringIO(_in)
  274. a['OutputType'] = _cstrO = StringIO()
  275. # data types (CH 8)
  276. a['WeakKeyDictionaryType'] = weakref.WeakKeyDictionary()
  277. a['WeakValueDictionaryType'] = weakref.WeakValueDictionary()
  278. a['ReferenceType'] = weakref.ref(_instance)
  279. a['DeadReferenceType'] = weakref.ref(_class())
  280. a['ProxyType'] = weakref.proxy(_instance)
  281. a['DeadProxyType'] = weakref.proxy(_class())
  282. a['CallableProxyType'] = weakref.proxy(_instance2)
  283. a['DeadCallableProxyType'] = weakref.proxy(_class2())
  284. a['QueueType'] = Queue.Queue()
  285. # numeric and mathematical types (CH 9)
  286. d['PartialType'] = functools.partial(int,base=2)
  287. a['IzipType'] = zip('0','1')
  288. a['ChainType'] = itertools.chain('0','1')
  289. d['ItemGetterType'] = operator.itemgetter(0)
  290. d['AttrGetterType'] = operator.attrgetter('__repr__')
  291. # file and directory access (CH 10)
  292. _fileW = _cstrO
  293. # data persistence (CH 11)
  294. if HAS_ALL:
  295. x['ConnectionType'] = _conn = sqlite3.connect(':memory:')
  296. x['CursorType'] = _conn.cursor()
  297. a['ShelveType'] = shelve.Shelf({})
  298. # data compression and archiving (CH 12)
  299. if HAS_ALL:
  300. x['BZ2FileType'] = bz2.BZ2File(os.devnull)
  301. x['BZ2CompressorType'] = bz2.BZ2Compressor()
  302. x['BZ2DecompressorType'] = bz2.BZ2Decompressor()
  303. #x['ZipFileType'] = _zip = zipfile.ZipFile(os.devnull,'w')
  304. #_zip.write(_tempfile,'x') [causes annoying warning/error printed on import]
  305. #a['ZipInfoType'] = _zip.getinfo('x')
  306. a['TarFileType'] = tarfile.open(fileobj=_fileW,mode='w')
  307. # file formats (CH 13)
  308. x['DialectType'] = csv.get_dialect('excel')
  309. a['PackerType'] = xdrlib.Packer()
  310. # optional operating system services (CH 16)
  311. a['LockType'] = threading.Lock()
  312. a['RLockType'] = threading.RLock()
  313. # generic operating system services (CH 15) # also closed/open and r/w/etc...
  314. a['NamedLoggerType'] = _logger = logging.getLogger(__name__)
  315. #a['FrozenModuleType'] = __hello__ #FIXME: prints "Hello world..."
  316. # interprocess communication (CH 17)
  317. x['SocketType'] = _socket = socket.socket()
  318. x['SocketPairType'] = socket.socketpair()[0]
  319. # python runtime services (CH 27)
  320. a['GeneratorContextManagerType'] = contextlib.contextmanager(max)([1])
  321. try: # ipython
  322. __IPYTHON__ is True # is ipython
  323. except NameError:
  324. # built-in constants (CH 4)
  325. a['QuitterType'] = quit
  326. d['ExitType'] = a['QuitterType']
  327. try: # numpy #FIXME: slow... 0.05 to 0.1 sec to import numpy
  328. from numpy import ufunc as _numpy_ufunc
  329. from numpy import array as _numpy_array
  330. from numpy import int32 as _numpy_int32
  331. a['NumpyUfuncType'] = _numpy_ufunc
  332. a['NumpyArrayType'] = _numpy_array
  333. a['NumpyInt32Type'] = _numpy_int32
  334. except ImportError:
  335. pass
  336. # numeric and mathematical types (CH 9)
  337. a['ProductType'] = itertools.product('0','1')
  338. # generic operating system services (CH 15)
  339. a['FileHandlerType'] = logging.FileHandler(os.devnull)
  340. a['RotatingFileHandlerType'] = logging.handlers.RotatingFileHandler(os.devnull)
  341. a['SocketHandlerType'] = logging.handlers.SocketHandler('localhost',514)
  342. a['MemoryHandlerType'] = logging.handlers.MemoryHandler(1)
  343. # data types (CH 8)
  344. a['WeakSetType'] = weakref.WeakSet() # 2.7
  345. # generic operating system services (CH 15) [errors when dill is imported]
  346. #a['ArgumentParserType'] = _parser = argparse.ArgumentParser('PROG')
  347. #a['NamespaceType'] = _parser.parse_args() # pickle ok
  348. #a['SubParsersActionType'] = _parser.add_subparsers()
  349. #a['MutuallyExclusiveGroupType'] = _parser.add_mutually_exclusive_group()
  350. #a['ArgumentGroupType'] = _parser.add_argument_group()
  351. # -- dill fails in some versions below here ---------------------------------
  352. # types module (part of CH 8)
  353. d['FileType'] = open(os.devnull, 'rb', buffering=0) # same 'wb','wb+','rb+'
  354. # built-in functions (CH 2)
  355. # Iterators:
  356. a['ListIteratorType'] = iter(_list) # empty vs non-empty
  357. a['SetIteratorType'] = iter(_set) #XXX: empty vs non-empty #FIXME: list_iterator
  358. a['TupleIteratorType']= iter(_tuple) # empty vs non-empty
  359. a['XRangeIteratorType'] = iter(_xrange) # empty vs non-empty
  360. a["BytesIteratorType"] = iter(b'')
  361. a["BytearrayIteratorType"] = iter(bytearray(b''))
  362. z = x if IS_PYPY else a
  363. z["CallableIteratorType"] = iter(iter, None)
  364. del z
  365. x["MemoryIteratorType"] = iter(memoryview(b''))
  366. a["ListReverseiteratorType"] = reversed([])
  367. X = a['OrderedDictType']
  368. d["OdictKeysType"] = X.keys()
  369. d["OdictValuesType"] = X.values()
  370. d["OdictItemsType"] = X.items()
  371. a["OdictIteratorType"] = iter(X.keys()) #FIXME: list_iterator
  372. del X
  373. #FIXME: list_iterator
  374. a['DictionaryItemIteratorType'] = iter(type.__dict__.items())
  375. a['DictionaryKeyIteratorType'] = iter(type.__dict__.keys())
  376. a['DictionaryValueIteratorType'] = iter(type.__dict__.values())
  377. if sys.hexversion >= 0x30800a0:
  378. a["DictReversekeyiteratorType"] = reversed({}.keys())
  379. a["DictReversevalueiteratorType"] = reversed({}.values())
  380. a["DictReverseitemiteratorType"] = reversed({}.items())
  381. try:
  382. import symtable
  383. #FIXME: fails to pickle
  384. x["SymtableEntryType"] = symtable.symtable("", "string", "exec")._table
  385. except ImportError:
  386. pass
  387. if sys.hexversion >= 0x30a00a0 and not IS_PYPY:
  388. x['LineIteratorType'] = compile('3', '', 'eval').co_lines()
  389. if sys.hexversion >= 0x30b00b0:
  390. from types import GenericAlias
  391. d["GenericAliasIteratorType"] = iter(GenericAlias(list, (int,)))
  392. x['PositionsIteratorType'] = compile('3', '', 'eval').co_positions()
  393. # data types (CH 8)
  394. a['PrettyPrinterType'] = pprint.PrettyPrinter()
  395. # numeric and mathematical types (CH 9)
  396. a['CycleType'] = itertools.cycle('0')
  397. # file and directory access (CH 10)
  398. a['TemporaryFileType'] = _tmpf
  399. # data compression and archiving (CH 12)
  400. x['GzipFileType'] = gzip.GzipFile(fileobj=_fileW)
  401. # generic operating system services (CH 15)
  402. a['StreamHandlerType'] = logging.StreamHandler()
  403. # numeric and mathematical types (CH 9)
  404. a['PermutationsType'] = itertools.permutations('0')
  405. a['CombinationsType'] = itertools.combinations('0',1)
  406. a['RepeatType'] = itertools.repeat(0)
  407. a['CompressType'] = itertools.compress('0',[1])
  408. #XXX: ...and etc
  409. # -- dill fails on all below here -------------------------------------------
  410. # types module (part of CH 8)
  411. x['GeneratorType'] = _generator = _function(1) #XXX: priority
  412. x['FrameType'] = _generator.gi_frame #XXX: inspect.currentframe()
  413. x['TracebackType'] = _function2()[1] #(see: inspect.getouterframes,getframeinfo)
  414. # other (concrete) object types
  415. # (also: Capsule / CObject ?)
  416. # built-in functions (CH 2)
  417. # built-in types (CH 5)
  418. # string services (CH 7)
  419. x['StructType'] = struct.Struct('c')
  420. x['CallableIteratorType'] = _srepattern.finditer('')
  421. x['SREMatchType'] = _srepattern.match('')
  422. x['SREScannerType'] = _srepattern.scanner('')
  423. x['StreamReader'] = codecs.StreamReader(_cstrI) #XXX: ... and etc
  424. # python object persistence (CH 11)
  425. # x['DbShelveType'] = shelve.open('foo','n')#,protocol=2) #XXX: delete foo
  426. if HAS_ALL:
  427. z = a if IS_PYPY else x
  428. z['DbmType'] = dbm.open(_tempfile,'n')
  429. del z
  430. # x['DbCursorType'] = _dbcursor = anydbm.open('foo','n') #XXX: delete foo
  431. # x['DbType'] = _dbcursor.db
  432. # data compression and archiving (CH 12)
  433. x['ZlibCompressType'] = zlib.compressobj()
  434. x['ZlibDecompressType'] = zlib.decompressobj()
  435. # file formats (CH 13)
  436. x['CSVReaderType'] = csv.reader(_cstrI)
  437. x['CSVWriterType'] = csv.writer(_cstrO)
  438. x['CSVDictReaderType'] = csv.DictReader(_cstrI)
  439. x['CSVDictWriterType'] = csv.DictWriter(_cstrO,{})
  440. # cryptographic services (CH 14)
  441. x['HashType'] = hashlib.md5()
  442. if (sys.hexversion < 0x30800a1):
  443. x['HMACType'] = hmac.new(_in)
  444. else:
  445. x['HMACType'] = hmac.new(_in, digestmod='md5')
  446. # generic operating system services (CH 15)
  447. if HAS_CURSES: pass
  448. #x['CursesWindowType'] = _curwin = curses.initscr() #FIXME: messes up tty
  449. #x['CursesTextPadType'] = textpad.Textbox(_curwin)
  450. #x['CursesPanelType'] = panel.new_panel(_curwin)
  451. if HAS_CTYPES:
  452. x['CCharPType'] = ctypes.c_char_p()
  453. x['CWCharPType'] = ctypes.c_wchar_p()
  454. x['CVoidPType'] = ctypes.c_void_p()
  455. if sys.platform[:3] == 'win':
  456. x['CDLLType'] = _cdll = ctypes.cdll.msvcrt
  457. else:
  458. x['CDLLType'] = _cdll = ctypes.CDLL(None)
  459. if not IS_PYPY:
  460. x['PyDLLType'] = _pydll = ctypes.pythonapi
  461. x['FuncPtrType'] = _cdll._FuncPtr()
  462. x['CCharArrayType'] = ctypes.create_string_buffer(1)
  463. x['CWCharArrayType'] = ctypes.create_unicode_buffer(1)
  464. x['CParamType'] = ctypes.byref(_cchar)
  465. x['LPCCharType'] = ctypes.pointer(_cchar)
  466. x['LPCCharObjType'] = _lpchar = ctypes.POINTER(ctypes.c_char)
  467. x['NullPtrType'] = _lpchar()
  468. x['NullPyObjectType'] = ctypes.py_object()
  469. x['PyObjectType'] = ctypes.py_object(lambda :None)
  470. z = a if IS_PYPY else x
  471. z['FieldType'] = _field = _Struct._field
  472. z['CFUNCTYPEType'] = _cfunc = ctypes.CFUNCTYPE(ctypes.c_char)
  473. if sys.hexversion < 0x30c00b3:
  474. x['CFunctionType'] = _cfunc(str)
  475. del z
  476. # numeric and mathematical types (CH 9)
  477. a['MethodCallerType'] = operator.methodcaller('mro') # 2.6
  478. # built-in types (CH 5)
  479. x['MemoryType'] = memoryview(_in) # 2.7
  480. x['MemoryType2'] = memoryview(bytearray(_in)) # 2.7
  481. d['DictItemsType'] = _dict.items() # 2.7
  482. d['DictKeysType'] = _dict.keys() # 2.7
  483. d['DictValuesType'] = _dict.values() # 2.7
  484. # generic operating system services (CH 15)
  485. a['RawTextHelpFormatterType'] = argparse.RawTextHelpFormatter('PROG')
  486. a['RawDescriptionHelpFormatterType'] = argparse.RawDescriptionHelpFormatter('PROG')
  487. a['ArgDefaultsHelpFormatterType'] = argparse.ArgumentDefaultsHelpFormatter('PROG')
  488. z = a if IS_PYPY else x
  489. z['CmpKeyType'] = _cmpkey = functools.cmp_to_key(_methodwrap) # 2.7, >=3.2
  490. z['CmpKeyObjType'] = _cmpkey('0') #2.7, >=3.2
  491. del z
  492. # oddities: removed, etc
  493. x['BufferType'] = x['MemoryType']
  494. from dill._dill import _testcapsule
  495. if _testcapsule is not None:
  496. d['PyCapsuleType'] = _testcapsule
  497. del _testcapsule
  498. if hasattr(dataclasses, '_HAS_DEFAULT_FACTORY'):
  499. a['DataclassesHasDefaultFactoryType'] = dataclasses._HAS_DEFAULT_FACTORY
  500. if hasattr(dataclasses, 'MISSING'):
  501. a['DataclassesMissingType'] = dataclasses.MISSING
  502. if hasattr(dataclasses, 'KW_ONLY'):
  503. a['DataclassesKWOnlyType'] = dataclasses.KW_ONLY
  504. if hasattr(dataclasses, '_FIELD_BASE'):
  505. a['DataclassesFieldBaseType'] = dataclasses._FIELD
  506. # -- cleanup ----------------------------------------------------------------
  507. a.update(d) # registered also succeed
  508. if sys.platform[:3] == 'win':
  509. os.close(_filedescrip) # required on win32
  510. os.remove(_tempfile)
  511. # EOF