mirror of https://github.com/sgoudham/Enso-Bot.git
Trying to use txt files for kakashi
parent
9bea4a3f03
commit
08838fdabf
Binary file not shown.
Binary file not shown.
@ -0,0 +1,100 @@
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717201077346238514/image0.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717201077669331036/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717201077941829722/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717201078633889913/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717201078885810176/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717203540048871456/40964a8ec3616dd143db1ac63c4090ee.jpg
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203546772340846/4707601f950c412dd6978c8264308632.jpg
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203597774946354/7941b52067df70825ae3a9051acfd98d.jpg
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203650333900840/dafb0bc78adc3548e9c9b24460d7c10d.jpg
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203693925040188/aad4edeac8e034683b5602cf01a41333.jpg?width=465&height=658
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203717085986836/5851485577679be2a09bdebef7e35522.jpg?width=390&height=658
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203783016513626/e2a746123c1e36d995fa95c44a3c3f85.jpg
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203811923394611/268a3266d4c255b72925a3eb541f4cf5.jpg?width=517&height=657
|
||||
https://media.discordapp.net/attachments/714671068941647933/717203866986479636/b283f71be006957107926e1d5d9ab60e.jpg?width=591&height=658
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717203972925947984/6f46bb96761b673f1c4f4b5584bf1ba8.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204020711915581/4025c1241a206406555bd6ab53640291.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204198491422770/94287174f2f5e5316144981190a38c66.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204289755283547/a9868fb38857dd51ccc93a3e202644ff.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204351638175784/3967dabc9b069080daded9a38f1d9e49.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204405178597396/3d063a07af0cfa320a100e169c959ff4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204454264537151/4c607bbcc9a360257e1d14b5c9858b21.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204495939141692/9d85777e4a452f2f38464f8a11dece5b.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204530760122478/edeaa333ed2fb68aa1205a783d0bb783.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204561936252958/4f39f6de439a99b4113f6a33fd803079.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204627484967012/ebb8b6713aff32745503d6cbe8996569.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204713648685126/a6cb9a07745c163d14d736e077765ec8.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204734905417738/3a081283ef670fd5326a694b7d41d35d.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204879155921006/864704a29ef1201f78f7f8fd71f57cf7.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717204999792361472/d9b273a711ccf1e6af531443a4cf06b5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717205121259405332/d2426eff482c18af2586e1fd2499d3d5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717205186463924224/7e27f5a97a80444ab5fc773e4d09d1bb.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717205371835514930/IMG_20191212_215715_438.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717205515519655976/df09731e2b38c1f50cc57f4600d937f5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206154882842695/image0.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206155356798986/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206155562057780/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206155797200896/image3.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206156031819786/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206156191334460/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206156673679380/image6.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206157227327578/image7.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206621121544230/image0.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206621310418954/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206621666672721/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206621993959474/image3.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206622249943050/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206622489018458/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717206622979489792/image6.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545579713921065/image0.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545580070699068/image1.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545580393398332/image2.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545580804702228/image3.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545581299499179/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545581526122586/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545581815529532/image6.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545582046085140/image7.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545582234697748/image8.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717545582427766784/image9.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547623334019102/image0.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547623762100254/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547624122810388/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547624374206554/image3.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547624655355944/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547624906883082/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547625095626752/image6.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547625557262417/image7.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547625762521167/image8.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717547626081288242/image9.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548032249430016/image0.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548032614465556/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548033000079380/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548033344143410/image3.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548033612709999/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548033868300298/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548034149449738/image6.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548034359296046/image7.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548034631663616/image8.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717548034820538406/image9.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551546946158602/image0.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551547197947954/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551547525103616/image2.gif
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551547776630824/image3.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551548170764398/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551548380610570/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551548720349235/image6.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551549139648592/image7.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551549357883512/image8.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551549525786745/image9.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551728316121148/image0.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551728873963610/image1.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551729343725568/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551729343725568/image2.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551729683595334/image3.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551730065276948/image4.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551730400821298/image5.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551731537477662/image6.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551731969622039/image7.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551732338458654/image8.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717551732594442290/image9.jpg
|
||||
https://cdn.discordapp.com/attachments/714671068941647933/717552058877739119/image0.gif
|
@ -0,0 +1,157 @@
|
||||
/* vim:set noet ts=8 sw=8 : */
|
||||
|
||||
/* Greenlet object interface */
|
||||
|
||||
#ifndef Py_GREENLETOBJECT_H
|
||||
#define Py_GREENLETOBJECT_H
|
||||
|
||||
#include <Python.h>
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define GREENLET_VERSION "0.4.15"
|
||||
|
||||
#if PY_VERSION_HEX >= 0x030700A3
|
||||
# define GREENLET_USE_EXC_INFO
|
||||
#endif
|
||||
|
||||
typedef struct _greenlet {
|
||||
PyObject_HEAD
|
||||
char* stack_start;
|
||||
char* stack_stop;
|
||||
char* stack_copy;
|
||||
intptr_t stack_saved;
|
||||
struct _greenlet* stack_prev;
|
||||
struct _greenlet* parent;
|
||||
PyObject* run_info;
|
||||
struct _frame* top_frame;
|
||||
int recursion_depth;
|
||||
PyObject* weakreflist;
|
||||
#ifdef GREENLET_USE_EXC_INFO
|
||||
_PyErr_StackItem* exc_info;
|
||||
_PyErr_StackItem exc_state;
|
||||
#else
|
||||
PyObject* exc_type;
|
||||
PyObject* exc_value;
|
||||
PyObject* exc_traceback;
|
||||
#endif
|
||||
PyObject* dict;
|
||||
} PyGreenlet;
|
||||
|
||||
#define PyGreenlet_Check(op) PyObject_TypeCheck(op, &PyGreenlet_Type)
|
||||
#define PyGreenlet_MAIN(op) (((PyGreenlet*)(op))->stack_stop == (char*) -1)
|
||||
#define PyGreenlet_STARTED(op) (((PyGreenlet*)(op))->stack_stop != NULL)
|
||||
#define PyGreenlet_ACTIVE(op) (((PyGreenlet*)(op))->stack_start != NULL)
|
||||
#define PyGreenlet_GET_PARENT(op) (((PyGreenlet*)(op))->parent)
|
||||
|
||||
#if (PY_MAJOR_VERSION == 2 && PY_MINOR_VERSION >= 7) || (PY_MAJOR_VERSION == 3 && PY_MINOR_VERSION >= 1) || PY_MAJOR_VERSION > 3
|
||||
#define GREENLET_USE_PYCAPSULE
|
||||
#endif
|
||||
|
||||
/* C API functions */
|
||||
|
||||
/* Total number of symbols that are exported */
|
||||
#define PyGreenlet_API_pointers 8
|
||||
|
||||
#define PyGreenlet_Type_NUM 0
|
||||
#define PyExc_GreenletError_NUM 1
|
||||
#define PyExc_GreenletExit_NUM 2
|
||||
|
||||
#define PyGreenlet_New_NUM 3
|
||||
#define PyGreenlet_GetCurrent_NUM 4
|
||||
#define PyGreenlet_Throw_NUM 5
|
||||
#define PyGreenlet_Switch_NUM 6
|
||||
#define PyGreenlet_SetParent_NUM 7
|
||||
|
||||
#ifndef GREENLET_MODULE
|
||||
/* This section is used by modules that uses the greenlet C API */
|
||||
static void **_PyGreenlet_API = NULL;
|
||||
|
||||
#define PyGreenlet_Type (*(PyTypeObject *) _PyGreenlet_API[PyGreenlet_Type_NUM])
|
||||
|
||||
#define PyExc_GreenletError \
|
||||
((PyObject *) _PyGreenlet_API[PyExc_GreenletError_NUM])
|
||||
|
||||
#define PyExc_GreenletExit \
|
||||
((PyObject *) _PyGreenlet_API[PyExc_GreenletExit_NUM])
|
||||
|
||||
/*
|
||||
* PyGreenlet_New(PyObject *args)
|
||||
*
|
||||
* greenlet.greenlet(run, parent=None)
|
||||
*/
|
||||
#define PyGreenlet_New \
|
||||
(* (PyGreenlet * (*)(PyObject *run, PyGreenlet *parent)) \
|
||||
_PyGreenlet_API[PyGreenlet_New_NUM])
|
||||
|
||||
/*
|
||||
* PyGreenlet_GetCurrent(void)
|
||||
*
|
||||
* greenlet.getcurrent()
|
||||
*/
|
||||
#define PyGreenlet_GetCurrent \
|
||||
(* (PyGreenlet * (*)(void)) _PyGreenlet_API[PyGreenlet_GetCurrent_NUM])
|
||||
|
||||
/*
|
||||
* PyGreenlet_Throw(
|
||||
* PyGreenlet *greenlet,
|
||||
* PyObject *typ,
|
||||
* PyObject *val,
|
||||
* PyObject *tb)
|
||||
*
|
||||
* g.throw(...)
|
||||
*/
|
||||
#define PyGreenlet_Throw \
|
||||
(* (PyObject * (*) \
|
||||
(PyGreenlet *self, PyObject *typ, PyObject *val, PyObject *tb)) \
|
||||
_PyGreenlet_API[PyGreenlet_Throw_NUM])
|
||||
|
||||
/*
|
||||
* PyGreenlet_Switch(PyGreenlet *greenlet, PyObject *args)
|
||||
*
|
||||
* g.switch(*args, **kwargs)
|
||||
*/
|
||||
#define PyGreenlet_Switch \
|
||||
(* (PyObject * (*)(PyGreenlet *greenlet, PyObject *args, PyObject *kwargs)) \
|
||||
_PyGreenlet_API[PyGreenlet_Switch_NUM])
|
||||
|
||||
/*
|
||||
* PyGreenlet_SetParent(PyObject *greenlet, PyObject *new_parent)
|
||||
*
|
||||
* g.parent = new_parent
|
||||
*/
|
||||
#define PyGreenlet_SetParent \
|
||||
(* (int (*)(PyGreenlet *greenlet, PyGreenlet *nparent)) \
|
||||
_PyGreenlet_API[PyGreenlet_SetParent_NUM])
|
||||
|
||||
/* Macro that imports greenlet and initializes C API */
|
||||
#ifdef GREENLET_USE_PYCAPSULE
|
||||
#define PyGreenlet_Import() \
|
||||
{ \
|
||||
_PyGreenlet_API = (void**)PyCapsule_Import("greenlet._C_API", 0); \
|
||||
}
|
||||
#else
|
||||
#define PyGreenlet_Import() \
|
||||
{ \
|
||||
PyObject *module = PyImport_ImportModule("greenlet"); \
|
||||
if (module != NULL) { \
|
||||
PyObject *c_api_object = PyObject_GetAttrString( \
|
||||
module, "_C_API"); \
|
||||
if (c_api_object != NULL && PyCObject_Check(c_api_object)) { \
|
||||
_PyGreenlet_API = \
|
||||
(void **) PyCObject_AsVoidPtr(c_api_object); \
|
||||
Py_DECREF(c_api_object); \
|
||||
} \
|
||||
Py_DECREF(module); \
|
||||
} \
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* GREENLET_MODULE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* !Py_GREENLETOBJECT_H */
|
@ -0,0 +1,194 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: dill
|
||||
Version: 0.3.1.1
|
||||
Summary: serialize all of python
|
||||
Home-page: https://pypi.org/project/dill
|
||||
Author: Mike McKerns
|
||||
Maintainer: Mike McKerns
|
||||
License: 3-clause BSD
|
||||
Download-URL: https://github.com/uqfoundation/dill/releases/download/dill-0.3.1.1/dill-0.3.1.1.tar.gz
|
||||
Description: -----------------------------
|
||||
dill: serialize all of python
|
||||
-----------------------------
|
||||
|
||||
About Dill
|
||||
==========
|
||||
|
||||
``dill`` extends python's ``pickle`` module for serializing and de-serializing
|
||||
python objects to the majority of the built-in python types. Serialization
|
||||
is the process of converting an object to a byte stream, and the inverse
|
||||
of which is converting a byte stream back to on python object hierarchy.
|
||||
|
||||
``dill`` provides the user the same interface as the ``pickle`` module, and
|
||||
also includes some additional features. In addition to pickling python
|
||||
objects, ``dill`` provides the ability to save the state of an interpreter
|
||||
session in a single command. Hence, it would be feasable to save a
|
||||
interpreter session, close the interpreter, ship the pickled file to
|
||||
another computer, open a new interpreter, unpickle the session and
|
||||
thus continue from the 'saved' state of the original interpreter
|
||||
session.
|
||||
|
||||
``dill`` can be used to store python objects to a file, but the primary
|
||||
usage is to send python objects across the network as a byte stream.
|
||||
``dill`` is quite flexible, and allows arbitrary user defined classes
|
||||
and functions to be serialized. Thus ``dill`` is not intended to be
|
||||
secure against erroneously or maliciously constructed data. It is
|
||||
left to the user to decide whether the data they unpickle is from
|
||||
a trustworthy source.
|
||||
|
||||
``dill`` is part of ``pathos``, a python framework for heterogeneous computing.
|
||||
``dill`` is in active development, so any user feedback, bug reports, comments,
|
||||
or suggestions are highly appreciated. A list of known issues is maintained
|
||||
at http://trac.mystic.cacr.caltech.edu/project/pathos/query.html, with a public
|
||||
ticket list at https://github.com/uqfoundation/dill/issues.
|
||||
|
||||
|
||||
Major Features
|
||||
==============
|
||||
|
||||
``dill`` can pickle the following standard types:
|
||||
|
||||
- none, type, bool, int, long, float, complex, str, unicode,
|
||||
- tuple, list, dict, file, buffer, builtin,
|
||||
- both old and new style classes,
|
||||
- instances of old and new style classes,
|
||||
- set, frozenset, array, functions, exceptions
|
||||
|
||||
``dill`` can also pickle more 'exotic' standard types:
|
||||
|
||||
- functions with yields, nested functions, lambdas,
|
||||
- cell, method, unboundmethod, module, code, methodwrapper,
|
||||
- dictproxy, methoddescriptor, getsetdescriptor, memberdescriptor,
|
||||
- wrapperdescriptor, xrange, slice,
|
||||
- notimplemented, ellipsis, quit
|
||||
|
||||
``dill`` cannot yet pickle these standard types:
|
||||
|
||||
- frame, generator, traceback
|
||||
|
||||
``dill`` also provides the capability to:
|
||||
|
||||
- save and load python interpreter sessions
|
||||
- save and extract the source code from functions and classes
|
||||
- interactively diagnose pickling errors
|
||||
|
||||
|
||||
Current Release
|
||||
===============
|
||||
|
||||
This documentation is for version ``dill-0.3.1.1``.
|
||||
|
||||
The latest released version of ``dill`` is available from:
|
||||
|
||||
https://pypi.org/project/dill
|
||||
|
||||
``dill`` is distributed under a 3-clause BSD license.
|
||||
|
||||
>>> import dill
|
||||
>>> print (dill.license())
|
||||
|
||||
|
||||
Development Version
|
||||
===================
|
||||
|
||||
You can get the latest development version with all the shiny new features at:
|
||||
|
||||
https://github.com/uqfoundation
|
||||
|
||||
If you have a new contribution, please submit a pull request.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
``dill`` is packaged to install from source, so you must
|
||||
download the tarball, unzip, and run the installer::
|
||||
|
||||
[download]
|
||||
$ tar -xvzf dill-0.3.1.1.tar.gz
|
||||
$ cd dill-0.3.1.1
|
||||
$ python setup py build
|
||||
$ python setup py install
|
||||
|
||||
You will be warned of any missing dependencies and/or settings
|
||||
after you run the "build" step above.
|
||||
|
||||
Alternately, ``dill`` can be installed with ``pip`` or ``easy_install``::
|
||||
|
||||
$ pip install dill
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
``dill`` requires:
|
||||
|
||||
- ``python``, **version >= 2.6** or **version >= 3.1**, or ``pypy``
|
||||
|
||||
Optional requirements:
|
||||
|
||||
- ``setuptools``, **version >= 0.6**
|
||||
- ``pyreadline``, **version >= 1.7.1** (on windows)
|
||||
- ``objgraph``, **version >= 1.7.2**
|
||||
|
||||
|
||||
More Information
|
||||
================
|
||||
|
||||
Probably the best way to get started is to look at the documentation at
|
||||
http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
|
||||
demonstrate how ``dill`` can serialize different python objects. You can
|
||||
run the test suite with ``python -m dill.tests``. The contents of any
|
||||
pickle file can be examined with ``undill``. As ``dill`` conforms to
|
||||
the ``pickle`` interface, the examples and documentation found at
|
||||
http://docs.python.org/library/pickle.html also apply to ``dill``
|
||||
if one will ``import dill as pickle``. The source code is also generally
|
||||
well documented, so further questions may be resolved by inspecting the
|
||||
code itself. Please feel free to submit a ticket on github, or ask a
|
||||
question on stackoverflow (**@Mike McKerns**).
|
||||
If you would like to share how you use ``dill`` in your work, please send
|
||||
an email (to **mmckerns at uqfoundation dot org**).
|
||||
|
||||
|
||||
Citation
|
||||
========
|
||||
|
||||
If you use ``dill`` to do research that leads to publication, we ask that you
|
||||
acknowledge use of ``dill`` by citing the following in your publication::
|
||||
|
||||
M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
|
||||
"Building a framework for predictive science", Proceedings of
|
||||
the 10th Python in Science Conference, 2011;
|
||||
http://arxiv.org/pdf/1202.1056
|
||||
|
||||
Michael McKerns and Michael Aivazis,
|
||||
"pathos: a framework for heterogeneous computing", 2010- ;
|
||||
http://trac.mystic.cacr.caltech.edu/project/pathos
|
||||
|
||||
Please see http://trac.mystic.cacr.caltech.edu/project/pathos or
|
||||
http://arxiv.org/pdf/1202.1056 for further information.
|
||||
|
||||
|
||||
Platform: Linux
|
||||
Platform: Windows
|
||||
Platform: Mac
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Intended Audience :: Science/Research
|
||||
Classifier: License :: OSI Approved :: BSD License
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.1
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Topic :: Scientific/Engineering
|
||||
Classifier: Topic :: Software Development
|
||||
Requires-Python: >=2.6, !=3.0.*
|
||||
Provides-Extra: readline
|
||||
Provides-Extra: graph
|
@ -0,0 +1,47 @@
|
||||
LICENSE
|
||||
MANIFEST.in
|
||||
README
|
||||
setup.cfg
|
||||
setup.py
|
||||
tox.ini
|
||||
dill/__diff.py
|
||||
dill/__init__.py
|
||||
dill/_dill.py
|
||||
dill/_objects.py
|
||||
dill/detect.py
|
||||
dill/info.py
|
||||
dill/objtypes.py
|
||||
dill/pointers.py
|
||||
dill/settings.py
|
||||
dill/source.py
|
||||
dill/temp.py
|
||||
dill.egg-info/PKG-INFO
|
||||
dill.egg-info/SOURCES.txt
|
||||
dill.egg-info/dependency_links.txt
|
||||
dill.egg-info/not-zip-safe
|
||||
dill.egg-info/requires.txt
|
||||
dill.egg-info/top_level.txt
|
||||
scripts/get_objgraph
|
||||
scripts/undill
|
||||
tests/__init__.py
|
||||
tests/__main__.py
|
||||
tests/test_check.py
|
||||
tests/test_classdef.py
|
||||
tests/test_detect.py
|
||||
tests/test_diff.py
|
||||
tests/test_extendpickle.py
|
||||
tests/test_file.py
|
||||
tests/test_functions.py
|
||||
tests/test_functors.py
|
||||
tests/test_mixins.py
|
||||
tests/test_module.py
|
||||
tests/test_moduledict.py
|
||||
tests/test_nested.py
|
||||
tests/test_objects.py
|
||||
tests/test_properties.py
|
||||
tests/test_recursive.py
|
||||
tests/test_restricted.py
|
||||
tests/test_selected.py
|
||||
tests/test_source.py
|
||||
tests/test_temp.py
|
||||
tests/test_weakref.py
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,74 @@
|
||||
..\..\..\Scripts\get_objgraph
|
||||
..\..\..\Scripts\undill
|
||||
..\dill\__diff.py
|
||||
..\dill\__init__.py
|
||||
..\dill\__pycache__\__diff.cpython-36.pyc
|
||||
..\dill\__pycache__\__init__.cpython-36.pyc
|
||||
..\dill\__pycache__\_dill.cpython-36.pyc
|
||||
..\dill\__pycache__\_objects.cpython-36.pyc
|
||||
..\dill\__pycache__\detect.cpython-36.pyc
|
||||
..\dill\__pycache__\info.cpython-36.pyc
|
||||
..\dill\__pycache__\objtypes.cpython-36.pyc
|
||||
..\dill\__pycache__\pointers.cpython-36.pyc
|
||||
..\dill\__pycache__\settings.cpython-36.pyc
|
||||
..\dill\__pycache__\source.cpython-36.pyc
|
||||
..\dill\__pycache__\temp.cpython-36.pyc
|
||||
..\dill\_dill.py
|
||||
..\dill\_objects.py
|
||||
..\dill\detect.py
|
||||
..\dill\info.py
|
||||
..\dill\objtypes.py
|
||||
..\dill\pointers.py
|
||||
..\dill\settings.py
|
||||
..\dill\source.py
|
||||
..\dill\temp.py
|
||||
..\dill\tests\__init__.py
|
||||
..\dill\tests\__main__.py
|
||||
..\dill\tests\__pycache__\__init__.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\__main__.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_check.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_classdef.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_detect.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_diff.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_extendpickle.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_file.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_functions.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_functors.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_mixins.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_module.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_moduledict.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_nested.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_objects.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_properties.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_recursive.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_restricted.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_selected.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_source.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_temp.cpython-36.pyc
|
||||
..\dill\tests\__pycache__\test_weakref.cpython-36.pyc
|
||||
..\dill\tests\test_check.py
|
||||
..\dill\tests\test_classdef.py
|
||||
..\dill\tests\test_detect.py
|
||||
..\dill\tests\test_diff.py
|
||||
..\dill\tests\test_extendpickle.py
|
||||
..\dill\tests\test_file.py
|
||||
..\dill\tests\test_functions.py
|
||||
..\dill\tests\test_functors.py
|
||||
..\dill\tests\test_mixins.py
|
||||
..\dill\tests\test_module.py
|
||||
..\dill\tests\test_moduledict.py
|
||||
..\dill\tests\test_nested.py
|
||||
..\dill\tests\test_objects.py
|
||||
..\dill\tests\test_properties.py
|
||||
..\dill\tests\test_recursive.py
|
||||
..\dill\tests\test_restricted.py
|
||||
..\dill\tests\test_selected.py
|
||||
..\dill\tests\test_source.py
|
||||
..\dill\tests\test_temp.py
|
||||
..\dill\tests\test_weakref.py
|
||||
PKG-INFO
|
||||
SOURCES.txt
|
||||
dependency_links.txt
|
||||
not-zip-safe
|
||||
requires.txt
|
||||
top_level.txt
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1,6 @@
|
||||
|
||||
[graph]
|
||||
objgraph>=1.7.2
|
||||
|
||||
[readline]
|
||||
pyreadline>=1.7.1
|
@ -0,0 +1 @@
|
||||
dill
|
@ -0,0 +1,240 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
"""
|
||||
Module to show if an object has changed since it was memorised
|
||||
"""
|
||||
|
||||
import os
|
||||
import sys
|
||||
import types
|
||||
try:
|
||||
import numpy
|
||||
HAS_NUMPY = True
|
||||
except:
|
||||
HAS_NUMPY = False
|
||||
try:
|
||||
import builtins
|
||||
except ImportError:
|
||||
import __builtin__ as builtins
|
||||
|
||||
# pypy doesn't use reference counting
|
||||
getrefcount = getattr(sys, 'getrefcount', lambda x:0)
|
||||
|
||||
# memo of objects indexed by id to a tuple (attributes, sequence items)
|
||||
# attributes is a dict indexed by attribute name to attribute id
|
||||
# sequence items is either a list of ids, of a dictionary of keys to ids
|
||||
memo = {}
|
||||
id_to_obj = {}
|
||||
# types that cannot have changing attributes
|
||||
builtins_types = set((str, list, dict, set, frozenset, int))
|
||||
dont_memo = set(id(i) for i in (memo, sys.modules, sys.path_importer_cache,
|
||||
os.environ, id_to_obj))
|
||||
|
||||
|
||||
def get_attrs(obj):
|
||||
"""
|
||||
Gets all the attributes of an object though its __dict__ or return None
|
||||
"""
|
||||
if type(obj) in builtins_types \
|
||||
or type(obj) is type and obj in builtins_types:
|
||||
return
|
||||
try:
|
||||
return obj.__dict__
|
||||
except:
|
||||
return
|
||||
|
||||
|
||||
def get_seq(obj, cache={str: False, frozenset: False, list: True, set: True,
|
||||
dict: True, tuple: True, type: False,
|
||||
types.ModuleType: False, types.FunctionType: False,
|
||||
types.BuiltinFunctionType: False}):
|
||||
"""
|
||||
Gets all the items in a sequence or return None
|
||||
"""
|
||||
try:
|
||||
o_type = obj.__class__
|
||||
except AttributeError:
|
||||
o_type = type(obj)
|
||||
hsattr = hasattr
|
||||
if o_type in cache:
|
||||
if cache[o_type]:
|
||||
if hsattr(obj, "copy"):
|
||||
return obj.copy()
|
||||
return obj
|
||||
elif HAS_NUMPY and o_type in (numpy.ndarray, numpy.ma.core.MaskedConstant):
|
||||
if obj.shape and obj.size:
|
||||
return obj
|
||||
else:
|
||||
return []
|
||||
elif hsattr(obj, "__contains__") and hsattr(obj, "__iter__") \
|
||||
and hsattr(obj, "__len__") and hsattr(o_type, "__contains__") \
|
||||
and hsattr(o_type, "__iter__") and hsattr(o_type, "__len__"):
|
||||
cache[o_type] = True
|
||||
if hsattr(obj, "copy"):
|
||||
return obj.copy()
|
||||
return obj
|
||||
else:
|
||||
cache[o_type] = False
|
||||
return None
|
||||
|
||||
|
||||
def memorise(obj, force=False):
|
||||
"""
|
||||
Adds an object to the memo, and recursively adds all the objects
|
||||
attributes, and if it is a container, its items. Use force=True to update
|
||||
an object already in the memo. Updating is not recursively done.
|
||||
"""
|
||||
obj_id = id(obj)
|
||||
if obj_id in memo and not force or obj_id in dont_memo:
|
||||
return
|
||||
id_ = id
|
||||
g = get_attrs(obj)
|
||||
if g is None:
|
||||
attrs_id = None
|
||||
else:
|
||||
attrs_id = dict((key,id_(value)) for key, value in g.items())
|
||||
|
||||
s = get_seq(obj)
|
||||
if s is None:
|
||||
seq_id = None
|
||||
elif hasattr(s, "items"):
|
||||
seq_id = dict((id_(key),id_(value)) for key, value in s.items())
|
||||
elif not hasattr(s, "__len__"): #XXX: avoid TypeError from unexpected case
|
||||
seq_id = None
|
||||
else:
|
||||
seq_id = [id_(i) for i in s]
|
||||
|
||||
memo[obj_id] = attrs_id, seq_id
|
||||
id_to_obj[obj_id] = obj
|
||||
mem = memorise
|
||||
if g is not None:
|
||||
[mem(value) for key, value in g.items()]
|
||||
|
||||
if s is not None:
|
||||
if hasattr(s, "items"):
|
||||
[(mem(key), mem(item))
|
||||
for key, item in s.items()]
|
||||
else:
|
||||
if hasattr(s, '__len__'):
|
||||
[mem(item) for item in s]
|
||||
else: mem(s)
|
||||
|
||||
|
||||
def release_gone():
|
||||
itop, mp, src = id_to_obj.pop, memo.pop, getrefcount
|
||||
[(itop(id_), mp(id_)) for id_, obj in list(id_to_obj.items())
|
||||
if src(obj) < 4] #XXX: correct for pypy?
|
||||
|
||||
|
||||
def whats_changed(obj, seen=None, simple=False, first=True):
|
||||
"""
|
||||
Check an object against the memo. Returns a list in the form
|
||||
(attribute changes, container changed). Attribute changes is a dict of
|
||||
attribute name to attribute value. container changed is a boolean.
|
||||
If simple is true, just returns a boolean. None for either item means
|
||||
that it has not been checked yet
|
||||
"""
|
||||
# Special cases
|
||||
if first:
|
||||
# ignore the _ variable, which only appears in interactive sessions
|
||||
if "_" in builtins.__dict__:
|
||||
del builtins._
|
||||
if seen is None:
|
||||
seen = {}
|
||||
|
||||
obj_id = id(obj)
|
||||
|
||||
if obj_id in seen:
|
||||
if simple:
|
||||
return any(seen[obj_id])
|
||||
return seen[obj_id]
|
||||
|
||||
# Safety checks
|
||||
if obj_id in dont_memo:
|
||||
seen[obj_id] = [{}, False]
|
||||
if simple:
|
||||
return False
|
||||
return seen[obj_id]
|
||||
elif obj_id not in memo:
|
||||
if simple:
|
||||
return True
|
||||
else:
|
||||
raise RuntimeError("Object not memorised " + str(obj))
|
||||
|
||||
seen[obj_id] = ({}, False)
|
||||
|
||||
chngd = whats_changed
|
||||
id_ = id
|
||||
|
||||
# compare attributes
|
||||
attrs = get_attrs(obj)
|
||||
if attrs is None:
|
||||
changed = {}
|
||||
else:
|
||||
obj_attrs = memo[obj_id][0]
|
||||
obj_get = obj_attrs.get
|
||||
changed = dict((key,None) for key in obj_attrs if key not in attrs)
|
||||
for key, o in attrs.items():
|
||||
if id_(o) != obj_get(key, None) or chngd(o, seen, True, False):
|
||||
changed[key] = o
|
||||
|
||||
# compare sequence
|
||||
items = get_seq(obj)
|
||||
seq_diff = False
|
||||
if (items is not None) and (hasattr(items, '__len__')):
|
||||
obj_seq = memo[obj_id][1]
|
||||
if (len(items) != len(obj_seq)):
|
||||
seq_diff = True
|
||||
elif hasattr(obj, "items"): # dict type obj
|
||||
obj_get = obj_seq.get
|
||||
for key, item in items.items():
|
||||
if id_(item) != obj_get(id_(key)) \
|
||||
or chngd(key, seen, True, False) \
|
||||
or chngd(item, seen, True, False):
|
||||
seq_diff = True
|
||||
break
|
||||
else:
|
||||
for i, j in zip(items, obj_seq): # list type obj
|
||||
if id_(i) != j or chngd(i, seen, True, False):
|
||||
seq_diff = True
|
||||
break
|
||||
seen[obj_id] = changed, seq_diff
|
||||
if simple:
|
||||
return changed or seq_diff
|
||||
return changed, seq_diff
|
||||
|
||||
|
||||
def has_changed(*args, **kwds):
|
||||
kwds['simple'] = True # ignore simple if passed in
|
||||
return whats_changed(*args, **kwds)
|
||||
|
||||
__import__ = __import__
|
||||
|
||||
|
||||
def _imp(*args, **kwds):
|
||||
"""
|
||||
Replaces the default __import__, to allow a module to be memorised
|
||||
before the user can change it
|
||||
"""
|
||||
before = set(sys.modules.keys())
|
||||
mod = __import__(*args, **kwds)
|
||||
after = set(sys.modules.keys()).difference(before)
|
||||
for m in after:
|
||||
memorise(sys.modules[m])
|
||||
return mod
|
||||
|
||||
builtins.__import__ = _imp
|
||||
if hasattr(builtins, "_"):
|
||||
del builtins._
|
||||
|
||||
# memorise all already imported modules. This implies that this must be
|
||||
# imported first for any changes to be recorded
|
||||
for mod in sys.modules.values():
|
||||
memorise(mod)
|
||||
release_gone()
|
@ -0,0 +1,127 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
# get version numbers, license, and long description
|
||||
try:
|
||||
from .info import this_version as __version__
|
||||
from .info import readme as __doc__, license as __license__
|
||||
except ImportError:
|
||||
msg = """First run 'python setup.py build' to build dill."""
|
||||
raise ImportError(msg)
|
||||
|
||||
__author__ = 'Mike McKerns'
|
||||
|
||||
__doc__ = """
|
||||
""" + __doc__
|
||||
|
||||
__license__ = """
|
||||
""" + __license__
|
||||
|
||||
from ._dill import dump, dumps, load, loads, dump_session, load_session, \
|
||||
Pickler, Unpickler, register, copy, pickle, pickles, check, \
|
||||
HIGHEST_PROTOCOL, DEFAULT_PROTOCOL, PicklingError, UnpicklingError, \
|
||||
HANDLE_FMODE, CONTENTS_FMODE, FILE_FMODE
|
||||
from . import source, temp, detect
|
||||
|
||||
# get global settings
|
||||
from .settings import settings
|
||||
|
||||
# make sure "trace" is turned off
|
||||
detect.trace(False)
|
||||
|
||||
try:
|
||||
from importlib import reload
|
||||
except ImportError:
|
||||
try:
|
||||
from imp import reload
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
# put the objects in order, if possible
|
||||
try:
|
||||
from collections import OrderedDict as odict
|
||||
except ImportError:
|
||||
try:
|
||||
from ordereddict import OrderedDict as odict
|
||||
except ImportError:
|
||||
odict = dict
|
||||
objects = odict()
|
||||
# local import of dill._objects
|
||||
#from . import _objects
|
||||
#objects.update(_objects.succeeds)
|
||||
#del _objects
|
||||
|
||||
# local import of dill.objtypes
|
||||
from . import objtypes as types
|
||||
|
||||
def load_types(pickleable=True, unpickleable=True):
|
||||
"""load pickleable and/or unpickleable types to ``dill.types``
|
||||
|
||||
``dill.types`` is meant to mimic the ``types`` module, providing a
|
||||
registry of object types. By default, the module is empty (for import
|
||||
speed purposes). Use the ``load_types`` function to load selected object
|
||||
types to the ``dill.types`` module.
|
||||
|
||||
Args:
|
||||
pickleable (bool, default=True): if True, load pickleable types.
|
||||
unpickleable (bool, default=True): if True, load unpickleable types.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
# local import of dill.objects
|
||||
from . import _objects
|
||||
if pickleable:
|
||||
objects.update(_objects.succeeds)
|
||||
else:
|
||||
[objects.pop(obj,None) for obj in _objects.succeeds]
|
||||
if unpickleable:
|
||||
objects.update(_objects.failures)
|
||||
else:
|
||||
[objects.pop(obj,None) for obj in _objects.failures]
|
||||
objects.update(_objects.registered)
|
||||
del _objects
|
||||
# reset contents of types to 'empty'
|
||||
[types.__dict__.pop(obj) for obj in list(types.__dict__.keys()) \
|
||||
if obj.find('Type') != -1]
|
||||
# add corresponding types from objects to types
|
||||
reload(types)
|
||||
|
||||
def extend(use_dill=True):
|
||||
'''add (or remove) dill types to/from the pickle registry
|
||||
|
||||
by default, ``dill`` populates its types to ``pickle.Pickler.dispatch``.
|
||||
Thus, all ``dill`` types are available upon calling ``'import pickle'``.
|
||||
To drop all ``dill`` types from the ``pickle`` dispatch, *use_dill=False*.
|
||||
|
||||
Args:
|
||||
use_dill (bool, default=True): if True, extend the dispatch table.
|
||||
|
||||
Returns:
|
||||
None
|
||||
'''
|
||||
from ._dill import _revert_extension, _extend
|
||||
if use_dill: _extend()
|
||||
else: _revert_extension()
|
||||
return
|
||||
|
||||
extend()
|
||||
|
||||
def license():
|
||||
"""print license"""
|
||||
print (__license__)
|
||||
return
|
||||
|
||||
def citation():
|
||||
"""print citation"""
|
||||
print (__doc__[-501:-123])
|
||||
return
|
||||
|
||||
del odict
|
||||
|
||||
# end of file
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,558 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
all Python Standard Library objects (currently: CH 1-15 @ 2.7)
|
||||
and some other common objects (i.e. numpy.ndarray)
|
||||
"""
|
||||
|
||||
__all__ = ['registered','failures','succeeds']
|
||||
|
||||
# helper imports
|
||||
import warnings; warnings.filterwarnings("ignore", category=DeprecationWarning)
|
||||
import sys
|
||||
PY3 = (hex(sys.hexversion) >= '0x30000f0')
|
||||
if PY3:
|
||||
import queue as Queue
|
||||
import dbm as anydbm
|
||||
else:
|
||||
import Queue
|
||||
import anydbm
|
||||
import sets # deprecated/removed
|
||||
import mutex # removed
|
||||
try:
|
||||
from cStringIO import StringIO # has StringI and StringO types
|
||||
except ImportError: # only has StringIO type
|
||||
if PY3:
|
||||
from io import BytesIO as StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
import re
|
||||
import array
|
||||
import collections
|
||||
import codecs
|
||||
import struct
|
||||
import datetime
|
||||
import calendar
|
||||
import weakref
|
||||
import pprint
|
||||
import decimal
|
||||
import functools
|
||||
import itertools
|
||||
import operator
|
||||
import tempfile
|
||||
import shelve
|
||||
import zlib
|
||||
import gzip
|
||||
import zipfile
|
||||
import tarfile
|
||||
import xdrlib
|
||||
import csv
|
||||
import hashlib
|
||||
import hmac
|
||||
import os
|
||||
import logging
|
||||
import optparse
|
||||
#import __hello__
|
||||
import threading
|
||||
import socket
|
||||
import contextlib
|
||||
try:
|
||||
import bz2
|
||||
import sqlite3
|
||||
if PY3: import dbm.ndbm as dbm
|
||||
else: import dbm
|
||||
HAS_ALL = True
|
||||
except ImportError: # Ubuntu
|
||||
HAS_ALL = False
|
||||
try:
|
||||
#import curses
|
||||
#from curses import textpad, panel
|
||||
HAS_CURSES = True
|
||||
except ImportError: # Windows
|
||||
HAS_CURSES = False
|
||||
try:
|
||||
import ctypes
|
||||
HAS_CTYPES = True
|
||||
# if using `pypy`, pythonapi is not found
|
||||
IS_PYPY = not hasattr(ctypes, 'pythonapi')
|
||||
except ImportError: # MacPorts
|
||||
HAS_CTYPES = False
|
||||
IS_PYPY = False
|
||||
|
||||
# helper objects
|
||||
class _class:
|
||||
def _method(self):
|
||||
pass
|
||||
# @classmethod
|
||||
# def _clsmethod(cls): #XXX: test me
|
||||
# pass
|
||||
# @staticmethod
|
||||
# def _static(self): #XXX: test me
|
||||
# pass
|
||||
class _class2:
|
||||
def __call__(self):
|
||||
pass
|
||||
_instance2 = _class2()
|
||||
class _newclass(object):
|
||||
def _method(self):
|
||||
pass
|
||||
# @classmethod
|
||||
# def _clsmethod(cls): #XXX: test me
|
||||
# pass
|
||||
# @staticmethod
|
||||
# def _static(self): #XXX: test me
|
||||
# pass
|
||||
class _newclass2(object):
|
||||
__slots__ = ['descriptor']
|
||||
def _function(x): yield x
|
||||
def _function2():
|
||||
try: raise
|
||||
except:
|
||||
from sys import exc_info
|
||||
e, er, tb = exc_info()
|
||||
return er, tb
|
||||
if HAS_CTYPES:
|
||||
class _Struct(ctypes.Structure):
|
||||
pass
|
||||
_Struct._fields_ = [("_field", ctypes.c_int),("next", ctypes.POINTER(_Struct))]
|
||||
_filedescrip, _tempfile = tempfile.mkstemp('r') # deleted in cleanup
|
||||
_tmpf = tempfile.TemporaryFile('w')
|
||||
|
||||
# put the objects in order, if possible
|
||||
try:
|
||||
from collections import OrderedDict as odict
|
||||
except ImportError:
|
||||
try:
|
||||
from ordereddict import OrderedDict as odict
|
||||
except ImportError:
|
||||
odict = dict
|
||||
# objects used by dill for type declaration
|
||||
registered = d = odict()
|
||||
# objects dill fails to pickle
|
||||
failures = x = odict()
|
||||
# all other type objects
|
||||
succeeds = a = odict()
|
||||
|
||||
# types module (part of CH 8)
|
||||
a['BooleanType'] = bool(1)
|
||||
a['BuiltinFunctionType'] = len
|
||||
a['BuiltinMethodType'] = a['BuiltinFunctionType']
|
||||
a['BytesType'] = _bytes = codecs.latin_1_encode('\x00')[0] # bytes(1)
|
||||
a['ClassType'] = _class
|
||||
a['ComplexType'] = complex(1)
|
||||
a['DictType'] = _dict = {}
|
||||
a['DictionaryType'] = a['DictType']
|
||||
a['FloatType'] = float(1)
|
||||
a['FunctionType'] = _function
|
||||
a['InstanceType'] = _instance = _class()
|
||||
a['IntType'] = _int = int(1)
|
||||
a['ListType'] = _list = []
|
||||
a['NoneType'] = None
|
||||
a['ObjectType'] = object()
|
||||
a['StringType'] = _str = str(1)
|
||||
a['TupleType'] = _tuple = ()
|
||||
a['TypeType'] = type
|
||||
if PY3:
|
||||
a['LongType'] = _int
|
||||
a['UnicodeType'] = _str
|
||||
else:
|
||||
a['LongType'] = long(1)
|
||||
a['UnicodeType'] = unicode(1)
|
||||
# built-in constants (CH 4)
|
||||
a['CopyrightType'] = copyright
|
||||
# built-in types (CH 5)
|
||||
a['ClassObjectType'] = _newclass # <type 'type'>
|
||||
a['ClassInstanceType'] = _newclass() # <type 'class'>
|
||||
a['SetType'] = _set = set()
|
||||
a['FrozenSetType'] = frozenset()
|
||||
# built-in exceptions (CH 6)
|
||||
a['ExceptionType'] = _exception = _function2()[0]
|
||||
# string services (CH 7)
|
||||
a['SREPatternType'] = _srepattern = re.compile('')
|
||||
# data types (CH 8)
|
||||
a['ArrayType'] = array.array("f")
|
||||
a['DequeType'] = collections.deque([0])
|
||||
a['DefaultDictType'] = collections.defaultdict(_function, _dict)
|
||||
a['TZInfoType'] = datetime.tzinfo()
|
||||
a['DateTimeType'] = datetime.datetime.today()
|
||||
a['CalendarType'] = calendar.Calendar()
|
||||
if not PY3:
|
||||
a['SetsType'] = sets.Set()
|
||||
a['ImmutableSetType'] = sets.ImmutableSet()
|
||||
a['MutexType'] = mutex.mutex()
|
||||
# numeric and mathematical types (CH 9)
|
||||
a['DecimalType'] = decimal.Decimal(1)
|
||||
a['CountType'] = itertools.count(0)
|
||||
# data compression and archiving (CH 12)
|
||||
a['TarInfoType'] = tarfile.TarInfo()
|
||||
# generic operating system services (CH 15)
|
||||
a['LoggerType'] = logging.getLogger()
|
||||
a['FormatterType'] = logging.Formatter() # pickle ok
|
||||
a['FilterType'] = logging.Filter() # pickle ok
|
||||
a['LogRecordType'] = logging.makeLogRecord(_dict) # pickle ok
|
||||
a['OptionParserType'] = _oparser = optparse.OptionParser() # pickle ok
|
||||
a['OptionGroupType'] = optparse.OptionGroup(_oparser,"foo") # pickle ok
|
||||
a['OptionType'] = optparse.Option('--foo') # pickle ok
|
||||
if HAS_CTYPES:
|
||||
a['CCharType'] = _cchar = ctypes.c_char()
|
||||
a['CWCharType'] = ctypes.c_wchar() # fail == 2.6
|
||||
a['CByteType'] = ctypes.c_byte()
|
||||
a['CUByteType'] = ctypes.c_ubyte()
|
||||
a['CShortType'] = ctypes.c_short()
|
||||
a['CUShortType'] = ctypes.c_ushort()
|
||||
a['CIntType'] = ctypes.c_int()
|
||||
a['CUIntType'] = ctypes.c_uint()
|
||||
a['CLongType'] = ctypes.c_long()
|
||||
a['CULongType'] = ctypes.c_ulong()
|
||||
a['CLongLongType'] = ctypes.c_longlong()
|
||||
a['CULongLongType'] = ctypes.c_ulonglong()
|
||||
a['CFloatType'] = ctypes.c_float()
|
||||
a['CDoubleType'] = ctypes.c_double()
|
||||
a['CSizeTType'] = ctypes.c_size_t()
|
||||
a['CLibraryLoaderType'] = ctypes.cdll
|
||||
a['StructureType'] = _Struct
|
||||
if not IS_PYPY:
|
||||
a['BigEndianStructureType'] = ctypes.BigEndianStructure()
|
||||
#NOTE: also LittleEndianStructureType and UnionType... abstract classes
|
||||
#NOTE: remember for ctypesobj.contents creates a new python object
|
||||
#NOTE: ctypes.c_int._objects is memberdescriptor for object's __dict__
|
||||
#NOTE: base class of all ctypes data types is non-public _CData
|
||||
|
||||
try: # python 2.6
|
||||
import fractions
|
||||
import number
|
||||
import io
|
||||
from io import StringIO as TextIO
|
||||
# built-in functions (CH 2)
|
||||
a['ByteArrayType'] = bytearray([1])
|
||||
# numeric and mathematical types (CH 9)
|
||||
a['FractionType'] = fractions.Fraction()
|
||||
a['NumberType'] = numbers.Number()
|
||||
# generic operating system services (CH 15)
|
||||
a['IOBaseType'] = io.IOBase()
|
||||
a['RawIOBaseType'] = io.RawIOBase()
|
||||
a['TextIOBaseType'] = io.TextIOBase()
|
||||
a['BufferedIOBaseType'] = io.BufferedIOBase()
|
||||
a['UnicodeIOType'] = TextIO() # the new StringIO
|
||||
a['LoggingAdapterType'] = logging.LoggingAdapter(_logger,_dict) # pickle ok
|
||||
if HAS_CTYPES:
|
||||
a['CBoolType'] = ctypes.c_bool(1)
|
||||
a['CLongDoubleType'] = ctypes.c_longdouble()
|
||||
except ImportError:
|
||||
pass
|
||||
try: # python 2.7
|
||||
import argparse
|
||||
# data types (CH 8)
|
||||
a['OrderedDictType'] = collections.OrderedDict(_dict)
|
||||
a['CounterType'] = collections.Counter(_dict)
|
||||
if HAS_CTYPES:
|
||||
a['CSSizeTType'] = ctypes.c_ssize_t()
|
||||
# generic operating system services (CH 15)
|
||||
a['NullHandlerType'] = logging.NullHandler() # pickle ok # new 2.7
|
||||
a['ArgParseFileType'] = argparse.FileType() # pickle ok
|
||||
except (AttributeError, ImportError):
|
||||
pass
|
||||
|
||||
# -- pickle fails on all below here -----------------------------------------
|
||||
# types module (part of CH 8)
|
||||
a['CodeType'] = compile('','','exec')
|
||||
a['DictProxyType'] = type.__dict__
|
||||
a['DictProxyType2'] = _newclass.__dict__
|
||||
a['EllipsisType'] = Ellipsis
|
||||
a['ClosedFileType'] = open(os.devnull, 'wb', buffering=0).close()
|
||||
a['GetSetDescriptorType'] = array.array.typecode
|
||||
a['LambdaType'] = _lambda = lambda x: lambda y: x #XXX: works when not imported!
|
||||
a['MemberDescriptorType'] = _newclass2.descriptor
|
||||
if not IS_PYPY:
|
||||
a['MemberDescriptorType2'] = datetime.timedelta.days
|
||||
a['MethodType'] = _method = _class()._method #XXX: works when not imported!
|
||||
a['ModuleType'] = datetime
|
||||
a['NotImplementedType'] = NotImplemented
|
||||
a['SliceType'] = slice(1)
|
||||
a['UnboundMethodType'] = _class._method #XXX: works when not imported!
|
||||
a['TextWrapperType'] = open(os.devnull, 'r') # same as mode='w','w+','r+'
|
||||
a['BufferedRandomType'] = open(os.devnull, 'r+b') # same as mode='w+b'
|
||||
a['BufferedReaderType'] = open(os.devnull, 'rb') # (default: buffering=-1)
|
||||
a['BufferedWriterType'] = open(os.devnull, 'wb')
|
||||
try: # oddities: deprecated
|
||||
from _pyio import open as _open
|
||||
a['PyTextWrapperType'] = _open(os.devnull, 'r', buffering=-1)
|
||||
a['PyBufferedRandomType'] = _open(os.devnull, 'r+b', buffering=-1)
|
||||
a['PyBufferedReaderType'] = _open(os.devnull, 'rb', buffering=-1)
|
||||
a['PyBufferedWriterType'] = _open(os.devnull, 'wb', buffering=-1)
|
||||
except ImportError:
|
||||
pass
|
||||
# other (concrete) object types
|
||||
if PY3:
|
||||
d['CellType'] = (_lambda)(0).__closure__[0]
|
||||
a['XRangeType'] = _xrange = range(1)
|
||||
else:
|
||||
d['CellType'] = (_lambda)(0).func_closure[0]
|
||||
a['XRangeType'] = _xrange = xrange(1)
|
||||
if not IS_PYPY:
|
||||
d['MethodDescriptorType'] = type.__dict__['mro']
|
||||
d['WrapperDescriptorType'] = type.__repr__
|
||||
a['WrapperDescriptorType2'] = type.__dict__['__module__']
|
||||
d['ClassMethodDescriptorType'] = type.__dict__['__prepare__' if PY3 else 'mro']
|
||||
# built-in functions (CH 2)
|
||||
if PY3 or IS_PYPY:
|
||||
_methodwrap = (1).__lt__
|
||||
else:
|
||||
_methodwrap = (1).__cmp__
|
||||
d['MethodWrapperType'] = _methodwrap
|
||||
a['StaticMethodType'] = staticmethod(_method)
|
||||
a['ClassMethodType'] = classmethod(_method)
|
||||
a['PropertyType'] = property()
|
||||
d['SuperType'] = super(Exception, _exception)
|
||||
# string services (CH 7)
|
||||
if PY3:
|
||||
_in = _bytes
|
||||
else:
|
||||
_in = _str
|
||||
a['InputType'] = _cstrI = StringIO(_in)
|
||||
a['OutputType'] = _cstrO = StringIO()
|
||||
# data types (CH 8)
|
||||
a['WeakKeyDictionaryType'] = weakref.WeakKeyDictionary()
|
||||
a['WeakValueDictionaryType'] = weakref.WeakValueDictionary()
|
||||
a['ReferenceType'] = weakref.ref(_instance)
|
||||
a['DeadReferenceType'] = weakref.ref(_class())
|
||||
a['ProxyType'] = weakref.proxy(_instance)
|
||||
a['DeadProxyType'] = weakref.proxy(_class())
|
||||
a['CallableProxyType'] = weakref.proxy(_instance2)
|
||||
a['DeadCallableProxyType'] = weakref.proxy(_class2())
|
||||
a['QueueType'] = Queue.Queue()
|
||||
# numeric and mathematical types (CH 9)
|
||||
d['PartialType'] = functools.partial(int,base=2)
|
||||
if PY3:
|
||||
a['IzipType'] = zip('0','1')
|
||||
else:
|
||||
a['IzipType'] = itertools.izip('0','1')
|
||||
a['ChainType'] = itertools.chain('0','1')
|
||||
d['ItemGetterType'] = operator.itemgetter(0)
|
||||
d['AttrGetterType'] = operator.attrgetter('__repr__')
|
||||
# file and directory access (CH 10)
|
||||
if PY3: _fileW = _cstrO
|
||||
else: _fileW = _tmpf
|
||||
# data persistence (CH 11)
|
||||
if HAS_ALL:
|
||||
a['ConnectionType'] = _conn = sqlite3.connect(':memory:')
|
||||
a['CursorType'] = _conn.cursor()
|
||||
a['ShelveType'] = shelve.Shelf({})
|
||||
# data compression and archiving (CH 12)
|
||||
if HAS_ALL:
|
||||
if (hex(sys.hexversion) < '0x2070ef0') or PY3:
|
||||
a['BZ2FileType'] = bz2.BZ2File(os.devnull) #FIXME: fail >= 3.3, 2.7.14
|
||||
a['BZ2CompressorType'] = bz2.BZ2Compressor()
|
||||
a['BZ2DecompressorType'] = bz2.BZ2Decompressor()
|
||||
#a['ZipFileType'] = _zip = zipfile.ZipFile(os.devnull,'w') #FIXME: fail >= 3.2
|
||||
#_zip.write(_tempfile,'x') [causes annoying warning/error printed on import]
|
||||
#a['ZipInfoType'] = _zip.getinfo('x')
|
||||
a['TarFileType'] = tarfile.open(fileobj=_fileW,mode='w')
|
||||
# file formats (CH 13)
|
||||
a['DialectType'] = csv.get_dialect('excel')
|
||||
a['PackerType'] = xdrlib.Packer()
|
||||
# optional operating system services (CH 16)
|
||||
a['LockType'] = threading.Lock()
|
||||
a['RLockType'] = threading.RLock()
|
||||
# generic operating system services (CH 15) # also closed/open and r/w/etc...
|
||||
a['NamedLoggerType'] = _logger = logging.getLogger(__name__) #FIXME: fail >= 3.2 and <= 2.6
|
||||
#a['FrozenModuleType'] = __hello__ #FIXME: prints "Hello world..."
|
||||
# interprocess communication (CH 17)
|
||||
if PY3:
|
||||
a['SocketType'] = _socket = socket.socket() #FIXME: fail >= 3.3
|
||||
a['SocketPairType'] = socket.socketpair()[0] #FIXME: fail >= 3.3
|
||||
else:
|
||||
a['SocketType'] = _socket = socket.socket()
|
||||
a['SocketPairType'] = _socket._sock
|
||||
# python runtime services (CH 27)
|
||||
if PY3:
|
||||
a['GeneratorContextManagerType'] = contextlib.contextmanager(max)([1])
|
||||
else:
|
||||
a['GeneratorContextManagerType'] = contextlib.GeneratorContextManager(max)
|
||||
|
||||
try: # ipython
|
||||
__IPYTHON__ is True # is ipython
|
||||
except NameError:
|
||||
# built-in constants (CH 4)
|
||||
a['QuitterType'] = quit
|
||||
d['ExitType'] = a['QuitterType']
|
||||
try: # numpy #FIXME: slow... 0.05 to 0.1 sec to import numpy
|
||||
from numpy import ufunc as _numpy_ufunc
|
||||
from numpy import array as _numpy_array
|
||||
from numpy import int32 as _numpy_int32
|
||||
a['NumpyUfuncType'] = _numpy_ufunc
|
||||
a['NumpyArrayType'] = _numpy_array
|
||||
a['NumpyInt32Type'] = _numpy_int32
|
||||
except ImportError:
|
||||
pass
|
||||
try: # python 2.6
|
||||
# numeric and mathematical types (CH 9)
|
||||
a['ProductType'] = itertools.product('0','1')
|
||||
# generic operating system services (CH 15)
|
||||
a['FileHandlerType'] = logging.FileHandler(os.devnull) #FIXME: fail >= 3.2 and <= 2.6
|
||||
a['RotatingFileHandlerType'] = logging.handlers.RotatingFileHandler(os.devnull)
|
||||
a['SocketHandlerType'] = logging.handlers.SocketHandler('localhost',514)
|
||||
a['MemoryHandlerType'] = logging.handlers.MemoryHandler(1)
|
||||
except AttributeError:
|
||||
pass
|
||||
try: # python 2.7
|
||||
# data types (CH 8)
|
||||
a['WeakSetType'] = weakref.WeakSet() # 2.7
|
||||
# # generic operating system services (CH 15) [errors when dill is imported]
|
||||
# a['ArgumentParserType'] = _parser = argparse.ArgumentParser('PROG')
|
||||
# a['NamespaceType'] = _parser.parse_args() # pickle ok
|
||||
# a['SubParsersActionType'] = _parser.add_subparsers()
|
||||
# a['MutuallyExclusiveGroupType'] = _parser.add_mutually_exclusive_group()
|
||||
# a['ArgumentGroupType'] = _parser.add_argument_group()
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# -- dill fails in some versions below here ---------------------------------
|
||||
# types module (part of CH 8)
|
||||
a['FileType'] = open(os.devnull, 'rb', buffering=0) # same 'wb','wb+','rb+'
|
||||
# FIXME: FileType fails >= 3.1
|
||||
# built-in functions (CH 2)
|
||||
a['ListIteratorType'] = iter(_list) # empty vs non-empty FIXME: fail < 3.2
|
||||
a['TupleIteratorType']= iter(_tuple) # empty vs non-empty FIXME: fail < 3.2
|
||||
a['XRangeIteratorType'] = iter(_xrange) # empty vs non-empty FIXME: fail < 3.2
|
||||
# data types (CH 8)
|
||||
a['PrettyPrinterType'] = pprint.PrettyPrinter() #FIXME: fail >= 3.2 and == 2.5
|
||||
# numeric and mathematical types (CH 9)
|
||||
a['CycleType'] = itertools.cycle('0') #FIXME: fail < 3.2
|
||||
# file and directory access (CH 10)
|
||||
a['TemporaryFileType'] = _tmpf #FIXME: fail >= 3.2 and == 2.5
|
||||
# data compression and archiving (CH 12)
|
||||
a['GzipFileType'] = gzip.GzipFile(fileobj=_fileW) #FIXME: fail > 3.2 and <= 2.6
|
||||
# generic operating system services (CH 15)
|
||||
a['StreamHandlerType'] = logging.StreamHandler() #FIXME: fail >= 3.2 and == 2.5
|
||||
try: # python 2.6
|
||||
# numeric and mathematical types (CH 9)
|
||||
a['PermutationsType'] = itertools.permutations('0') #FIXME: fail < 3.2
|
||||
a['CombinationsType'] = itertools.combinations('0',1) #FIXME: fail < 3.2
|
||||
except AttributeError:
|
||||
pass
|
||||
try: # python 2.7
|
||||
# numeric and mathematical types (CH 9)
|
||||
a['RepeatType'] = itertools.repeat(0) #FIXME: fail < 3.2
|
||||
a['CompressType'] = itertools.compress('0',[1]) #FIXME: fail < 3.2
|
||||
#XXX: ...and etc
|
||||
except AttributeError:
|
||||
pass
|
||||
|
||||
# -- dill fails on all below here -------------------------------------------
|
||||
# types module (part of CH 8)
|
||||
x['GeneratorType'] = _generator = _function(1) #XXX: priority
|
||||
x['FrameType'] = _generator.gi_frame #XXX: inspect.currentframe()
|
||||
x['TracebackType'] = _function2()[1] #(see: inspect.getouterframes,getframeinfo)
|
||||
# other (concrete) object types
|
||||
# (also: Capsule / CObject ?)
|
||||
# built-in functions (CH 2)
|
||||
x['SetIteratorType'] = iter(_set) #XXX: empty vs non-empty
|
||||
# built-in types (CH 5)
|
||||
if PY3:
|
||||
x['DictionaryItemIteratorType'] = iter(type.__dict__.items())
|
||||
x['DictionaryKeyIteratorType'] = iter(type.__dict__.keys())
|
||||
x['DictionaryValueIteratorType'] = iter(type.__dict__.values())
|
||||
else:
|
||||
x['DictionaryItemIteratorType'] = type.__dict__.iteritems()
|
||||
x['DictionaryKeyIteratorType'] = type.__dict__.iterkeys()
|
||||
x['DictionaryValueIteratorType'] = type.__dict__.itervalues()
|
||||
# string services (CH 7)
|
||||
x['StructType'] = struct.Struct('c')
|
||||
x['CallableIteratorType'] = _srepattern.finditer('')
|
||||
x['SREMatchType'] = _srepattern.match('')
|
||||
x['SREScannerType'] = _srepattern.scanner('')
|
||||
x['StreamReader'] = codecs.StreamReader(_cstrI) #XXX: ... and etc
|
||||
# python object persistence (CH 11)
|
||||
# x['DbShelveType'] = shelve.open('foo','n')#,protocol=2) #XXX: delete foo
|
||||
if HAS_ALL:
|
||||
x['DbmType'] = dbm.open(_tempfile,'n')
|
||||
# x['DbCursorType'] = _dbcursor = anydbm.open('foo','n') #XXX: delete foo
|
||||
# x['DbType'] = _dbcursor.db
|
||||
# data compression and archiving (CH 12)
|
||||
x['ZlibCompressType'] = zlib.compressobj()
|
||||
x['ZlibDecompressType'] = zlib.decompressobj()
|
||||
# file formats (CH 13)
|
||||
x['CSVReaderType'] = csv.reader(_cstrI)
|
||||
x['CSVWriterType'] = csv.writer(_cstrO)
|
||||
x['CSVDictReaderType'] = csv.DictReader(_cstrI)
|
||||
x['CSVDictWriterType'] = csv.DictWriter(_cstrO,{})
|
||||
# cryptographic services (CH 14)
|
||||
x['HashType'] = hashlib.md5()
|
||||
if (hex(sys.hexversion) < '0x30800a1'):
|
||||
x['HMACType'] = hmac.new(_in)
|
||||
else:
|
||||
x['HMACType'] = hmac.new(_in, digestmod='md5')
|
||||
# generic operating system services (CH 15)
|
||||
if HAS_CURSES: pass
|
||||
#x['CursesWindowType'] = _curwin = curses.initscr() #FIXME: messes up tty
|
||||
#x['CursesTextPadType'] = textpad.Textbox(_curwin)
|
||||
#x['CursesPanelType'] = panel.new_panel(_curwin)
|
||||
if HAS_CTYPES:
|
||||
x['CCharPType'] = ctypes.c_char_p()
|
||||
x['CWCharPType'] = ctypes.c_wchar_p()
|
||||
x['CVoidPType'] = ctypes.c_void_p()
|
||||
if sys.platform[:3] == 'win':
|
||||
x['CDLLType'] = _cdll = ctypes.cdll.msvcrt
|
||||
else:
|
||||
x['CDLLType'] = _cdll = ctypes.CDLL(None)
|
||||
if not IS_PYPY:
|
||||
x['PyDLLType'] = _pydll = ctypes.pythonapi
|
||||
x['FuncPtrType'] = _cdll._FuncPtr()
|
||||
x['CCharArrayType'] = ctypes.create_string_buffer(1)
|
||||
x['CWCharArrayType'] = ctypes.create_unicode_buffer(1)
|
||||
x['CParamType'] = ctypes.byref(_cchar)
|
||||
x['LPCCharType'] = ctypes.pointer(_cchar)
|
||||
x['LPCCharObjType'] = _lpchar = ctypes.POINTER(ctypes.c_char)
|
||||
x['NullPtrType'] = _lpchar()
|
||||
x['NullPyObjectType'] = ctypes.py_object()
|
||||
x['PyObjectType'] = ctypes.py_object(lambda :None)
|
||||
x['FieldType'] = _field = _Struct._field
|
||||
x['CFUNCTYPEType'] = _cfunc = ctypes.CFUNCTYPE(ctypes.c_char)
|
||||
x['CFunctionType'] = _cfunc(str)
|
||||
try: # python 2.6
|
||||
# numeric and mathematical types (CH 9)
|
||||
x['MethodCallerType'] = operator.methodcaller('mro') # 2.6
|
||||
except AttributeError:
|
||||
pass
|
||||
try: # python 2.7
|
||||
# built-in types (CH 5)
|
||||
x['MemoryType'] = memoryview(_in) # 2.7
|
||||
x['MemoryType2'] = memoryview(bytearray(_in)) # 2.7
|
||||
if PY3:
|
||||
x['DictItemsType'] = _dict.items() # 2.7
|
||||
x['DictKeysType'] = _dict.keys() # 2.7
|
||||
x['DictValuesType'] = _dict.values() # 2.7
|
||||
else:
|
||||
x['DictItemsType'] = _dict.viewitems() # 2.7
|
||||
x['DictKeysType'] = _dict.viewkeys() # 2.7
|
||||
x['DictValuesType'] = _dict.viewvalues() # 2.7
|
||||
# generic operating system services (CH 15)
|
||||
x['RawTextHelpFormatterType'] = argparse.RawTextHelpFormatter('PROG')
|
||||
x['RawDescriptionHelpFormatterType'] = argparse.RawDescriptionHelpFormatter('PROG')
|
||||
x['ArgDefaultsHelpFormatterType'] = argparse.ArgumentDefaultsHelpFormatter('PROG')
|
||||
except NameError:
|
||||
pass
|
||||
try: # python 2.7 (and not 3.1)
|
||||
x['CmpKeyType'] = _cmpkey = functools.cmp_to_key(_methodwrap) # 2.7, >=3.2
|
||||
x['CmpKeyObjType'] = _cmpkey('0') #2.7, >=3.2
|
||||
except AttributeError:
|
||||
pass
|
||||
if PY3: # oddities: removed, etc
|
||||
x['BufferType'] = x['MemoryType']
|
||||
else:
|
||||
x['BufferType'] = buffer('')
|
||||
|
||||
# -- cleanup ----------------------------------------------------------------
|
||||
a.update(d) # registered also succeed
|
||||
if sys.platform[:3] == 'win':
|
||||
os.close(_filedescrip) # required on win32
|
||||
os.remove(_tempfile)
|
||||
|
||||
|
||||
# EOF
|
@ -0,0 +1,308 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
Methods for detecting objects leading to pickling failures.
|
||||
"""
|
||||
|
||||
import dis
|
||||
from inspect import ismethod, isfunction, istraceback, isframe, iscode
|
||||
from .pointers import parent, reference, at, parents, children
|
||||
|
||||
from ._dill import _trace as trace
|
||||
from ._dill import PY3
|
||||
|
||||
__all__ = ['baditems','badobjects','badtypes','code','errors','freevars',
|
||||
'getmodule','globalvars','nestedcode','nestedglobals','outermost',
|
||||
'referredglobals','referrednested','trace','varnames']
|
||||
|
||||
def getmodule(object, _filename=None, force=False):
|
||||
"""get the module of the object"""
|
||||
from inspect import getmodule as getmod
|
||||
module = getmod(object, _filename)
|
||||
if module or not force: return module
|
||||
if PY3: builtins = 'builtins'
|
||||
else: builtins = '__builtin__'
|
||||
builtins = __import__(builtins)
|
||||
from .source import getname
|
||||
name = getname(object, force=True)
|
||||
return builtins if name in vars(builtins).keys() else None
|
||||
|
||||
def outermost(func): # is analogous to getsource(func,enclosing=True)
|
||||
"""get outermost enclosing object (i.e. the outer function in a closure)
|
||||
|
||||
NOTE: this is the object-equivalent of getsource(func, enclosing=True)
|
||||
"""
|
||||
if PY3:
|
||||
if ismethod(func):
|
||||
_globals = func.__func__.__globals__ or {}
|
||||
elif isfunction(func):
|
||||
_globals = func.__globals__ or {}
|
||||
else:
|
||||
return #XXX: or raise? no matches
|
||||
_globals = _globals.items()
|
||||
else:
|
||||
if ismethod(func):
|
||||
_globals = func.im_func.func_globals or {}
|
||||
elif isfunction(func):
|
||||
_globals = func.func_globals or {}
|
||||
else:
|
||||
return #XXX: or raise? no matches
|
||||
_globals = _globals.iteritems()
|
||||
# get the enclosing source
|
||||
from .source import getsourcelines
|
||||
try: lines,lnum = getsourcelines(func, enclosing=True)
|
||||
except: #TypeError, IOError
|
||||
lines,lnum = [],None
|
||||
code = ''.join(lines)
|
||||
# get all possible names,objects that are named in the enclosing source
|
||||
_locals = ((name,obj) for (name,obj) in _globals if name in code)
|
||||
# now only save the objects that generate the enclosing block
|
||||
for name,obj in _locals: #XXX: don't really need 'name'
|
||||
try:
|
||||
if getsourcelines(obj) == (lines,lnum): return obj
|
||||
except: #TypeError, IOError
|
||||
pass
|
||||
return #XXX: or raise? no matches
|
||||
|
||||
def nestedcode(func, recurse=True): #XXX: or return dict of {co_name: co} ?
|
||||
"""get the code objects for any nested functions (e.g. in a closure)"""
|
||||
func = code(func)
|
||||
if not iscode(func): return [] #XXX: or raise? no matches
|
||||
nested = set()
|
||||
for co in func.co_consts:
|
||||
if co is None: continue
|
||||
co = code(co)
|
||||
if co:
|
||||
nested.add(co)
|
||||
if recurse: nested |= set(nestedcode(co, recurse=True))
|
||||
return list(nested)
|
||||
|
||||
def code(func):
|
||||
'''get the code object for the given function or method
|
||||
|
||||
NOTE: use dill.source.getsource(CODEOBJ) to get the source code
|
||||
'''
|
||||
if PY3:
|
||||
im_func = '__func__'
|
||||
func_code = '__code__'
|
||||
else:
|
||||
im_func = 'im_func'
|
||||
func_code = 'func_code'
|
||||
if ismethod(func): func = getattr(func, im_func)
|
||||
if isfunction(func): func = getattr(func, func_code)
|
||||
if istraceback(func): func = func.tb_frame
|
||||
if isframe(func): func = func.f_code
|
||||
if iscode(func): return func
|
||||
return
|
||||
|
||||
#XXX: ugly: parse dis.dis for name after "<code object" in line and in globals?
|
||||
def referrednested(func, recurse=True): #XXX: return dict of {__name__: obj} ?
|
||||
"""get functions defined inside of func (e.g. inner functions in a closure)
|
||||
|
||||
NOTE: results may differ if the function has been executed or not.
|
||||
If len(nestedcode(func)) > len(referrednested(func)), try calling func().
|
||||
If possible, python builds code objects, but delays building functions
|
||||
until func() is called.
|
||||
"""
|
||||
if PY3:
|
||||
att1 = '__code__'
|
||||
att0 = '__func__'
|
||||
else:
|
||||
att1 = 'func_code' # functions
|
||||
att0 = 'im_func' # methods
|
||||
|
||||
import gc
|
||||
funcs = set()
|
||||
# get the code objects, and try to track down by referrence
|
||||
for co in nestedcode(func, recurse):
|
||||
# look for function objects that refer to the code object
|
||||
for obj in gc.get_referrers(co):
|
||||
# get methods
|
||||
_ = getattr(obj, att0, None) # ismethod
|
||||
if getattr(_, att1, None) is co: funcs.add(obj)
|
||||
# get functions
|
||||
elif getattr(obj, att1, None) is co: funcs.add(obj)
|
||||
# get frame objects
|
||||
elif getattr(obj, 'f_code', None) is co: funcs.add(obj)
|
||||
# get code objects
|
||||
elif hasattr(obj, 'co_code') and obj is co: funcs.add(obj)
|
||||
# frameobjs => func.func_code.co_varnames not in func.func_code.co_cellvars
|
||||
# funcobjs => func.func_code.co_cellvars not in func.func_code.co_varnames
|
||||
# frameobjs are not found, however funcobjs are...
|
||||
# (see: test_mixins.quad ... and test_mixins.wtf)
|
||||
# after execution, code objects get compiled, and then may be found by gc
|
||||
return list(funcs)
|
||||
|
||||
|
||||
def freevars(func):
|
||||
"""get objects defined in enclosing code that are referred to by func
|
||||
|
||||
returns a dict of {name:object}"""
|
||||
if PY3:
|
||||
im_func = '__func__'
|
||||
func_code = '__code__'
|
||||
func_closure = '__closure__'
|
||||
else:
|
||||
im_func = 'im_func'
|
||||
func_code = 'func_code'
|
||||
func_closure = 'func_closure'
|
||||
if ismethod(func): func = getattr(func, im_func)
|
||||
if isfunction(func):
|
||||
closures = getattr(func, func_closure) or ()
|
||||
func = getattr(func, func_code).co_freevars # get freevars
|
||||
else:
|
||||
return {}
|
||||
return dict((name,c.cell_contents) for (name,c) in zip(func,closures))
|
||||
|
||||
# thanks to Davies Liu for recursion of globals
|
||||
def nestedglobals(func, recurse=True):
|
||||
"""get the names of any globals found within func"""
|
||||
func = code(func)
|
||||
if func is None: return list()
|
||||
from .temp import capture
|
||||
names = set()
|
||||
with capture('stdout') as out:
|
||||
dis.dis(func) #XXX: dis.dis(None) disassembles last traceback
|
||||
for line in out.getvalue().splitlines():
|
||||
if '_GLOBAL' in line:
|
||||
name = line.split('(')[-1].split(')')[0]
|
||||
names.add(name)
|
||||
for co in getattr(func, 'co_consts', tuple()):
|
||||
if co and recurse and iscode(co):
|
||||
names.update(nestedglobals(co, recurse=True))
|
||||
return list(names)
|
||||
|
||||
def referredglobals(func, recurse=True, builtin=False):
|
||||
"""get the names of objects in the global scope referred to by func"""
|
||||
return globalvars(func, recurse, builtin).keys()
|
||||
|
||||
def globalvars(func, recurse=True, builtin=False):
|
||||
"""get objects defined in global scope that are referred to by func
|
||||
|
||||
return a dict of {name:object}"""
|
||||
if PY3:
|
||||
im_func = '__func__'
|
||||
func_code = '__code__'
|
||||
func_globals = '__globals__'
|
||||
func_closure = '__closure__'
|
||||
else:
|
||||
im_func = 'im_func'
|
||||
func_code = 'func_code'
|
||||
func_globals = 'func_globals'
|
||||
func_closure = 'func_closure'
|
||||
if ismethod(func): func = getattr(func, im_func)
|
||||
if isfunction(func):
|
||||
globs = vars(getmodule(sum)).copy() if builtin else {}
|
||||
# get references from within closure
|
||||
orig_func, func = func, set()
|
||||
for obj in getattr(orig_func, func_closure) or {}:
|
||||
_vars = globalvars(obj.cell_contents, recurse, builtin) or {}
|
||||
func.update(_vars) #XXX: (above) be wary of infinte recursion?
|
||||
globs.update(_vars)
|
||||
# get globals
|
||||
globs.update(getattr(orig_func, func_globals) or {})
|
||||
# get names of references
|
||||
if not recurse:
|
||||
func.update(getattr(orig_func, func_code).co_names)
|
||||
else:
|
||||
func.update(nestedglobals(getattr(orig_func, func_code)))
|
||||
# find globals for all entries of func
|
||||
for key in func.copy(): #XXX: unnecessary...?
|
||||
nested_func = globs.get(key)
|
||||
if nested_func is orig_func:
|
||||
#func.remove(key) if key in func else None
|
||||
continue #XXX: globalvars(func, False)?
|
||||
func.update(globalvars(nested_func, True, builtin))
|
||||
elif iscode(func):
|
||||
globs = vars(getmodule(sum)).copy() if builtin else {}
|
||||
#globs.update(globals())
|
||||
if not recurse:
|
||||
func = func.co_names # get names
|
||||
else:
|
||||
orig_func = func.co_name # to stop infinite recursion
|
||||
func = set(nestedglobals(func))
|
||||
# find globals for all entries of func
|
||||
for key in func.copy(): #XXX: unnecessary...?
|
||||
if key is orig_func:
|
||||
#func.remove(key) if key in func else None
|
||||
continue #XXX: globalvars(func, False)?
|
||||
nested_func = globs.get(key)
|
||||
func.update(globalvars(nested_func, True, builtin))
|
||||
else:
|
||||
return {}
|
||||
#NOTE: if name not in func_globals, then we skip it...
|
||||
return dict((name,globs[name]) for name in func if name in globs)
|
||||
|
||||
|
||||
def varnames(func):
|
||||
"""get names of variables defined by func
|
||||
|
||||
returns a tuple (local vars, local vars referrenced by nested functions)"""
|
||||
func = code(func)
|
||||
if not iscode(func):
|
||||
return () #XXX: better ((),())? or None?
|
||||
return func.co_varnames, func.co_cellvars
|
||||
|
||||
|
||||
def baditems(obj, exact=False, safe=False): #XXX: obj=globals() ?
|
||||
"""get items in object that fail to pickle"""
|
||||
if not hasattr(obj,'__iter__'): # is not iterable
|
||||
return [j for j in (badobjects(obj,0,exact,safe),) if j is not None]
|
||||
obj = obj.values() if getattr(obj,'values',None) else obj
|
||||
_obj = [] # can't use a set, as items may be unhashable
|
||||
[_obj.append(badobjects(i,0,exact,safe)) for i in obj if i not in _obj]
|
||||
return [j for j in _obj if j is not None]
|
||||
|
||||
|
||||
def badobjects(obj, depth=0, exact=False, safe=False):
|
||||
"""get objects that fail to pickle"""
|
||||
from dill import pickles
|
||||
if not depth:
|
||||
if pickles(obj,exact,safe): return None
|
||||
return obj
|
||||
return dict(((attr, badobjects(getattr(obj,attr),depth-1,exact,safe)) \
|
||||
for attr in dir(obj) if not pickles(getattr(obj,attr),exact,safe)))
|
||||
|
||||
def badtypes(obj, depth=0, exact=False, safe=False):
|
||||
"""get types for objects that fail to pickle"""
|
||||
from dill import pickles
|
||||
if not depth:
|
||||
if pickles(obj,exact,safe): return None
|
||||
return type(obj)
|
||||
return dict(((attr, badtypes(getattr(obj,attr),depth-1,exact,safe)) \
|
||||
for attr in dir(obj) if not pickles(getattr(obj,attr),exact,safe)))
|
||||
|
||||
def errors(obj, depth=0, exact=False, safe=False):
|
||||
"""get errors for objects that fail to pickle"""
|
||||
from dill import pickles, copy
|
||||
if not depth:
|
||||
try:
|
||||
pik = copy(obj)
|
||||
if exact:
|
||||
assert pik == obj, \
|
||||
"Unpickling produces %s instead of %s" % (pik,obj)
|
||||
assert type(pik) == type(obj), \
|
||||
"Unpickling produces %s instead of %s" % (type(pik),type(obj))
|
||||
return None
|
||||
except Exception:
|
||||
import sys
|
||||
return sys.exc_info()[1]
|
||||
_dict = {}
|
||||
for attr in dir(obj):
|
||||
try:
|
||||
_attr = getattr(obj,attr)
|
||||
except Exception:
|
||||
import sys
|
||||
_dict[attr] = sys.exc_info()[1]
|
||||
continue
|
||||
if not pickles(_attr,exact,safe):
|
||||
_dict[attr] = errors(_attr,depth-1,exact,safe)
|
||||
return _dict
|
||||
|
||||
|
||||
# EOF
|
@ -0,0 +1,202 @@
|
||||
# THIS FILE GENERATED FROM SETUP.PY
|
||||
this_version = '0.3.1.1'
|
||||
stable_version = '0.3.1.1'
|
||||
readme = '''-----------------------------
|
||||
dill: serialize all of python
|
||||
-----------------------------
|
||||
|
||||
About Dill
|
||||
==========
|
||||
|
||||
``dill`` extends python's ``pickle`` module for serializing and de-serializing
|
||||
python objects to the majority of the built-in python types. Serialization
|
||||
is the process of converting an object to a byte stream, and the inverse
|
||||
of which is converting a byte stream back to on python object hierarchy.
|
||||
|
||||
``dill`` provides the user the same interface as the ``pickle`` module, and
|
||||
also includes some additional features. In addition to pickling python
|
||||
objects, ``dill`` provides the ability to save the state of an interpreter
|
||||
session in a single command. Hence, it would be feasable to save a
|
||||
interpreter session, close the interpreter, ship the pickled file to
|
||||
another computer, open a new interpreter, unpickle the session and
|
||||
thus continue from the 'saved' state of the original interpreter
|
||||
session.
|
||||
|
||||
``dill`` can be used to store python objects to a file, but the primary
|
||||
usage is to send python objects across the network as a byte stream.
|
||||
``dill`` is quite flexible, and allows arbitrary user defined classes
|
||||
and functions to be serialized. Thus ``dill`` is not intended to be
|
||||
secure against erroneously or maliciously constructed data. It is
|
||||
left to the user to decide whether the data they unpickle is from
|
||||
a trustworthy source.
|
||||
|
||||
``dill`` is part of ``pathos``, a python framework for heterogeneous computing.
|
||||
``dill`` is in active development, so any user feedback, bug reports, comments,
|
||||
or suggestions are highly appreciated. A list of known issues is maintained
|
||||
at http://trac.mystic.cacr.caltech.edu/project/pathos/query.html, with a public
|
||||
ticket list at https://github.com/uqfoundation/dill/issues.
|
||||
|
||||
|
||||
Major Features
|
||||
==============
|
||||
|
||||
``dill`` can pickle the following standard types:
|
||||
|
||||
- none, type, bool, int, long, float, complex, str, unicode,
|
||||
- tuple, list, dict, file, buffer, builtin,
|
||||
- both old and new style classes,
|
||||
- instances of old and new style classes,
|
||||
- set, frozenset, array, functions, exceptions
|
||||
|
||||
``dill`` can also pickle more 'exotic' standard types:
|
||||
|
||||
- functions with yields, nested functions, lambdas,
|
||||
- cell, method, unboundmethod, module, code, methodwrapper,
|
||||
- dictproxy, methoddescriptor, getsetdescriptor, memberdescriptor,
|
||||
- wrapperdescriptor, xrange, slice,
|
||||
- notimplemented, ellipsis, quit
|
||||
|
||||
``dill`` cannot yet pickle these standard types:
|
||||
|
||||
- frame, generator, traceback
|
||||
|
||||
``dill`` also provides the capability to:
|
||||
|
||||
- save and load python interpreter sessions
|
||||
- save and extract the source code from functions and classes
|
||||
- interactively diagnose pickling errors
|
||||
|
||||
|
||||
Current Release
|
||||
===============
|
||||
|
||||
This documentation is for version ``dill-0.3.1.1``.
|
||||
|
||||
The latest released version of ``dill`` is available from:
|
||||
|
||||
https://pypi.org/project/dill
|
||||
|
||||
``dill`` is distributed under a 3-clause BSD license.
|
||||
|
||||
>>> import dill
|
||||
>>> print (dill.license())
|
||||
|
||||
|
||||
Development Version
|
||||
===================
|
||||
|
||||
You can get the latest development version with all the shiny new features at:
|
||||
|
||||
https://github.com/uqfoundation
|
||||
|
||||
If you have a new contribution, please submit a pull request.
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
``dill`` is packaged to install from source, so you must
|
||||
download the tarball, unzip, and run the installer::
|
||||
|
||||
[download]
|
||||
$ tar -xvzf dill-0.3.1.1.tar.gz
|
||||
$ cd dill-0.3.1.1
|
||||
$ python setup py build
|
||||
$ python setup py install
|
||||
|
||||
You will be warned of any missing dependencies and/or settings
|
||||
after you run the "build" step above.
|
||||
|
||||
Alternately, ``dill`` can be installed with ``pip`` or ``easy_install``::
|
||||
|
||||
$ pip install dill
|
||||
|
||||
|
||||
Requirements
|
||||
============
|
||||
|
||||
``dill`` requires:
|
||||
|
||||
- ``python``, **version >= 2.6** or **version >= 3.1**, or ``pypy``
|
||||
|
||||
Optional requirements:
|
||||
|
||||
- ``setuptools``, **version >= 0.6**
|
||||
- ``pyreadline``, **version >= 1.7.1** (on windows)
|
||||
- ``objgraph``, **version >= 1.7.2**
|
||||
|
||||
|
||||
More Information
|
||||
================
|
||||
|
||||
Probably the best way to get started is to look at the documentation at
|
||||
http://dill.rtfd.io. Also see ``dill.tests`` for a set of scripts that
|
||||
demonstrate how ``dill`` can serialize different python objects. You can
|
||||
run the test suite with ``python -m dill.tests``. The contents of any
|
||||
pickle file can be examined with ``undill``. As ``dill`` conforms to
|
||||
the ``pickle`` interface, the examples and documentation found at
|
||||
http://docs.python.org/library/pickle.html also apply to ``dill``
|
||||
if one will ``import dill as pickle``. The source code is also generally
|
||||
well documented, so further questions may be resolved by inspecting the
|
||||
code itself. Please feel free to submit a ticket on github, or ask a
|
||||
question on stackoverflow (**@Mike McKerns**).
|
||||
If you would like to share how you use ``dill`` in your work, please send
|
||||
an email (to **mmckerns at uqfoundation dot org**).
|
||||
|
||||
|
||||
Citation
|
||||
========
|
||||
|
||||
If you use ``dill`` to do research that leads to publication, we ask that you
|
||||
acknowledge use of ``dill`` by citing the following in your publication::
|
||||
|
||||
M.M. McKerns, L. Strand, T. Sullivan, A. Fang, M.A.G. Aivazis,
|
||||
"Building a framework for predictive science", Proceedings of
|
||||
the 10th Python in Science Conference, 2011;
|
||||
http://arxiv.org/pdf/1202.1056
|
||||
|
||||
Michael McKerns and Michael Aivazis,
|
||||
"pathos: a framework for heterogeneous computing", 2010- ;
|
||||
http://trac.mystic.cacr.caltech.edu/project/pathos
|
||||
|
||||
Please see http://trac.mystic.cacr.caltech.edu/project/pathos or
|
||||
http://arxiv.org/pdf/1202.1056 for further information.
|
||||
|
||||
'''
|
||||
license = '''Copyright (c) 2004-2016 California Institute of Technology.
|
||||
Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
All rights reserved.
|
||||
|
||||
This software is available subject to the conditions and terms laid
|
||||
out below. By downloading and using this software you are agreeing
|
||||
to the following conditions.
|
||||
|
||||
Redistribution and use in source and binary forms, with or without
|
||||
modification, are permitted provided that the following conditions
|
||||
are met::
|
||||
|
||||
- Redistribution of source code must retain the above copyright
|
||||
notice, this list of conditions and the following disclaimer.
|
||||
|
||||
- Redistribution in binary form must reproduce the above copyright
|
||||
notice, this list of conditions and the following disclaimer in the
|
||||
documentations and/or other materials provided with the distribution.
|
||||
|
||||
- Neither the name of the California Institute of Technology nor
|
||||
the names of its contributors may be used to endorse or promote
|
||||
products derived from this software without specific prior written
|
||||
permission.
|
||||
|
||||
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
||||
TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
'''
|
@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
all Python Standard Library object types (currently: CH 1-15 @ 2.7)
|
||||
and some other common object types (i.e. numpy.ndarray)
|
||||
|
||||
to load more objects and types, use dill.load_types()
|
||||
"""
|
||||
|
||||
# non-local import of dill.objects
|
||||
from dill import objects
|
||||
for _type in objects.keys():
|
||||
exec("%s = type(objects['%s'])" % (_type,_type))
|
||||
|
||||
del objects
|
||||
try:
|
||||
del _type
|
||||
except NameError:
|
||||
pass
|
@ -0,0 +1,122 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
__all__ = ['parent', 'reference', 'at', 'parents', 'children']
|
||||
|
||||
import gc
|
||||
import sys
|
||||
|
||||
from ._dill import _proxy_helper as reference
|
||||
from ._dill import _locate_object as at
|
||||
|
||||
def parent(obj, objtype, ignore=()):
|
||||
"""
|
||||
>>> listiter = iter([4,5,6,7])
|
||||
>>> obj = parent(listiter, list)
|
||||
>>> obj == [4,5,6,7] # actually 'is', but don't have handle any longer
|
||||
True
|
||||
|
||||
NOTE: objtype can be a single type (e.g. int or list) or a tuple of types.
|
||||
|
||||
WARNING: if obj is a sequence (e.g. list), may produce unexpected results.
|
||||
Parent finds *one* parent (e.g. the last member of the sequence).
|
||||
"""
|
||||
depth = 1 #XXX: always looking for the parent (only, right?)
|
||||
chain = parents(obj, objtype, depth, ignore)
|
||||
parent = chain.pop()
|
||||
if parent is obj:
|
||||
return None
|
||||
return parent
|
||||
|
||||
|
||||
def parents(obj, objtype, depth=1, ignore=()): #XXX: objtype=object ?
|
||||
"""Find the chain of referents for obj. Chain will end with obj.
|
||||
|
||||
objtype: an object type or tuple of types to search for
|
||||
depth: search depth (e.g. depth=2 is 'grandparents')
|
||||
ignore: an object or tuple of objects to ignore in the search
|
||||
"""
|
||||
edge_func = gc.get_referents # looking for refs, not back_refs
|
||||
predicate = lambda x: isinstance(x, objtype) # looking for parent type
|
||||
#if objtype is None: predicate = lambda x: True #XXX: in obj.mro() ?
|
||||
ignore = (ignore,) if not hasattr(ignore, '__len__') else ignore
|
||||
ignore = (id(obj) for obj in ignore)
|
||||
chain = find_chain(obj, predicate, edge_func, depth)[::-1]
|
||||
#XXX: should pop off obj... ?
|
||||
return chain
|
||||
|
||||
|
||||
def children(obj, objtype, depth=1, ignore=()): #XXX: objtype=object ?
|
||||
"""Find the chain of referrers for obj. Chain will start with obj.
|
||||
|
||||
objtype: an object type or tuple of types to search for
|
||||
depth: search depth (e.g. depth=2 is 'grandchildren')
|
||||
ignore: an object or tuple of objects to ignore in the search
|
||||
|
||||
NOTE: a common thing to ignore is all globals, 'ignore=(globals(),)'
|
||||
|
||||
NOTE: repeated calls may yield different results, as python stores
|
||||
the last value in the special variable '_'; thus, it is often good
|
||||
to execute something to replace '_' (e.g. >>> 1+1).
|
||||
"""
|
||||
edge_func = gc.get_referrers # looking for back_refs, not refs
|
||||
predicate = lambda x: isinstance(x, objtype) # looking for child type
|
||||
#if objtype is None: predicate = lambda x: True #XXX: in obj.mro() ?
|
||||
ignore = (ignore,) if not hasattr(ignore, '__len__') else ignore
|
||||
ignore = (id(obj) for obj in ignore)
|
||||
chain = find_chain(obj, predicate, edge_func, depth, ignore)
|
||||
#XXX: should pop off obj... ?
|
||||
return chain
|
||||
|
||||
|
||||
# more generic helper function (cut-n-paste from objgraph)
|
||||
# Source at http://mg.pov.lt/objgraph/
|
||||
# Copyright (c) 2008-2010 Marius Gedminas <marius@pov.lt>
|
||||
# Copyright (c) 2010 Stefano Rivera <stefano@rivera.za.net>
|
||||
# Released under the MIT licence (see objgraph/objgrah.py)
|
||||
|
||||
def find_chain(obj, predicate, edge_func, max_depth=20, extra_ignore=()):
|
||||
queue = [obj]
|
||||
depth = {id(obj): 0}
|
||||
parent = {id(obj): None}
|
||||
ignore = set(extra_ignore)
|
||||
ignore.add(id(extra_ignore))
|
||||
ignore.add(id(queue))
|
||||
ignore.add(id(depth))
|
||||
ignore.add(id(parent))
|
||||
ignore.add(id(ignore))
|
||||
ignore.add(id(sys._getframe())) # this function
|
||||
ignore.add(id(sys._getframe(1))) # find_chain/find_backref_chain, likely
|
||||
gc.collect()
|
||||
while queue:
|
||||
target = queue.pop(0)
|
||||
if predicate(target):
|
||||
chain = [target]
|
||||
while parent[id(target)] is not None:
|
||||
target = parent[id(target)]
|
||||
chain.append(target)
|
||||
return chain
|
||||
tdepth = depth[id(target)]
|
||||
if tdepth < max_depth:
|
||||
referrers = edge_func(target)
|
||||
ignore.add(id(referrers))
|
||||
for source in referrers:
|
||||
if id(source) in ignore:
|
||||
continue
|
||||
if id(source) not in depth:
|
||||
depth[id(source)] = tdepth + 1
|
||||
parent[id(source)] = target
|
||||
queue.append(source)
|
||||
return [obj] # not found
|
||||
|
||||
|
||||
# backward compatability
|
||||
refobject = at
|
||||
|
||||
|
||||
# EOF
|
@ -0,0 +1,28 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
global settings for Pickler
|
||||
"""
|
||||
|
||||
try:
|
||||
from pickle import DEFAULT_PROTOCOL
|
||||
except ImportError:
|
||||
from pickle import HIGHEST_PROTOCOL as DEFAULT_PROTOCOL
|
||||
|
||||
settings = {
|
||||
#'main' : None,
|
||||
'protocol' : DEFAULT_PROTOCOL,
|
||||
'byref' : False,
|
||||
#'strictio' : False,
|
||||
'fmode' : 0, #HANDLE_FMODE
|
||||
'recurse' : False,
|
||||
'ignore' : False,
|
||||
}
|
||||
|
||||
del DEFAULT_PROTOCOL
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,263 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
Methods for serialized objects (or source code) stored in temporary files
|
||||
and file-like objects.
|
||||
"""
|
||||
#XXX: better instead to have functions write to any given file-like object ?
|
||||
#XXX: currently, all file-like objects are created by the function...
|
||||
|
||||
__all__ = ['dump_source', 'dump', 'dumpIO_source', 'dumpIO',\
|
||||
'load_source', 'load', 'loadIO_source', 'loadIO',\
|
||||
'capture']
|
||||
|
||||
import contextlib
|
||||
from ._dill import PY3
|
||||
|
||||
|
||||
@contextlib.contextmanager
|
||||
def capture(stream='stdout'):
|
||||
"""builds a context that temporarily replaces the given stream name
|
||||
|
||||
>>> with capture('stdout') as out:
|
||||
... print "foo!"
|
||||
...
|
||||
>>> print out.getvalue()
|
||||
foo!
|
||||
|
||||
"""
|
||||
import sys
|
||||
if PY3:
|
||||
from io import StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
orig = getattr(sys, stream)
|
||||
setattr(sys, stream, StringIO())
|
||||
try:
|
||||
yield getattr(sys, stream)
|
||||
finally:
|
||||
setattr(sys, stream, orig)
|
||||
|
||||
|
||||
def b(x): # deal with b'foo' versus 'foo'
|
||||
import codecs
|
||||
return codecs.latin_1_encode(x)[0]
|
||||
|
||||
def load_source(file, **kwds):
|
||||
"""load an object that was stored with dill.temp.dump_source
|
||||
|
||||
file: filehandle
|
||||
alias: string name of stored object
|
||||
mode: mode to open the file, one of: {'r', 'rb'}
|
||||
|
||||
>>> f = lambda x: x**2
|
||||
>>> pyfile = dill.temp.dump_source(f, alias='_f')
|
||||
>>> _f = dill.temp.load_source(pyfile)
|
||||
>>> _f(4)
|
||||
16
|
||||
"""
|
||||
alias = kwds.pop('alias', None)
|
||||
mode = kwds.pop('mode', 'r')
|
||||
fname = getattr(file, 'name', file) # fname=file.name or fname=file (if str)
|
||||
source = open(fname, mode=mode, **kwds).read()
|
||||
if not alias:
|
||||
tag = source.strip().splitlines()[-1].split()
|
||||
if tag[0] != '#NAME:':
|
||||
stub = source.splitlines()[0]
|
||||
raise IOError("unknown name for code: %s" % stub)
|
||||
alias = tag[-1]
|
||||
local = {}
|
||||
exec(source, local)
|
||||
_ = eval("%s" % alias, local)
|
||||
return _
|
||||
|
||||
def dump_source(object, **kwds):
|
||||
"""write object source to a NamedTemporaryFile (instead of dill.dump)
|
||||
Loads with "import" or "dill.temp.load_source". Returns the filehandle.
|
||||
|
||||
>>> f = lambda x: x**2
|
||||
>>> pyfile = dill.temp.dump_source(f, alias='_f')
|
||||
>>> _f = dill.temp.load_source(pyfile)
|
||||
>>> _f(4)
|
||||
16
|
||||
|
||||
>>> f = lambda x: x**2
|
||||
>>> pyfile = dill.temp.dump_source(f, dir='.')
|
||||
>>> modulename = os.path.basename(pyfile.name).split('.py')[0]
|
||||
>>> exec('from %s import f as _f' % modulename)
|
||||
>>> _f(4)
|
||||
16
|
||||
|
||||
Optional kwds:
|
||||
If 'alias' is specified, the object will be renamed to the given string.
|
||||
|
||||
If 'prefix' is specified, the file name will begin with that prefix,
|
||||
otherwise a default prefix is used.
|
||||
|
||||
If 'dir' is specified, the file will be created in that directory,
|
||||
otherwise a default directory is used.
|
||||
|
||||
If 'text' is specified and true, the file is opened in text
|
||||
mode. Else (the default) the file is opened in binary mode. On
|
||||
some operating systems, this makes no difference.
|
||||
|
||||
NOTE: Keep the return value for as long as you want your file to exist !
|
||||
""" #XXX: write a "load_source"?
|
||||
from .source import importable, getname
|
||||
import tempfile
|
||||
kwds.pop('suffix', '') # this is *always* '.py'
|
||||
alias = kwds.pop('alias', '') #XXX: include an alias so a name is known
|
||||
name = str(alias) or getname(object)
|
||||
name = "\n#NAME: %s\n" % name
|
||||
#XXX: assumes kwds['dir'] is writable and on $PYTHONPATH
|
||||
file = tempfile.NamedTemporaryFile(suffix='.py', **kwds)
|
||||
file.write(b(''.join([importable(object, alias=alias),name])))
|
||||
file.flush()
|
||||
return file
|
||||
|
||||
def load(file, **kwds):
|
||||
"""load an object that was stored with dill.temp.dump
|
||||
|
||||
file: filehandle
|
||||
mode: mode to open the file, one of: {'r', 'rb'}
|
||||
|
||||
>>> dumpfile = dill.temp.dump([1, 2, 3, 4, 5])
|
||||
>>> dill.temp.load(dumpfile)
|
||||
[1, 2, 3, 4, 5]
|
||||
"""
|
||||
import dill as pickle
|
||||
mode = kwds.pop('mode', 'rb')
|
||||
name = getattr(file, 'name', file) # name=file.name or name=file (if str)
|
||||
return pickle.load(open(name, mode=mode, **kwds))
|
||||
|
||||
def dump(object, **kwds):
|
||||
"""dill.dump of object to a NamedTemporaryFile.
|
||||
Loads with "dill.temp.load". Returns the filehandle.
|
||||
|
||||
>>> dumpfile = dill.temp.dump([1, 2, 3, 4, 5])
|
||||
>>> dill.temp.load(dumpfile)
|
||||
[1, 2, 3, 4, 5]
|
||||
|
||||
Optional kwds:
|
||||
If 'suffix' is specified, the file name will end with that suffix,
|
||||
otherwise there will be no suffix.
|
||||
|
||||
If 'prefix' is specified, the file name will begin with that prefix,
|
||||
otherwise a default prefix is used.
|
||||
|
||||
If 'dir' is specified, the file will be created in that directory,
|
||||
otherwise a default directory is used.
|
||||
|
||||
If 'text' is specified and true, the file is opened in text
|
||||
mode. Else (the default) the file is opened in binary mode. On
|
||||
some operating systems, this makes no difference.
|
||||
|
||||
NOTE: Keep the return value for as long as you want your file to exist !
|
||||
"""
|
||||
import dill as pickle
|
||||
import tempfile
|
||||
file = tempfile.NamedTemporaryFile(**kwds)
|
||||
pickle.dump(object, file)
|
||||
file.flush()
|
||||
return file
|
||||
|
||||
def loadIO(buffer, **kwds):
|
||||
"""load an object that was stored with dill.temp.dumpIO
|
||||
|
||||
buffer: buffer object
|
||||
|
||||
>>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5])
|
||||
>>> dill.temp.loadIO(dumpfile)
|
||||
[1, 2, 3, 4, 5]
|
||||
"""
|
||||
import dill as pickle
|
||||
if PY3:
|
||||
from io import BytesIO as StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
value = getattr(buffer, 'getvalue', buffer) # value or buffer.getvalue
|
||||
if value != buffer: value = value() # buffer.getvalue()
|
||||
return pickle.load(StringIO(value))
|
||||
|
||||
def dumpIO(object, **kwds):
|
||||
"""dill.dump of object to a buffer.
|
||||
Loads with "dill.temp.loadIO". Returns the buffer object.
|
||||
|
||||
>>> dumpfile = dill.temp.dumpIO([1, 2, 3, 4, 5])
|
||||
>>> dill.temp.loadIO(dumpfile)
|
||||
[1, 2, 3, 4, 5]
|
||||
"""
|
||||
import dill as pickle
|
||||
if PY3:
|
||||
from io import BytesIO as StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
file = StringIO()
|
||||
pickle.dump(object, file)
|
||||
file.flush()
|
||||
return file
|
||||
|
||||
def loadIO_source(buffer, **kwds):
|
||||
"""load an object that was stored with dill.temp.dumpIO_source
|
||||
|
||||
buffer: buffer object
|
||||
alias: string name of stored object
|
||||
|
||||
>>> f = lambda x:x**2
|
||||
>>> pyfile = dill.temp.dumpIO_source(f, alias='_f')
|
||||
>>> _f = dill.temp.loadIO_source(pyfile)
|
||||
>>> _f(4)
|
||||
16
|
||||
"""
|
||||
alias = kwds.pop('alias', None)
|
||||
source = getattr(buffer, 'getvalue', buffer) # source or buffer.getvalue
|
||||
if source != buffer: source = source() # buffer.getvalue()
|
||||
if PY3: source = source.decode() # buffer to string
|
||||
if not alias:
|
||||
tag = source.strip().splitlines()[-1].split()
|
||||
if tag[0] != '#NAME:':
|
||||
stub = source.splitlines()[0]
|
||||
raise IOError("unknown name for code: %s" % stub)
|
||||
alias = tag[-1]
|
||||
local = {}
|
||||
exec(source, local)
|
||||
_ = eval("%s" % alias, local)
|
||||
return _
|
||||
|
||||
def dumpIO_source(object, **kwds):
|
||||
"""write object source to a buffer (instead of dill.dump)
|
||||
Loads by with dill.temp.loadIO_source. Returns the buffer object.
|
||||
|
||||
>>> f = lambda x:x**2
|
||||
>>> pyfile = dill.temp.dumpIO_source(f, alias='_f')
|
||||
>>> _f = dill.temp.loadIO_source(pyfile)
|
||||
>>> _f(4)
|
||||
16
|
||||
|
||||
Optional kwds:
|
||||
If 'alias' is specified, the object will be renamed to the given string.
|
||||
"""
|
||||
from .source import importable, getname
|
||||
if PY3:
|
||||
from io import BytesIO as StringIO
|
||||
else:
|
||||
from StringIO import StringIO
|
||||
alias = kwds.pop('alias', '') #XXX: include an alias so a name is known
|
||||
name = str(alias) or getname(object)
|
||||
name = "\n#NAME: %s\n" % name
|
||||
#XXX: assumes kwds['dir'] is writable and on $PYTHONPATH
|
||||
file = StringIO()
|
||||
file.write(b(''.join([importable(object, alias=alias),name])))
|
||||
file.flush()
|
||||
return file
|
||||
|
||||
|
||||
del contextlib
|
||||
|
||||
|
||||
# EOF
|
@ -0,0 +1,23 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2018-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
to run this test suite, first build and install `dill`.
|
||||
|
||||
$ python setup.py build
|
||||
$ python setup.py install
|
||||
|
||||
|
||||
then run the tests with:
|
||||
|
||||
$ python -m dill.tests
|
||||
|
||||
|
||||
or, if `nose` is installed:
|
||||
|
||||
$ nosetests
|
||||
|
||||
"""
|
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2018-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
from __future__ import print_function
|
||||
import glob
|
||||
import os
|
||||
try:
|
||||
import pox
|
||||
python = pox.which_python(version=True, fullpath=False) or 'python'
|
||||
except ImportError:
|
||||
python = 'python'
|
||||
|
||||
suite = os.path.dirname(__file__) or os.path.curdir
|
||||
tests = glob.glob(suite + os.path.sep + 'test_*.py')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
for test in tests:
|
||||
print('.', end='')
|
||||
os.system('{0} {1}'.format(python, test))
|
||||
print('')
|
||||
|
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
from dill import check
|
||||
import sys
|
||||
|
||||
from dill.temp import capture
|
||||
from dill._dill import PY3
|
||||
|
||||
|
||||
#FIXME: this doesn't catch output... it's from the internal call
|
||||
def raise_check(func, **kwds):
|
||||
try:
|
||||
with capture('stdout') as out:
|
||||
check(func, **kwds)
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
raise AssertionError(str(e))
|
||||
else:
|
||||
assert 'Traceback' not in out.getvalue()
|
||||
finally:
|
||||
out.close()
|
||||
|
||||
|
||||
f = lambda x:x**2
|
||||
|
||||
|
||||
def test_simple():
|
||||
raise_check(f)
|
||||
|
||||
|
||||
def test_recurse():
|
||||
raise_check(f, recurse=True)
|
||||
|
||||
|
||||
def test_byref():
|
||||
raise_check(f, byref=True)
|
||||
|
||||
|
||||
def test_protocol():
|
||||
raise_check(f, protocol=True)
|
||||
|
||||
|
||||
def test_python():
|
||||
raise_check(f, python=None)
|
||||
|
||||
|
||||
#TODO: test incompatible versions
|
||||
#TODO: test dump failure
|
||||
#TODO: test load failure
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_simple()
|
||||
test_recurse()
|
||||
test_byref()
|
||||
test_protocol()
|
||||
test_python()
|
@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import dill
|
||||
import sys
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
# test classdefs
|
||||
class _class:
|
||||
def _method(self):
|
||||
pass
|
||||
def ok(self):
|
||||
return True
|
||||
|
||||
class _class2:
|
||||
def __call__(self):
|
||||
pass
|
||||
def ok(self):
|
||||
return True
|
||||
|
||||
class _newclass(object):
|
||||
def _method(self):
|
||||
pass
|
||||
def ok(self):
|
||||
return True
|
||||
|
||||
class _newclass2(object):
|
||||
def __call__(self):
|
||||
pass
|
||||
def ok(self):
|
||||
return True
|
||||
|
||||
class _meta(type):
|
||||
pass
|
||||
|
||||
def __call__(self):
|
||||
pass
|
||||
def ok(self):
|
||||
return True
|
||||
|
||||
_mclass = _meta("_mclass", (object,), {"__call__": __call__, "ok": ok})
|
||||
|
||||
del __call__
|
||||
del ok
|
||||
|
||||
o = _class()
|
||||
oc = _class2()
|
||||
n = _newclass()
|
||||
nc = _newclass2()
|
||||
m = _mclass()
|
||||
|
||||
# test pickles for class instances
|
||||
def test_class_instances():
|
||||
assert dill.pickles(o)
|
||||
assert dill.pickles(oc)
|
||||
assert dill.pickles(n)
|
||||
assert dill.pickles(nc)
|
||||
assert dill.pickles(m)
|
||||
|
||||
def test_class_objects():
|
||||
clslist = [_class,_class2,_newclass,_newclass2,_mclass]
|
||||
objlist = [o,oc,n,nc,m]
|
||||
_clslist = [dill.dumps(obj) for obj in clslist]
|
||||
_objlist = [dill.dumps(obj) for obj in objlist]
|
||||
|
||||
for obj in clslist:
|
||||
globals().pop(obj.__name__)
|
||||
del clslist
|
||||
for obj in ['o','oc','n','nc']:
|
||||
globals().pop(obj)
|
||||
del objlist
|
||||
del obj
|
||||
|
||||
for obj,cls in zip(_objlist,_clslist):
|
||||
_cls = dill.loads(cls)
|
||||
_obj = dill.loads(obj)
|
||||
assert _obj.ok()
|
||||
assert _cls.ok(_cls())
|
||||
if _cls.__name__ == "_mclass":
|
||||
assert type(_cls).__name__ == "_meta"
|
||||
|
||||
# test NoneType
|
||||
def test_none():
|
||||
assert dill.pickles(type(None))
|
||||
|
||||
if hex(sys.hexversion) >= '0x20600f0':
|
||||
from collections import namedtuple
|
||||
Z = namedtuple("Z", ['a','b'])
|
||||
Zi = Z(0,1)
|
||||
X = namedtuple("Y", ['a','b'])
|
||||
X.__name__ = "X"
|
||||
if hex(sys.hexversion) >= '0x30300f0':
|
||||
X.__qualname__ = "X" #XXX: name must 'match' or fails to pickle
|
||||
Xi = X(0,1)
|
||||
Bad = namedtuple("FakeName", ['a','b'])
|
||||
Badi = Bad(0,1)
|
||||
else:
|
||||
Z = Zi = X = Xi = Bad = Badi = None
|
||||
|
||||
# test namedtuple
|
||||
def test_namedtuple():
|
||||
assert Z is dill.loads(dill.dumps(Z))
|
||||
assert Zi == dill.loads(dill.dumps(Zi))
|
||||
assert X is dill.loads(dill.dumps(X))
|
||||
assert Xi == dill.loads(dill.dumps(Xi))
|
||||
assert Bad is not dill.loads(dill.dumps(Bad))
|
||||
assert Bad._fields == dill.loads(dill.dumps(Bad))._fields
|
||||
assert tuple(Badi) == tuple(dill.loads(dill.dumps(Badi)))
|
||||
|
||||
def test_array_nested():
|
||||
try:
|
||||
import numpy as np
|
||||
|
||||
x = np.array([1])
|
||||
y = (x,)
|
||||
dill.dumps(x)
|
||||
assert y == dill.loads(dill.dumps(y))
|
||||
|
||||
except ImportError: pass
|
||||
|
||||
|
||||
def test_array_subclass():
|
||||
try:
|
||||
import numpy as np
|
||||
|
||||
class TestArray(np.ndarray):
|
||||
def __new__(cls, input_array, color):
|
||||
obj = np.asarray(input_array).view(cls)
|
||||
obj.color = color
|
||||
return obj
|
||||
def __array_finalize__(self, obj):
|
||||
if obj is None:
|
||||
return
|
||||
if isinstance(obj, type(self)):
|
||||
self.color = obj.color
|
||||
def __getnewargs__(self):
|
||||
return np.asarray(self), self.color
|
||||
|
||||
a1 = TestArray(np.zeros(100), color='green')
|
||||
assert dill.pickles(a1)
|
||||
assert a1.__dict__ == dill.copy(a1).__dict__
|
||||
|
||||
a2 = a1[0:9]
|
||||
assert dill.pickles(a2)
|
||||
assert a2.__dict__ == dill.copy(a2).__dict__
|
||||
|
||||
class TestArray2(np.ndarray):
|
||||
color = 'blue'
|
||||
|
||||
a3 = TestArray2([1,2,3,4,5])
|
||||
a3.color = 'green'
|
||||
assert dill.pickles(a3)
|
||||
assert a3.__dict__ == dill.copy(a3).__dict__
|
||||
|
||||
except ImportError: pass
|
||||
|
||||
|
||||
def test_method_decorator():
|
||||
class A(object):
|
||||
@classmethod
|
||||
def test(cls):
|
||||
pass
|
||||
|
||||
a = A()
|
||||
|
||||
res = dill.dumps(a)
|
||||
new_obj = dill.loads(res)
|
||||
new_obj.__class__.test()
|
||||
|
||||
# test slots
|
||||
class Y(object):
|
||||
__slots__ = ['y']
|
||||
def __init__(self, y):
|
||||
self.y = y
|
||||
|
||||
value = 123
|
||||
y = Y(value)
|
||||
|
||||
def test_slots():
|
||||
assert dill.pickles(Y)
|
||||
assert dill.pickles(y)
|
||||
assert dill.pickles(Y.y)
|
||||
assert dill.copy(y).y == value
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_class_instances()
|
||||
test_class_objects()
|
||||
test_none()
|
||||
test_namedtuple()
|
||||
test_array_nested()
|
||||
test_array_subclass()
|
||||
test_method_decorator()
|
||||
test_slots()
|
@ -0,0 +1,156 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
from dill.detect import baditems, badobjects, badtypes, errors, parent, at, globalvars
|
||||
from dill import settings
|
||||
from dill._dill import IS_PYPY
|
||||
from pickle import PicklingError
|
||||
|
||||
import inspect
|
||||
|
||||
def test_bad_things():
|
||||
f = inspect.currentframe()
|
||||
assert baditems(f) == [f]
|
||||
#assert baditems(globals()) == [f] #XXX
|
||||
assert badobjects(f) is f
|
||||
assert badtypes(f) == type(f)
|
||||
assert type(errors(f)) is PicklingError if IS_PYPY else TypeError
|
||||
d = badtypes(f, 1)
|
||||
assert isinstance(d, dict)
|
||||
assert list(badobjects(f, 1).keys()) == list(d.keys())
|
||||
assert list(errors(f, 1).keys()) == list(d.keys())
|
||||
s = set([(err.__class__.__name__,err.args[0]) for err in list(errors(f, 1).values())])
|
||||
a = dict(s)
|
||||
assert len(s) is len(a) # TypeError (and possibly PicklingError)
|
||||
n = 1 if IS_PYPY else 2
|
||||
assert len(a) is n if 'PicklingError' in a.keys() else n-1
|
||||
|
||||
def test_parent():
|
||||
x = [4,5,6,7]
|
||||
listiter = iter(x)
|
||||
obj = parent(listiter, list)
|
||||
assert obj is x
|
||||
|
||||
if IS_PYPY: assert parent(obj, int) is None
|
||||
else: assert parent(obj, int) is x[-1] # python oddly? finds last int
|
||||
assert at(id(at)) is at
|
||||
|
||||
a, b, c = 1, 2, 3
|
||||
|
||||
def squared(x):
|
||||
return a+x**2
|
||||
|
||||
def foo(x):
|
||||
def bar(y):
|
||||
return squared(x)+y
|
||||
return bar
|
||||
|
||||
class _class:
|
||||
def _method(self):
|
||||
pass
|
||||
def ok(self):
|
||||
return True
|
||||
|
||||
def test_globals():
|
||||
def f():
|
||||
a
|
||||
def g():
|
||||
b
|
||||
def h():
|
||||
c
|
||||
assert globalvars(f) == dict(a=1, b=2, c=3)
|
||||
|
||||
res = globalvars(foo, recurse=True)
|
||||
assert set(res) == set(['squared', 'a'])
|
||||
res = globalvars(foo, recurse=False)
|
||||
assert res == {}
|
||||
zap = foo(2)
|
||||
res = globalvars(zap, recurse=True)
|
||||
assert set(res) == set(['squared', 'a'])
|
||||
res = globalvars(zap, recurse=False)
|
||||
assert set(res) == set(['squared'])
|
||||
del zap
|
||||
res = globalvars(squared)
|
||||
assert set(res) == set(['a'])
|
||||
# FIXME: should find referenced __builtins__
|
||||
#res = globalvars(_class, recurse=True)
|
||||
#assert set(res) == set(['True'])
|
||||
#res = globalvars(_class, recurse=False)
|
||||
#assert res == {}
|
||||
#res = globalvars(_class.ok, recurse=True)
|
||||
#assert set(res) == set(['True'])
|
||||
#res = globalvars(_class.ok, recurse=False)
|
||||
#assert set(res) == set(['True'])
|
||||
|
||||
|
||||
#98 dill ignores __getstate__ in interactive lambdas
|
||||
bar = [0]
|
||||
|
||||
class Foo(object):
|
||||
def __init__(self):
|
||||
pass
|
||||
def __getstate__(self):
|
||||
bar[0] = bar[0]+1
|
||||
return {}
|
||||
def __setstate__(self, data):
|
||||
pass
|
||||
|
||||
f = Foo()
|
||||
|
||||
def test_getstate():
|
||||
from dill import dumps, loads
|
||||
dumps(f)
|
||||
b = bar[0]
|
||||
dumps(lambda: f, recurse=False) # doesn't call __getstate__
|
||||
assert bar[0] == b
|
||||
dumps(lambda: f, recurse=True) # calls __getstate__
|
||||
assert bar[0] == b + 1
|
||||
|
||||
#97 serialize lambdas in test files
|
||||
def test_deleted():
|
||||
from dill import dumps, loads
|
||||
from math import sin, pi
|
||||
global sin
|
||||
|
||||
def sinc(x):
|
||||
return sin(x)/x
|
||||
|
||||
settings['recurse'] = True
|
||||
_sinc = dumps(sinc)
|
||||
sin = globals().pop('sin')
|
||||
sin = 1
|
||||
del sin
|
||||
sinc_ = loads(_sinc) # no NameError... pickling preserves 'sin'
|
||||
res = sinc_(1)
|
||||
from math import sin
|
||||
assert sinc(1) == res
|
||||
|
||||
|
||||
def test_lambdify():
|
||||
try:
|
||||
from sympy import symbols, lambdify
|
||||
except ImportError:
|
||||
return
|
||||
settings['recurse'] = True
|
||||
x = symbols("x")
|
||||
y = x**2
|
||||
f = lambdify([x], y)
|
||||
z = min
|
||||
d = globals()
|
||||
globalvars(f, recurse=True, builtin=True)
|
||||
assert z is min
|
||||
assert d is globals()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_bad_things()
|
||||
test_parent()
|
||||
test_globals()
|
||||
test_getstate()
|
||||
test_deleted()
|
||||
test_lambdify()
|
@ -0,0 +1,110 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
from dill import __diff as diff
|
||||
|
||||
import sys
|
||||
IS_PYPY = not hasattr(sys, 'getrefcount')
|
||||
|
||||
class A:
|
||||
pass
|
||||
|
||||
def test_diff():
|
||||
a = A()
|
||||
b = A()
|
||||
c = A()
|
||||
a.a = b
|
||||
b.a = c
|
||||
diff.memorise(a)
|
||||
assert not diff.has_changed(a)
|
||||
c.a = 1
|
||||
assert diff.has_changed(a)
|
||||
diff.memorise(c, force=True)
|
||||
assert not diff.has_changed(a)
|
||||
c.a = 2
|
||||
assert diff.has_changed(a)
|
||||
changed = diff.whats_changed(a)
|
||||
assert list(changed[0].keys()) == ["a"]
|
||||
assert not changed[1]
|
||||
|
||||
a2 = []
|
||||
b2 = [a2]
|
||||
c2 = [b2]
|
||||
diff.memorise(c2)
|
||||
assert not diff.has_changed(c2)
|
||||
a2.append(1)
|
||||
assert diff.has_changed(c2)
|
||||
changed = diff.whats_changed(c2)
|
||||
assert changed[0] == {}
|
||||
assert changed[1]
|
||||
|
||||
a3 = {}
|
||||
b3 = {1: a3}
|
||||
c3 = {1: b3}
|
||||
diff.memorise(c3)
|
||||
assert not diff.has_changed(c3)
|
||||
a3[1] = 1
|
||||
assert diff.has_changed(c3)
|
||||
changed = diff.whats_changed(c3)
|
||||
assert changed[0] == {}
|
||||
assert changed[1]
|
||||
|
||||
if not IS_PYPY:
|
||||
try:
|
||||
import abc
|
||||
# make sure the "_abc_invaldation_counter" doesn't make test fail
|
||||
diff.memorise(abc.ABCMeta, force=True)
|
||||
assert not diff.has_changed(abc)
|
||||
abc.ABCMeta.zzz = 1
|
||||
assert diff.has_changed(abc)
|
||||
changed = diff.whats_changed(abc)
|
||||
assert list(changed[0].keys()) == ["ABCMeta"]
|
||||
assert not changed[1]
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
'''
|
||||
import Queue
|
||||
diff.memorise(Queue, force=True)
|
||||
assert not diff.has_changed(Queue)
|
||||
Queue.Queue.zzz = 1
|
||||
assert diff.has_changed(Queue)
|
||||
changed = diff.whats_changed(Queue)
|
||||
assert list(changed[0].keys()) == ["Queue"]
|
||||
assert not changed[1]
|
||||
|
||||
import math
|
||||
diff.memorise(math, force=True)
|
||||
assert not diff.has_changed(math)
|
||||
math.zzz = 1
|
||||
assert diff.has_changed(math)
|
||||
changed = diff.whats_changed(math)
|
||||
assert list(changed[0].keys()) == ["zzz"]
|
||||
assert not changed[1]
|
||||
'''
|
||||
|
||||
a = A()
|
||||
b = A()
|
||||
c = A()
|
||||
a.a = b
|
||||
b.a = c
|
||||
diff.memorise(a)
|
||||
assert not diff.has_changed(a)
|
||||
c.a = 1
|
||||
assert diff.has_changed(a)
|
||||
diff.memorise(c, force=True)
|
||||
assert not diff.has_changed(a)
|
||||
del c.a
|
||||
assert diff.has_changed(a)
|
||||
changed = diff.whats_changed(a)
|
||||
assert list(changed[0].keys()) == ["a"]
|
||||
assert not changed[1]
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_diff()
|
@ -0,0 +1,38 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import dill as pickle
|
||||
try:
|
||||
from StringIO import StringIO
|
||||
except ImportError:
|
||||
from io import BytesIO as StringIO
|
||||
|
||||
|
||||
def my_fn(x):
|
||||
return x * 17
|
||||
|
||||
|
||||
def test_extend():
|
||||
obj = lambda : my_fn(34)
|
||||
assert obj() == 578
|
||||
|
||||
obj_io = StringIO()
|
||||
pickler = pickle.Pickler(obj_io)
|
||||
pickler.dump(obj)
|
||||
|
||||
obj_str = obj_io.getvalue()
|
||||
|
||||
obj2_io = StringIO(obj_str)
|
||||
unpickler = pickle.Unpickler(obj2_io)
|
||||
obj2 = unpickler.load()
|
||||
|
||||
assert obj2() == 578
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_extend()
|
@ -0,0 +1,502 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import os
|
||||
import sys
|
||||
import string
|
||||
import random
|
||||
|
||||
import dill
|
||||
|
||||
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
fname = "_test_file.txt"
|
||||
rand_chars = list(string.ascii_letters) + ["\n"] * 40 # bias newline
|
||||
|
||||
if sys.hexversion < 0x03030000:
|
||||
FileNotFoundError = IOError
|
||||
buffer_error = ValueError("invalid buffer size")
|
||||
dne_error = FileNotFoundError("[Errno 2] No such file or directory: '%s'" % fname)
|
||||
|
||||
|
||||
def write_randomness(number=200):
|
||||
f = open(fname, "w")
|
||||
for i in range(number):
|
||||
f.write(random.choice(rand_chars))
|
||||
f.close()
|
||||
f = open(fname, "r")
|
||||
contents = f.read()
|
||||
f.close()
|
||||
return contents
|
||||
|
||||
|
||||
def trunc_file():
|
||||
open(fname, "w").close()
|
||||
|
||||
|
||||
def throws(op, args, exc):
|
||||
try:
|
||||
op(*args)
|
||||
except type(exc):
|
||||
return sys.exc_info()[1].args == exc.args
|
||||
else:
|
||||
return False
|
||||
|
||||
|
||||
def teardown_module():
|
||||
if os.path.exists(fname):
|
||||
os.remove(fname)
|
||||
|
||||
|
||||
def bench(strictio, fmode, skippypy):
|
||||
import platform
|
||||
if skippypy and platform.python_implementation() == 'PyPy':
|
||||
# Skip for PyPy...
|
||||
return
|
||||
|
||||
# file exists, with same contents
|
||||
# read
|
||||
|
||||
write_randomness()
|
||||
|
||||
f = open(fname, "r")
|
||||
_f = dill.loads(dill.dumps(f, fmode=fmode))#, strictio=strictio))
|
||||
assert _f.mode == f.mode
|
||||
assert _f.tell() == f.tell()
|
||||
assert _f.read() == f.read()
|
||||
f.close()
|
||||
_f.close()
|
||||
|
||||
# write
|
||||
|
||||
f = open(fname, "w")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
f2 = dill.loads(f_dumped) #FIXME: fails due to pypy/issues/1233
|
||||
# TypeError: expected py_object instance instead of str
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2name = f2.name
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
|
||||
if fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == ftell
|
||||
assert f2name == fname
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
|
||||
# append
|
||||
|
||||
trunc_file()
|
||||
|
||||
f = open(fname, "a")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
|
||||
assert f2mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2tell == ftell
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2tell == ftell
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
|
||||
# file exists, with different contents (smaller size)
|
||||
# read
|
||||
|
||||
write_randomness()
|
||||
|
||||
f = open(fname, "r")
|
||||
fstr = f.read()
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
_flen = 150
|
||||
_fstr = write_randomness(number=_flen)
|
||||
|
||||
if strictio: # throw error if ftell > EOF
|
||||
assert throws(dill.loads, (f_dumped,), buffer_error)
|
||||
else:
|
||||
f2 = dill.loads(f_dumped)
|
||||
assert f2.mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert f2.tell() == _flen
|
||||
assert f2.read() == ""
|
||||
f2.seek(0)
|
||||
assert f2.read() == _fstr
|
||||
assert f2.tell() == _flen # 150
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert f2.tell() == 0
|
||||
assert f2.read() == _fstr
|
||||
assert f2.tell() == _flen # 150
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert f2.tell() == ftell # 200
|
||||
assert f2.read() == ""
|
||||
f2.seek(0)
|
||||
assert f2.read() == fstr
|
||||
assert f2.tell() == ftell # 200
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close()
|
||||
|
||||
# write
|
||||
|
||||
write_randomness()
|
||||
|
||||
f = open(fname, "w")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
fstr = open(fname).read()
|
||||
|
||||
f = open(fname, "w")
|
||||
f.write("h")
|
||||
_ftell = f.tell()
|
||||
f.close()
|
||||
|
||||
if strictio: # throw error if ftell > EOF
|
||||
assert throws(dill.loads, (f_dumped,), buffer_error)
|
||||
else:
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == "h world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == _ftell
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close()
|
||||
|
||||
# append
|
||||
|
||||
trunc_file()
|
||||
|
||||
f = open(fname, "a")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
fstr = open(fname).read()
|
||||
|
||||
f = open(fname, "w")
|
||||
f.write("h")
|
||||
_ftell = f.tell()
|
||||
f.close()
|
||||
|
||||
if strictio: # throw error if ftell > EOF
|
||||
assert throws(dill.loads, (f_dumped,), buffer_error)
|
||||
else:
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
assert f2mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
# position of writes cannot be changed on some OSs
|
||||
assert open(fname).read() == "h world!"
|
||||
assert f2tell == _ftell
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == "h world!"
|
||||
assert f2tell == _ftell
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close()
|
||||
|
||||
# file does not exist
|
||||
# read
|
||||
|
||||
write_randomness()
|
||||
|
||||
f = open(fname, "r")
|
||||
fstr = f.read()
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
|
||||
os.remove(fname)
|
||||
|
||||
if strictio: # throw error if file DNE
|
||||
assert throws(dill.loads, (f_dumped,), dne_error)
|
||||
else:
|
||||
f2 = dill.loads(f_dumped)
|
||||
assert f2.mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
# FIXME: this fails on systems where f2.tell() always returns 0
|
||||
# assert f2.tell() == ftell # 200
|
||||
assert f2.read() == ""
|
||||
f2.seek(0)
|
||||
assert f2.read() == ""
|
||||
assert f2.tell() == 0
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert f2.tell() == ftell # 200
|
||||
assert f2.read() == ""
|
||||
f2.seek(0)
|
||||
assert f2.read() == fstr
|
||||
assert f2.tell() == ftell # 200
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert f2.tell() == 0
|
||||
assert f2.read() == ""
|
||||
assert f2.tell() == 0
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close()
|
||||
|
||||
# write
|
||||
|
||||
write_randomness()
|
||||
|
||||
f = open(fname, "w+")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
ftell = f.tell()
|
||||
f1mode = f.mode
|
||||
f.close()
|
||||
|
||||
os.remove(fname)
|
||||
|
||||
if strictio: # throw error if file DNE
|
||||
assert throws(dill.loads, (f_dumped,), dne_error)
|
||||
else:
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2mode == 'w+'
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
|
||||
# append
|
||||
|
||||
trunc_file()
|
||||
|
||||
f = open(fname, "a")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
ftell = f.tell()
|
||||
f1mode = f.mode
|
||||
f.close()
|
||||
|
||||
os.remove(fname)
|
||||
|
||||
if strictio: # throw error if file DNE
|
||||
assert throws(dill.loads, (f_dumped,), dne_error)
|
||||
else:
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
assert f2mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
|
||||
# file exists, with different contents (larger size)
|
||||
# read
|
||||
|
||||
write_randomness()
|
||||
|
||||
f = open(fname, "r")
|
||||
fstr = f.read()
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
f.close()
|
||||
_flen = 250
|
||||
_fstr = write_randomness(number=_flen)
|
||||
|
||||
# XXX: no safe_file: no way to be 'safe'?
|
||||
|
||||
f2 = dill.loads(f_dumped)
|
||||
assert f2.mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert f2.tell() == ftell # 200
|
||||
assert f2.read() == _fstr[ftell:]
|
||||
f2.seek(0)
|
||||
assert f2.read() == _fstr
|
||||
assert f2.tell() == _flen # 250
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert f2.tell() == 0
|
||||
assert f2.read() == _fstr
|
||||
assert f2.tell() == _flen # 250
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert f2.tell() == ftell # 200
|
||||
assert f2.read() == ""
|
||||
f2.seek(0)
|
||||
assert f2.read() == fstr
|
||||
assert f2.tell() == ftell # 200
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close() # XXX: other alternatives?
|
||||
|
||||
# write
|
||||
|
||||
f = open(fname, "w")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
|
||||
fstr = open(fname).read()
|
||||
|
||||
f.write(" and goodbye!")
|
||||
_ftell = f.tell()
|
||||
f.close()
|
||||
|
||||
# XXX: no safe_file: no way to be 'safe'?
|
||||
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == "hello world!odbye!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == ftell
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == " world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == 0
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2mode == f1mode
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close()
|
||||
|
||||
# append
|
||||
|
||||
trunc_file()
|
||||
|
||||
f = open(fname, "a")
|
||||
f.write("hello")
|
||||
f_dumped = dill.dumps(f, fmode=fmode)#, strictio=strictio)
|
||||
f1mode = f.mode
|
||||
ftell = f.tell()
|
||||
fstr = open(fname).read()
|
||||
|
||||
f.write(" and goodbye!")
|
||||
_ftell = f.tell()
|
||||
f.close()
|
||||
|
||||
# XXX: no safe_file: no way to be 'safe'?
|
||||
|
||||
f2 = dill.loads(f_dumped)
|
||||
f2mode = f2.mode
|
||||
f2tell = f2.tell()
|
||||
f2.write(" world!")
|
||||
f2.close()
|
||||
assert f2mode == f1mode
|
||||
if fmode == dill.CONTENTS_FMODE:
|
||||
assert open(fname).read() == "hello and goodbye! world!"
|
||||
assert f2tell == ftell
|
||||
elif fmode == dill.HANDLE_FMODE:
|
||||
assert open(fname).read() == "hello and goodbye! world!"
|
||||
assert f2tell == _ftell
|
||||
elif fmode == dill.FILE_FMODE:
|
||||
assert open(fname).read() == "hello world!"
|
||||
assert f2tell == ftell
|
||||
else:
|
||||
raise RuntimeError("Unknown file mode '%s'" % fmode)
|
||||
f2.close()
|
||||
|
||||
|
||||
def test_nostrictio_handlefmode():
|
||||
bench(False, dill.HANDLE_FMODE, False)
|
||||
teardown_module()
|
||||
|
||||
|
||||
def test_nostrictio_filefmode():
|
||||
bench(False, dill.FILE_FMODE, False)
|
||||
teardown_module()
|
||||
|
||||
|
||||
def test_nostrictio_contentsfmode():
|
||||
bench(False, dill.CONTENTS_FMODE, True)
|
||||
teardown_module()
|
||||
|
||||
|
||||
#bench(True, dill.HANDLE_FMODE, False)
|
||||
#bench(True, dill.FILE_FMODE, False)
|
||||
#bench(True, dill.CONTENTS_FMODE, True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_nostrictio_handlefmode()
|
||||
test_nostrictio_filefmode()
|
||||
test_nostrictio_contentsfmode()
|
@ -0,0 +1,63 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
|
||||
import dill
|
||||
import sys
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
|
||||
def is_py3():
|
||||
return hex(sys.hexversion) >= '0x30000f0'
|
||||
|
||||
|
||||
def function_a(a):
|
||||
return a
|
||||
|
||||
|
||||
def function_b(b, b1):
|
||||
return b + b1
|
||||
|
||||
|
||||
def function_c(c, c1=1):
|
||||
return c + c1
|
||||
|
||||
|
||||
def function_d(d, d1, d2=1):
|
||||
return d + d1 + d2
|
||||
|
||||
|
||||
if is_py3():
|
||||
exec('''
|
||||
def function_e(e, *e1, e2=1, e3=2):
|
||||
return e + sum(e1) + e2 + e3''')
|
||||
|
||||
|
||||
def test_functions():
|
||||
dumped_func_a = dill.dumps(function_a)
|
||||
assert dill.loads(dumped_func_a)(0) == 0
|
||||
|
||||
dumped_func_b = dill.dumps(function_b)
|
||||
assert dill.loads(dumped_func_b)(1,2) == 3
|
||||
|
||||
dumped_func_c = dill.dumps(function_c)
|
||||
assert dill.loads(dumped_func_c)(1) == 2
|
||||
assert dill.loads(dumped_func_c)(1, 2) == 3
|
||||
|
||||
dumped_func_d = dill.dumps(function_d)
|
||||
assert dill.loads(dumped_func_d)(1, 2) == 4
|
||||
assert dill.loads(dumped_func_d)(1, 2, 3) == 6
|
||||
assert dill.loads(dumped_func_d)(1, 2, d2=3) == 6
|
||||
|
||||
if is_py3():
|
||||
exec('''
|
||||
dumped_func_e = dill.dumps(function_e)
|
||||
assert dill.loads(dumped_func_e)(1, 2) == 6
|
||||
assert dill.loads(dumped_func_e)(1, 2, 3) == 9
|
||||
assert dill.loads(dumped_func_e)(1, 2, e2=3) == 8
|
||||
assert dill.loads(dumped_func_e)(1, 2, e2=3, e3=4) == 10
|
||||
assert dill.loads(dumped_func_e)(1, 2, 3, e2=4) == 12
|
||||
assert dill.loads(dumped_func_e)(1, 2, 3, e2=4, e3=5) == 15''')
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_functions()
|
@ -0,0 +1,39 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import functools
|
||||
import dill
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
|
||||
def f(a, b, c): # without keywords
|
||||
pass
|
||||
|
||||
|
||||
def g(a, b, c=2): # with keywords
|
||||
pass
|
||||
|
||||
|
||||
def h(a=1, b=2, c=3): # without args
|
||||
pass
|
||||
|
||||
|
||||
def test_functools():
|
||||
fp = functools.partial(f, 1, 2)
|
||||
gp = functools.partial(g, 1, c=2)
|
||||
hp = functools.partial(h, 1, c=2)
|
||||
bp = functools.partial(int, base=2)
|
||||
|
||||
assert dill.pickles(fp, safe=True)
|
||||
assert dill.pickles(gp, safe=True)
|
||||
assert dill.pickles(hp, safe=True)
|
||||
assert dill.pickles(bp, safe=True)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_functools()
|
@ -0,0 +1,121 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import dill
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
|
||||
def wtf(x,y,z):
|
||||
def zzz():
|
||||
return x
|
||||
def yyy():
|
||||
return y
|
||||
def xxx():
|
||||
return z
|
||||
return zzz,yyy
|
||||
|
||||
|
||||
def quad(a=1, b=1, c=0):
|
||||
inverted = [False]
|
||||
def invert():
|
||||
inverted[0] = not inverted[0]
|
||||
def dec(f):
|
||||
def func(*args, **kwds):
|
||||
x = f(*args, **kwds)
|
||||
if inverted[0]: x = -x
|
||||
return a*x**2 + b*x + c
|
||||
func.__wrapped__ = f
|
||||
func.invert = invert
|
||||
func.inverted = inverted
|
||||
return func
|
||||
return dec
|
||||
|
||||
|
||||
@quad(a=0,b=2)
|
||||
def double_add(*args):
|
||||
return sum(args)
|
||||
|
||||
|
||||
fx = sum([1,2,3])
|
||||
|
||||
|
||||
### to make it interesting...
|
||||
def quad_factory(a=1,b=1,c=0):
|
||||
def dec(f):
|
||||
def func(*args,**kwds):
|
||||
fx = f(*args,**kwds)
|
||||
return a*fx**2 + b*fx + c
|
||||
return func
|
||||
return dec
|
||||
|
||||
|
||||
@quad_factory(a=0,b=4,c=0)
|
||||
def quadish(x):
|
||||
return x+1
|
||||
|
||||
|
||||
quadratic = quad_factory()
|
||||
|
||||
|
||||
def doubler(f):
|
||||
def inner(*args, **kwds):
|
||||
fx = f(*args, **kwds)
|
||||
return 2*fx
|
||||
return inner
|
||||
|
||||
|
||||
@doubler
|
||||
def quadruple(x):
|
||||
return 2*x
|
||||
|
||||
|
||||
def test_mixins():
|
||||
# test mixins
|
||||
assert double_add(1,2,3) == 2*fx
|
||||
double_add.invert()
|
||||
assert double_add(1,2,3) == -2*fx
|
||||
|
||||
_d = dill.copy(double_add)
|
||||
assert _d(1,2,3) == -2*fx
|
||||
#_d.invert() #FIXME: fails seemingly randomly
|
||||
#assert _d(1,2,3) == 2*fx
|
||||
|
||||
assert _d.__wrapped__(1,2,3) == fx
|
||||
|
||||
# XXX: issue or feature? in python3.4, inverted is linked through copy
|
||||
if not double_add.inverted[0]:
|
||||
double_add.invert()
|
||||
|
||||
# test some stuff from source and pointers
|
||||
ds = dill.source
|
||||
dd = dill.detect
|
||||
assert ds.getsource(dd.freevars(quadish)['f']) == '@quad_factory(a=0,b=4,c=0)\ndef quadish(x):\n return x+1\n'
|
||||
assert ds.getsource(dd.freevars(quadruple)['f']) == '@doubler\ndef quadruple(x):\n return 2*x\n'
|
||||
assert ds.importable(quadish, source=False) == 'from %s import quadish\n' % __name__
|
||||
assert ds.importable(quadruple, source=False) == 'from %s import quadruple\n' % __name__
|
||||
assert ds.importable(quadratic, source=False) == 'from %s import quadratic\n' % __name__
|
||||
assert ds.importable(double_add, source=False) == 'from %s import double_add\n' % __name__
|
||||
assert ds.importable(quadruple, source=True) == 'def doubler(f):\n def inner(*args, **kwds):\n fx = f(*args, **kwds)\n return 2*fx\n return inner\n\n@doubler\ndef quadruple(x):\n return 2*x\n'
|
||||
#***** #FIXME: this needs work
|
||||
result = ds.importable(quadish, source=True)
|
||||
a,b,c,_,result = result.split('\n',4)
|
||||
assert result == 'def quad_factory(a=1,b=1,c=0):\n def dec(f):\n def func(*args,**kwds):\n fx = f(*args,**kwds)\n return a*fx**2 + b*fx + c\n return func\n return dec\n\n@quad_factory(a=0,b=4,c=0)\ndef quadish(x):\n return x+1\n'
|
||||
assert set([a,b,c]) == set(['a = 0', 'c = 0', 'b = 4'])
|
||||
result = ds.importable(quadratic, source=True)
|
||||
a,b,c,result = result.split('\n',3)
|
||||
assert result == '\ndef dec(f):\n def func(*args,**kwds):\n fx = f(*args,**kwds)\n return a*fx**2 + b*fx + c\n return func\n'
|
||||
assert set([a,b,c]) == set(['a = 1', 'c = 0', 'b = 1'])
|
||||
result = ds.importable(double_add, source=True)
|
||||
a,b,c,d,_,result = result.split('\n',5)
|
||||
assert result == 'def quad(a=1, b=1, c=0):\n inverted = [False]\n def invert():\n inverted[0] = not inverted[0]\n def dec(f):\n def func(*args, **kwds):\n x = f(*args, **kwds)\n if inverted[0]: x = -x\n return a*x**2 + b*x + c\n func.__wrapped__ = f\n func.invert = invert\n func.inverted = inverted\n return func\n return dec\n\n@quad(a=0,b=2)\ndef double_add(*args):\n return sum(args)\n'
|
||||
assert set([a,b,c,d]) == set(['a = 0', 'c = 0', 'b = 2', 'inverted = [True]'])
|
||||
#*****
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_mixins()
|
@ -0,0 +1,85 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import sys
|
||||
import dill
|
||||
import test_mixins as module
|
||||
try: from imp import reload
|
||||
except ImportError: pass
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
cached = (module.__cached__ if hasattr(module, "__cached__")
|
||||
else module.__file__.split(".", 1)[0] + ".pyc")
|
||||
|
||||
module.a = 1234
|
||||
|
||||
pik_mod = dill.dumps(module)
|
||||
|
||||
module.a = 0
|
||||
|
||||
# remove module
|
||||
del sys.modules[module.__name__]
|
||||
del module
|
||||
|
||||
module = dill.loads(pik_mod)
|
||||
def test_attributes():
|
||||
#assert hasattr(module, "a") and module.a == 1234 #FIXME: -m dill.tests
|
||||
assert module.double_add(1, 2, 3) == 2 * module.fx
|
||||
|
||||
# Restart, and test use_diff
|
||||
|
||||
reload(module)
|
||||
|
||||
try:
|
||||
dill.use_diff()
|
||||
|
||||
module.a = 1234
|
||||
|
||||
pik_mod = dill.dumps(module)
|
||||
|
||||
module.a = 0
|
||||
|
||||
# remove module
|
||||
del sys.modules[module.__name__]
|
||||
del module
|
||||
|
||||
module = dill.loads(pik_mod)
|
||||
def test_diff_attributes():
|
||||
assert hasattr(module, "a") and module.a == 1234
|
||||
assert module.double_add(1, 2, 3) == 2 * module.fx
|
||||
|
||||
except AttributeError:
|
||||
def test_diff_attributes():
|
||||
pass
|
||||
|
||||
# clean up
|
||||
import os
|
||||
if os.path.exists(cached):
|
||||
os.remove(cached)
|
||||
pycache = os.path.join(os.path.dirname(module.__file__), "__pycache__")
|
||||
if os.path.exists(pycache) and not os.listdir(pycache):
|
||||
os.removedirs(pycache)
|
||||
|
||||
|
||||
# test when module is None
|
||||
import math
|
||||
|
||||
def get_lambda(str, **kwarg):
|
||||
return eval(str, kwarg, None)
|
||||
|
||||
obj = get_lambda('lambda x: math.exp(x)', math=math)
|
||||
|
||||
def test_module_is_none():
|
||||
assert obj.__module__ is None
|
||||
assert dill.copy(obj)(3) == obj(3)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_attributes()
|
||||
test_diff_attributes()
|
||||
test_module_is_none()
|
@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import dill
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
def f(func):
|
||||
def w(*args):
|
||||
return f(*args)
|
||||
return w
|
||||
|
||||
@f
|
||||
def f2(): pass
|
||||
|
||||
# check when __main__ and on import
|
||||
def test_decorated():
|
||||
assert dill.pickles(f2)
|
||||
|
||||
|
||||
import doctest
|
||||
import logging
|
||||
logging.basicConfig(level=logging.DEBUG)
|
||||
|
||||
class SomeUnreferencedUnpicklableClass(object):
|
||||
def __reduce__(self):
|
||||
raise Exception
|
||||
|
||||
unpicklable = SomeUnreferencedUnpicklableClass()
|
||||
|
||||
# This works fine outside of Doctest:
|
||||
def test_normal():
|
||||
serialized = dill.dumps(lambda x: x)
|
||||
|
||||
# should not try to pickle unpicklable object in __globals__
|
||||
def tests():
|
||||
"""
|
||||
>>> serialized = dill.dumps(lambda x: x)
|
||||
"""
|
||||
return
|
||||
|
||||
#print("\n\nRunning Doctest:")
|
||||
def test_doctest():
|
||||
doctest.testmod()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_decorated()
|
||||
test_normal()
|
||||
test_doctest()
|
@ -0,0 +1,135 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
test dill's ability to handle nested functions
|
||||
"""
|
||||
|
||||
import os
|
||||
import math
|
||||
|
||||
import dill as pickle
|
||||
pickle.settings['recurse'] = True
|
||||
|
||||
|
||||
# the nested function: pickle should fail here, but dill is ok.
|
||||
def adder(augend):
|
||||
zero = [0]
|
||||
|
||||
def inner(addend):
|
||||
return addend + augend + zero[0]
|
||||
return inner
|
||||
|
||||
|
||||
# rewrite the nested function using a class: standard pickle should work here.
|
||||
class cadder(object):
|
||||
def __init__(self, augend):
|
||||
self.augend = augend
|
||||
self.zero = [0]
|
||||
|
||||
def __call__(self, addend):
|
||||
return addend + self.augend + self.zero[0]
|
||||
|
||||
|
||||
# rewrite again, but as an old-style class
|
||||
class c2adder:
|
||||
def __init__(self, augend):
|
||||
self.augend = augend
|
||||
self.zero = [0]
|
||||
|
||||
def __call__(self, addend):
|
||||
return addend + self.augend + self.zero[0]
|
||||
|
||||
|
||||
# some basic class stuff
|
||||
class basic(object):
|
||||
pass
|
||||
|
||||
|
||||
class basic2:
|
||||
pass
|
||||
|
||||
|
||||
x = 5
|
||||
y = 1
|
||||
|
||||
|
||||
def test_basic():
|
||||
a = [0, 1, 2]
|
||||
pa = pickle.dumps(a)
|
||||
pmath = pickle.dumps(math) #XXX: FAILS in pickle
|
||||
pmap = pickle.dumps(map)
|
||||
# ...
|
||||
la = pickle.loads(pa)
|
||||
lmath = pickle.loads(pmath)
|
||||
lmap = pickle.loads(pmap)
|
||||
assert list(map(math.sin, a)) == list(lmap(lmath.sin, la))
|
||||
|
||||
|
||||
def test_basic_class():
|
||||
pbasic2 = pickle.dumps(basic2)
|
||||
_pbasic2 = pickle.loads(pbasic2)()
|
||||
pbasic = pickle.dumps(basic)
|
||||
_pbasic = pickle.loads(pbasic)()
|
||||
|
||||
|
||||
def test_c2adder():
|
||||
pc2adder = pickle.dumps(c2adder)
|
||||
pc2add5 = pickle.loads(pc2adder)(x)
|
||||
assert pc2add5(y) == x+y
|
||||
|
||||
|
||||
def test_pickled_cadder():
|
||||
pcadder = pickle.dumps(cadder)
|
||||
pcadd5 = pickle.loads(pcadder)(x)
|
||||
assert pcadd5(y) == x+y
|
||||
|
||||
|
||||
def test_raw_adder_and_inner():
|
||||
add5 = adder(x)
|
||||
assert add5(y) == x+y
|
||||
|
||||
|
||||
def test_pickled_adder():
|
||||
padder = pickle.dumps(adder)
|
||||
padd5 = pickle.loads(padder)(x)
|
||||
assert padd5(y) == x+y
|
||||
|
||||
|
||||
def test_pickled_inner():
|
||||
add5 = adder(x)
|
||||
pinner = pickle.dumps(add5) #XXX: FAILS in pickle
|
||||
p5add = pickle.loads(pinner)
|
||||
assert p5add(y) == x+y
|
||||
|
||||
|
||||
def test_moduledict_where_not_main():
|
||||
try:
|
||||
from . import test_moduledict
|
||||
except:
|
||||
import test_moduledict
|
||||
name = 'test_moduledict.py'
|
||||
if os.path.exists(name) and os.path.exists(name+'c'):
|
||||
os.remove(name+'c')
|
||||
|
||||
if os.path.exists(name) and hasattr(test_moduledict, "__cached__") \
|
||||
and os.path.exists(test_moduledict.__cached__):
|
||||
os.remove(getattr(test_moduledict, "__cached__"))
|
||||
|
||||
if os.path.exists("__pycache__") and not os.listdir("__pycache__"):
|
||||
os.removedirs("__pycache__")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_basic()
|
||||
test_basic_class()
|
||||
test_c2adder()
|
||||
test_pickled_cadder()
|
||||
test_raw_adder_and_inner()
|
||||
test_pickled_adder()
|
||||
test_pickled_inner()
|
||||
test_moduledict_where_not_main()
|
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
demonstrate dill's ability to pickle different python types
|
||||
test pickling of all Python Standard Library objects (currently: CH 1-14 @ 2.7)
|
||||
"""
|
||||
|
||||
import dill as pickle
|
||||
pickle.settings['recurse'] = True
|
||||
#pickle.detect.trace(True)
|
||||
#import pickle
|
||||
|
||||
# get all objects for testing
|
||||
from dill import load_types, objects, extend
|
||||
load_types(pickleable=True,unpickleable=False)
|
||||
|
||||
# uncomment the next two lines to test cloudpickle
|
||||
#extend(False)
|
||||
#import cloudpickle as pickle
|
||||
|
||||
# helper objects
|
||||
class _class:
|
||||
def _method(self):
|
||||
pass
|
||||
|
||||
# objects that *fail* if imported
|
||||
special = {}
|
||||
special['LambdaType'] = _lambda = lambda x: lambda y: x
|
||||
special['MethodType'] = _method = _class()._method
|
||||
special['UnboundMethodType'] = _class._method
|
||||
objects.update(special)
|
||||
|
||||
def pickles(name, exact=False):
|
||||
"""quick check if object pickles with dill"""
|
||||
obj = objects[name]
|
||||
try:
|
||||
pik = pickle.loads(pickle.dumps(obj))
|
||||
if exact:
|
||||
try:
|
||||
assert pik == obj
|
||||
except AssertionError:
|
||||
assert type(obj) == type(pik)
|
||||
print ("weak: %s %s" % (name, type(obj)))
|
||||
else:
|
||||
assert type(obj) == type(pik)
|
||||
except Exception:
|
||||
print ("fails: %s %s" % (name, type(obj)))
|
||||
|
||||
|
||||
def test_objects():
|
||||
for member in objects.keys():
|
||||
#pickles(member, exact=True)
|
||||
pickles(member, exact=False)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_objects()
|
@ -0,0 +1,62 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import sys
|
||||
|
||||
import dill
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
|
||||
class Foo(object):
|
||||
def __init__(self):
|
||||
self._data = 1
|
||||
|
||||
def _get_data(self):
|
||||
return self._data
|
||||
|
||||
def _set_data(self, x):
|
||||
self._data = x
|
||||
|
||||
data = property(_get_data, _set_data)
|
||||
|
||||
|
||||
def test_data_not_none():
|
||||
FooS = dill.copy(Foo)
|
||||
assert FooS.data.fget is not None
|
||||
assert FooS.data.fset is not None
|
||||
assert FooS.data.fdel is None
|
||||
|
||||
|
||||
def test_data_unchanged():
|
||||
FooS = dill.copy(Foo)
|
||||
try:
|
||||
res = FooS().data
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
raise AssertionError(str(e))
|
||||
else:
|
||||
assert res == 1
|
||||
|
||||
|
||||
def test_data_changed():
|
||||
FooS = dill.copy(Foo)
|
||||
try:
|
||||
f = FooS()
|
||||
f.data = 1024
|
||||
res = f.data
|
||||
except Exception:
|
||||
e = sys.exc_info()[1]
|
||||
raise AssertionError(str(e))
|
||||
else:
|
||||
assert res == 1024
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_data_not_none()
|
||||
test_data_unchanged()
|
||||
test_data_changed()
|
@ -0,0 +1,85 @@
|
||||
import dill
|
||||
from functools import partial
|
||||
from dill._dill import PY3, OLDER
|
||||
_super = super
|
||||
|
||||
class obj1(object):
|
||||
def __init__(self):
|
||||
super(obj1, self).__init__()
|
||||
|
||||
class obj2(object):
|
||||
def __init__(self):
|
||||
_super(obj2, self).__init__()
|
||||
|
||||
class obj3(object):
|
||||
super_ = super
|
||||
def __init__(self):
|
||||
obj3.super_(obj3, self).__init__()
|
||||
|
||||
|
||||
def test_super():
|
||||
assert dill.copy(obj1(), byref=True)
|
||||
assert dill.copy(obj1(), byref=True, recurse=True)
|
||||
#assert dill.copy(obj1(), recurse=True) #FIXME: fails __main__.py
|
||||
assert dill.copy(obj1())
|
||||
|
||||
assert dill.copy(obj2(), byref=True)
|
||||
assert dill.copy(obj2(), byref=True, recurse=True)
|
||||
#assert dill.copy(obj2(), recurse=True) #FIXME: fails __main__.py
|
||||
assert dill.copy(obj2())
|
||||
|
||||
assert dill.copy(obj3(), byref=True)
|
||||
assert dill.copy(obj3(), byref=True, recurse=True)
|
||||
#assert dill.copy(obj3(), recurse=True) #FIXME: fails __main__.py
|
||||
assert dill.copy(obj3())
|
||||
|
||||
|
||||
def get_trigger(model):
|
||||
pass
|
||||
|
||||
class Machine(object):
|
||||
def __init__(self):
|
||||
self.child = Model()
|
||||
self.trigger = partial(get_trigger, self)
|
||||
self.child.trigger = partial(get_trigger, self.child)
|
||||
|
||||
class Model(object):
|
||||
pass
|
||||
|
||||
|
||||
|
||||
def test_partial():
|
||||
assert dill.copy(Machine(), byref=True)
|
||||
assert dill.copy(Machine(), byref=True, recurse=True)
|
||||
if not OLDER:
|
||||
assert dill.copy(Machine(), recurse=True)
|
||||
assert dill.copy(Machine())
|
||||
|
||||
|
||||
class Machine2(object):
|
||||
def __init__(self):
|
||||
self.go = partial(self.member, self)
|
||||
def member(self, model):
|
||||
pass
|
||||
|
||||
|
||||
class SubMachine(Machine2):
|
||||
def __init__(self):
|
||||
_super(SubMachine, self).__init__()
|
||||
#super(SubMachine, self).__init__() #XXX: works, except for 3.1-3.3
|
||||
|
||||
|
||||
def test_partials():
|
||||
assert dill.copy(SubMachine(), byref=True)
|
||||
assert dill.copy(SubMachine(), byref=True, recurse=True)
|
||||
#if not OLDER: #FIXME: fails __main__.py
|
||||
# assert dill.copy(SubMachine(), recurse=True)
|
||||
assert dill.copy(SubMachine())
|
||||
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
#print(('byref','_super','_recurse','_memo','_stop','OLDER'))
|
||||
test_super()
|
||||
test_partial()
|
||||
test_partials()
|
@ -0,0 +1,27 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Kirill Makhonin (@kirillmakhonin)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import dill
|
||||
|
||||
class RestrictedType:
|
||||
def __bool__(*args, **kwargs):
|
||||
raise Exception('Restricted function')
|
||||
|
||||
__eq__ = __lt__ = __le__ = __ne__ = __gt__ = __ge__ = __hash__ = __bool__
|
||||
|
||||
glob_obj = RestrictedType()
|
||||
|
||||
def restricted_func():
|
||||
a = glob_obj
|
||||
|
||||
def test_function_with_restricted_object():
|
||||
deserialized = dill.loads(dill.dumps(restricted_func, recurse=True))
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_function_with_restricted_object()
|
@ -0,0 +1,99 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
testing some selected object types
|
||||
"""
|
||||
|
||||
import dill
|
||||
dill.settings['recurse'] = True
|
||||
|
||||
verbose = False
|
||||
|
||||
def test_dict_contents():
|
||||
c = type.__dict__
|
||||
for i,j in c.items():
|
||||
#try:
|
||||
ok = dill.pickles(j)
|
||||
#except:
|
||||
# print ("FAIL: %s with %s" % (i, dill.detect.errors(j)))
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(j), j))
|
||||
assert ok
|
||||
if verbose: print ("")
|
||||
|
||||
def _g(x): yield x;
|
||||
|
||||
def _f():
|
||||
try: raise
|
||||
except:
|
||||
from sys import exc_info
|
||||
e, er, tb = exc_info()
|
||||
return er, tb
|
||||
|
||||
class _d(object):
|
||||
def _method(self):
|
||||
pass
|
||||
|
||||
from dill import objects
|
||||
from dill import load_types
|
||||
load_types(pickleable=True,unpickleable=False)
|
||||
_newclass = objects['ClassObjectType']
|
||||
del objects
|
||||
|
||||
# getset_descriptor for new-style classes (fails on '_method', if not __main__)
|
||||
def test_class_descriptors():
|
||||
d = _d.__dict__
|
||||
for i in d.values():
|
||||
ok = dill.pickles(i)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(i), i))
|
||||
assert ok
|
||||
if verbose: print ("")
|
||||
od = _newclass.__dict__
|
||||
for i in od.values():
|
||||
ok = dill.pickles(i)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(i), i))
|
||||
assert ok
|
||||
if verbose: print ("")
|
||||
|
||||
# (__main__) class instance for new-style classes
|
||||
def test_class():
|
||||
o = _d()
|
||||
oo = _newclass()
|
||||
ok = dill.pickles(o)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(o), o))
|
||||
assert ok
|
||||
ok = dill.pickles(oo)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(oo), oo))
|
||||
assert ok
|
||||
if verbose: print ("")
|
||||
|
||||
# frames, generators, and tracebacks (all depend on frame)
|
||||
def test_frame_related():
|
||||
g = _g(1)
|
||||
f = g.gi_frame
|
||||
e,t = _f()
|
||||
_is = lambda ok: not ok if dill._dill.IS_PYPY else ok
|
||||
ok = dill.pickles(f)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(f), f))
|
||||
assert _is(not ok) #XXX: dill fails
|
||||
ok = dill.pickles(g)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(g), g))
|
||||
assert _is(not ok) #XXX: dill fails
|
||||
ok = dill.pickles(t)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(t), t))
|
||||
assert not ok #XXX: dill fails
|
||||
ok = dill.pickles(e)
|
||||
if verbose: print ("%s: %s, %s" % (ok, type(e), e))
|
||||
assert ok
|
||||
if verbose: print ("")
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_frame_related()
|
||||
test_dict_contents()
|
||||
test_class()
|
||||
test_class_descriptors()
|
@ -0,0 +1,161 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
from dill.source import getsource, getname, _wrap, likely_import
|
||||
from dill.source import getimportable
|
||||
|
||||
|
||||
import sys
|
||||
PY3 = sys.version_info[0] >= 3
|
||||
|
||||
f = lambda x: x**2
|
||||
def g(x): return f(x) - x
|
||||
|
||||
def h(x):
|
||||
def g(x): return x
|
||||
return g(x) - x
|
||||
|
||||
class Foo(object):
|
||||
def bar(self, x):
|
||||
return x*x+x
|
||||
_foo = Foo()
|
||||
|
||||
def add(x,y):
|
||||
return x+y
|
||||
|
||||
# yes, same as 'f', but things are tricky when it comes to pointers
|
||||
squared = lambda x:x**2
|
||||
|
||||
class Bar:
|
||||
pass
|
||||
_bar = Bar()
|
||||
|
||||
# inspect.getsourcelines # dill.source.getblocks
|
||||
def test_getsource():
|
||||
assert getsource(f) == 'f = lambda x: x**2\n'
|
||||
assert getsource(g) == 'def g(x): return f(x) - x\n'
|
||||
assert getsource(h) == 'def h(x):\n def g(x): return x\n return g(x) - x\n'
|
||||
assert getname(f) == 'f'
|
||||
assert getname(g) == 'g'
|
||||
assert getname(h) == 'h'
|
||||
assert _wrap(f)(4) == 16
|
||||
assert _wrap(g)(4) == 12
|
||||
assert _wrap(h)(4) == 0
|
||||
|
||||
assert getname(Foo) == 'Foo'
|
||||
assert getname(Bar) == 'Bar'
|
||||
assert getsource(Bar) == 'class Bar:\n pass\n'
|
||||
assert getsource(Foo) == 'class Foo(object):\n def bar(self, x):\n return x*x+x\n'
|
||||
#XXX: add getsource for _foo, _bar
|
||||
|
||||
# test itself
|
||||
def test_itself():
|
||||
assert likely_import(likely_import)=='from dill.source import likely_import\n'
|
||||
|
||||
# builtin functions and objects
|
||||
def test_builtin():
|
||||
if PY3: builtin = 'builtins'
|
||||
else: builtin = '__builtin__'
|
||||
assert likely_import(pow) == 'pow\n'
|
||||
assert likely_import(100) == '100\n'
|
||||
assert likely_import(True) == 'True\n'
|
||||
assert likely_import(pow, explicit=True) == 'from %s import pow\n' % builtin
|
||||
assert likely_import(100, explicit=True) == '100\n'
|
||||
assert likely_import(True, explicit=True) == 'True\n' if PY3 else 'from %s import True\n' % builtin
|
||||
# this is kinda BS... you can't import a None
|
||||
assert likely_import(None) == 'None\n'
|
||||
assert likely_import(None, explicit=True) == 'None\n'
|
||||
|
||||
|
||||
# other imported functions
|
||||
def test_imported():
|
||||
from math import sin
|
||||
assert likely_import(sin) == 'from math import sin\n'
|
||||
|
||||
# interactively defined functions
|
||||
def test_dynamic():
|
||||
assert likely_import(add) == 'from %s import add\n' % __name__
|
||||
# interactive lambdas
|
||||
assert likely_import(squared) == 'from %s import squared\n' % __name__
|
||||
|
||||
# classes and class instances
|
||||
def test_classes():
|
||||
try: #XXX: should this be a 'special case'?
|
||||
from StringIO import StringIO
|
||||
x = "from StringIO import StringIO\n"
|
||||
y = x
|
||||
except ImportError:
|
||||
from io import BytesIO as StringIO
|
||||
x = "from io import BytesIO\n"
|
||||
y = "from _io import BytesIO\n"
|
||||
s = StringIO()
|
||||
|
||||
assert likely_import(StringIO) == x
|
||||
assert likely_import(s) == y
|
||||
# interactively defined classes and class instances
|
||||
assert likely_import(Foo) == 'from %s import Foo\n' % __name__
|
||||
assert likely_import(_foo) == 'from %s import Foo\n' % __name__
|
||||
|
||||
|
||||
# test getimportable
|
||||
def test_importable():
|
||||
assert getimportable(add) == 'from %s import add\n' % __name__
|
||||
assert getimportable(squared) == 'from %s import squared\n' % __name__
|
||||
assert getimportable(Foo) == 'from %s import Foo\n' % __name__
|
||||
assert getimportable(Foo.bar) == 'from %s import bar\n' % __name__
|
||||
assert getimportable(_foo.bar) == 'from %s import bar\n' % __name__
|
||||
assert getimportable(None) == 'None\n'
|
||||
assert getimportable(100) == '100\n'
|
||||
|
||||
assert getimportable(add, byname=False) == 'def add(x,y):\n return x+y\n'
|
||||
assert getimportable(squared, byname=False) == 'squared = lambda x:x**2\n'
|
||||
assert getimportable(None, byname=False) == 'None\n'
|
||||
assert getimportable(Bar, byname=False) == 'class Bar:\n pass\n'
|
||||
assert getimportable(Foo, byname=False) == 'class Foo(object):\n def bar(self, x):\n return x*x+x\n'
|
||||
assert getimportable(Foo.bar, byname=False) == 'def bar(self, x):\n return x*x+x\n'
|
||||
assert getimportable(Foo.bar, byname=True) == 'from %s import bar\n' % __name__
|
||||
assert getimportable(Foo.bar, alias='memo', byname=True) == 'from %s import bar as memo\n' % __name__
|
||||
assert getimportable(Foo, alias='memo', byname=True) == 'from %s import Foo as memo\n' % __name__
|
||||
assert getimportable(squared, alias='memo', byname=True) == 'from %s import squared as memo\n' % __name__
|
||||
assert getimportable(squared, alias='memo', byname=False) == 'memo = squared = lambda x:x**2\n'
|
||||
assert getimportable(add, alias='memo', byname=False) == 'def add(x,y):\n return x+y\n\nmemo = add\n'
|
||||
assert getimportable(None, alias='memo', byname=False) == 'memo = None\n'
|
||||
assert getimportable(100, alias='memo', byname=False) == 'memo = 100\n'
|
||||
assert getimportable(add, explicit=True) == 'from %s import add\n' % __name__
|
||||
assert getimportable(squared, explicit=True) == 'from %s import squared\n' % __name__
|
||||
assert getimportable(Foo, explicit=True) == 'from %s import Foo\n' % __name__
|
||||
assert getimportable(Foo.bar, explicit=True) == 'from %s import bar\n' % __name__
|
||||
assert getimportable(_foo.bar, explicit=True) == 'from %s import bar\n' % __name__
|
||||
assert getimportable(None, explicit=True) == 'None\n'
|
||||
assert getimportable(100, explicit=True) == '100\n'
|
||||
|
||||
|
||||
def test_numpy():
|
||||
try:
|
||||
from numpy import array
|
||||
x = array([1,2,3])
|
||||
assert getimportable(x) == 'from numpy import array\narray([1, 2, 3])\n'
|
||||
assert getimportable(array) == 'from %s import array\n' % array.__module__
|
||||
assert getimportable(x, byname=False) == 'from numpy import array\narray([1, 2, 3])\n'
|
||||
assert getimportable(array, byname=False) == 'from %s import array\n' % array.__module__
|
||||
except ImportError: pass
|
||||
|
||||
#NOTE: if before likely_import(pow), will cause pow to throw AssertionError
|
||||
def test_foo():
|
||||
assert getimportable(_foo, byname=False).startswith("import dill\nclass Foo(object):\n def bar(self, x):\n return x*x+x\ndill.loads(")
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_getsource()
|
||||
test_itself()
|
||||
test_builtin()
|
||||
test_imported()
|
||||
test_dynamic()
|
||||
test_classes()
|
||||
test_importable()
|
||||
test_numpy()
|
||||
test_foo()
|
@ -0,0 +1,103 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import sys
|
||||
from dill.temp import dump, dump_source, dumpIO, dumpIO_source
|
||||
from dill.temp import load, load_source, loadIO, loadIO_source
|
||||
WINDOWS = sys.platform[:3] == 'win'
|
||||
|
||||
|
||||
f = lambda x: x**2
|
||||
x = [1,2,3,4,5]
|
||||
|
||||
# source code to tempfile
|
||||
def test_code_to_tempfile():
|
||||
if not WINDOWS: #see: https://bugs.python.org/issue14243
|
||||
pyfile = dump_source(f, alias='_f')
|
||||
_f = load_source(pyfile)
|
||||
assert _f(4) == f(4)
|
||||
|
||||
# source code to stream
|
||||
def test_code_to_stream():
|
||||
pyfile = dumpIO_source(f, alias='_f')
|
||||
_f = loadIO_source(pyfile)
|
||||
assert _f(4) == f(4)
|
||||
|
||||
# pickle to tempfile
|
||||
def test_pickle_to_tempfile():
|
||||
if not WINDOWS: #see: https://bugs.python.org/issue14243
|
||||
dumpfile = dump(x)
|
||||
_x = load(dumpfile)
|
||||
assert _x == x
|
||||
|
||||
# pickle to stream
|
||||
def test_pickle_to_stream():
|
||||
dumpfile = dumpIO(x)
|
||||
_x = loadIO(dumpfile)
|
||||
assert _x == x
|
||||
|
||||
### now testing the objects ###
|
||||
f = lambda x: x**2
|
||||
def g(x): return f(x) - x
|
||||
|
||||
def h(x):
|
||||
def g(x): return x
|
||||
return g(x) - x
|
||||
|
||||
class Foo(object):
|
||||
def bar(self, x):
|
||||
return x*x+x
|
||||
_foo = Foo()
|
||||
|
||||
def add(x,y):
|
||||
return x+y
|
||||
|
||||
# yes, same as 'f', but things are tricky when it comes to pointers
|
||||
squared = lambda x:x**2
|
||||
|
||||
class Bar:
|
||||
pass
|
||||
_bar = Bar()
|
||||
|
||||
|
||||
# test function-type objects that take 2 args
|
||||
def test_two_arg_functions():
|
||||
for obj in [add]:
|
||||
pyfile = dumpIO_source(obj, alias='_obj')
|
||||
_obj = loadIO_source(pyfile)
|
||||
assert _obj(4,2) == obj(4,2)
|
||||
|
||||
# test function-type objects that take 1 arg
|
||||
def test_one_arg_functions():
|
||||
for obj in [g, h, squared]:
|
||||
pyfile = dumpIO_source(obj, alias='_obj')
|
||||
_obj = loadIO_source(pyfile)
|
||||
assert _obj(4) == obj(4)
|
||||
|
||||
# test instance-type objects
|
||||
#for obj in [_bar, _foo]:
|
||||
# pyfile = dumpIO_source(obj, alias='_obj')
|
||||
# _obj = loadIO_source(pyfile)
|
||||
# assert type(_obj) == type(obj)
|
||||
|
||||
# test the rest of the objects
|
||||
def test_the_rest():
|
||||
for obj in [Bar, Foo, Foo.bar, _foo.bar]:
|
||||
pyfile = dumpIO_source(obj, alias='_obj')
|
||||
_obj = loadIO_source(pyfile)
|
||||
assert _obj.__name__ == obj.__name__
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_code_to_tempfile()
|
||||
test_code_to_stream()
|
||||
test_pickle_to_tempfile()
|
||||
test_pickle_to_stream()
|
||||
test_two_arg_functions()
|
||||
test_one_arg_functions()
|
||||
test_the_rest()
|
@ -0,0 +1,89 @@
|
||||
#!/usr/bin/env python
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
|
||||
import dill
|
||||
dill.settings['recurse'] = True
|
||||
import weakref
|
||||
|
||||
class _class:
|
||||
def _method(self):
|
||||
pass
|
||||
|
||||
class _class2:
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
class _newclass(object):
|
||||
def _method(self):
|
||||
pass
|
||||
|
||||
class _newclass2(object):
|
||||
def __call__(self):
|
||||
pass
|
||||
|
||||
def _function():
|
||||
pass
|
||||
|
||||
|
||||
def test_weakref():
|
||||
o = _class()
|
||||
oc = _class2()
|
||||
n = _newclass()
|
||||
nc = _newclass2()
|
||||
f = _function
|
||||
z = _class
|
||||
x = _newclass
|
||||
|
||||
r = weakref.ref(o)
|
||||
dr = weakref.ref(_class())
|
||||
p = weakref.proxy(o)
|
||||
dp = weakref.proxy(_class())
|
||||
c = weakref.proxy(oc)
|
||||
dc = weakref.proxy(_class2())
|
||||
|
||||
m = weakref.ref(n)
|
||||
dm = weakref.ref(_newclass())
|
||||
t = weakref.proxy(n)
|
||||
dt = weakref.proxy(_newclass())
|
||||
d = weakref.proxy(nc)
|
||||
dd = weakref.proxy(_newclass2())
|
||||
|
||||
fr = weakref.ref(f)
|
||||
fp = weakref.proxy(f)
|
||||
#zr = weakref.ref(z) #XXX: weakrefs not allowed for classobj objects
|
||||
#zp = weakref.proxy(z) #XXX: weakrefs not allowed for classobj objects
|
||||
xr = weakref.ref(x)
|
||||
xp = weakref.proxy(x)
|
||||
|
||||
objlist = [r,dr,m,dm,fr,xr, p,dp,t,dt, c,dc,d,dd, fp,xp]
|
||||
#dill.detect.trace(True)
|
||||
|
||||
for obj in objlist:
|
||||
res = dill.detect.errors(obj)
|
||||
if res:
|
||||
print ("%s" % res)
|
||||
#print ("%s:\n %s" % (obj, res))
|
||||
# else:
|
||||
# print ("PASS: %s" % obj)
|
||||
assert not res
|
||||
|
||||
def test_dictproxy():
|
||||
from dill._dill import DictProxyType
|
||||
try:
|
||||
m = DictProxyType({"foo": "bar"})
|
||||
except:
|
||||
m = type.__dict__
|
||||
mp = dill.copy(m)
|
||||
assert mp.items() == m.items()
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
test_weakref()
|
||||
from dill._dill import IS_PYPY
|
||||
if not IS_PYPY:
|
||||
test_dictproxy()
|
@ -0,0 +1 @@
|
||||
pip
|
@ -0,0 +1,48 @@
|
||||
PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
|
||||
--------------------------------------------
|
||||
|
||||
1. This LICENSE AGREEMENT is between the Python Software Foundation
|
||||
("PSF"), and the Individual or Organization ("Licensee") accessing and
|
||||
otherwise using this software ("Python") in source or binary form and
|
||||
its associated documentation.
|
||||
|
||||
2. Subject to the terms and conditions of this License Agreement, PSF
|
||||
hereby grants Licensee a nonexclusive, royalty-free, world-wide
|
||||
license to reproduce, analyze, test, perform and/or display publicly,
|
||||
prepare derivative works, distribute, and otherwise use Python
|
||||
alone or in any derivative version, provided, however, that PSF's
|
||||
License Agreement and PSF's notice of copyright, i.e., "Copyright (c)
|
||||
2001, 2002, 2003, 2004, 2005, 2006 Python Software Foundation; All Rights
|
||||
Reserved" are retained in Python alone or in any derivative version
|
||||
prepared by Licensee.
|
||||
|
||||
3. In the event Licensee prepares a derivative work that is based on
|
||||
or incorporates Python or any part thereof, and wants to make
|
||||
the derivative work available to others as provided herein, then
|
||||
Licensee hereby agrees to include in any such work a brief summary of
|
||||
the changes made to Python.
|
||||
|
||||
4. PSF is making Python available to Licensee on an "AS IS"
|
||||
basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
|
||||
IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
|
||||
DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
|
||||
FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
|
||||
INFRINGE ANY THIRD PARTY RIGHTS.
|
||||
|
||||
5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
|
||||
FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
|
||||
A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
|
||||
OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
|
||||
|
||||
6. This License Agreement will automatically terminate upon a material
|
||||
breach of its terms and conditions.
|
||||
|
||||
7. Nothing in this License Agreement shall be deemed to create any
|
||||
relationship of agency, partnership, or joint venture between PSF and
|
||||
Licensee. This License Agreement does not grant permission to use PSF
|
||||
trademarks or trade name in a trademark sense to endorse or promote
|
||||
products or services of Licensee, or any third party.
|
||||
|
||||
8. By copying, installing or otherwise using Python, Licensee
|
||||
agrees to be bound by the terms and conditions of this License
|
||||
Agreement.
|
@ -0,0 +1,21 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: futures
|
||||
Version: 3.1.1
|
||||
Summary: Backport of the concurrent.futures package from Python 3.2
|
||||
Home-page: https://github.com/agronholm/pythonfutures
|
||||
Author: Brian Quinlan
|
||||
Author-email: brian@sweetapp.com
|
||||
Maintainer: Alex Gronholm
|
||||
Maintainer-email: alex.gronholm+pypi@nextday.fi
|
||||
License: PSF
|
||||
Platform: UNKNOWN
|
||||
Classifier: License :: OSI Approved :: Python Software Foundation License
|
||||
Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 2 :: Only
|
||||
|
||||
UNKNOWN
|
||||
|
||||
|
@ -0,0 +1,6 @@
|
||||
futures-3.1.1.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
futures-3.1.1.dist-info/LICENSE,sha256=ppi9XUQeShavbJkrjoDL-hJ1XXLZEIVPofsR1N6wBZo,2395
|
||||
futures-3.1.1.dist-info/METADATA,sha256=4x6xpqUIETthRvn7Z-puOLm5FypL8DdBOkO4f-RWE9k,674
|
||||
futures-3.1.1.dist-info/RECORD,,
|
||||
futures-3.1.1.dist-info/WHEEL,sha256=t_MpApv386-8PVts2R6wsTifdIn0vbUDTVv61IbqFC8,92
|
||||
futures-3.1.1.dist-info/top_level.txt,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
|
@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.33.3)
|
||||
Root-Is-Purelib: true
|
||||
Tag: py3-none-any
|
||||
|
@ -0,0 +1 @@
|
||||
|
@ -0,0 +1 @@
|
||||
pip
|
@ -0,0 +1,90 @@
|
||||
Metadata-Version: 2.1
|
||||
Name: greenlet
|
||||
Version: 0.4.15
|
||||
Summary: Lightweight in-process concurrent programming
|
||||
Home-page: https://github.com/python-greenlet/greenlet
|
||||
Maintainer: Alexey Borzenkov
|
||||
Maintainer-email: snaury@gmail.com
|
||||
License: MIT License
|
||||
Platform: any
|
||||
Classifier: Intended Audience :: Developers
|
||||
Classifier: License :: OSI Approved :: MIT License
|
||||
Classifier: Natural Language :: English
|
||||
Classifier: Programming Language :: C
|
||||
Classifier: Programming Language :: Python
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.4
|
||||
Classifier: Programming Language :: Python :: 2.5
|
||||
Classifier: Programming Language :: Python :: 2.6
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.0
|
||||
Classifier: Programming Language :: Python :: 3.1
|
||||
Classifier: Programming Language :: Python :: 3.2
|
||||
Classifier: Programming Language :: Python :: 3.3
|
||||
Classifier: Programming Language :: Python :: 3.4
|
||||
Classifier: Programming Language :: Python :: 3.5
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Operating System :: OS Independent
|
||||
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
||||
|
||||
.. image:: https://secure.travis-ci.org/python-greenlet/greenlet.png
|
||||
:target: http://travis-ci.org/python-greenlet/greenlet
|
||||
|
||||
The greenlet package is a spin-off of Stackless, a version of CPython
|
||||
that supports micro-threads called "tasklets". Tasklets run
|
||||
pseudo-concurrently (typically in a single or a few OS-level threads)
|
||||
and are synchronized with data exchanges on "channels".
|
||||
|
||||
A "greenlet", on the other hand, is a still more primitive notion of
|
||||
micro-thread with no implicit scheduling; coroutines, in other
|
||||
words. This is useful when you want to control exactly when your code
|
||||
runs. You can build custom scheduled micro-threads on top of greenlet;
|
||||
however, it seems that greenlets are useful on their own as a way to
|
||||
make advanced control flow structures. For example, we can recreate
|
||||
generators; the difference with Python's own generators is that our
|
||||
generators can call nested functions and the nested functions can
|
||||
yield values too. Additionally, you don't need a "yield" keyword. See
|
||||
the example in tests/test_generator.py.
|
||||
|
||||
Greenlets are provided as a C extension module for the regular
|
||||
unmodified interpreter.
|
||||
|
||||
Greenlets are lightweight coroutines for in-process concurrent
|
||||
programming.
|
||||
|
||||
Who is using Greenlet?
|
||||
======================
|
||||
|
||||
There are several libraries that use Greenlet as a more flexible
|
||||
alternative to Python's built in coroutine support:
|
||||
|
||||
- `Concurrence`_
|
||||
- `Eventlet`_
|
||||
- `Gevent`_
|
||||
|
||||
.. _Concurrence: http://opensource.hyves.org/concurrence/
|
||||
.. _Eventlet: http://eventlet.net/
|
||||
.. _Gevent: http://www.gevent.org/
|
||||
|
||||
Getting Greenlet
|
||||
================
|
||||
|
||||
The easiest way to get Greenlet is to install it with pip or
|
||||
easy_install::
|
||||
|
||||
pip install greenlet
|
||||
easy_install greenlet
|
||||
|
||||
|
||||
Source code archives and windows installers are available on the
|
||||
python package index at https://pypi.python.org/pypi/greenlet
|
||||
|
||||
The source code repository is hosted on github:
|
||||
https://github.com/python-greenlet/greenlet
|
||||
|
||||
Documentation is available on readthedocs.org:
|
||||
https://greenlet.readthedocs.io
|
||||
|
||||
|
@ -0,0 +1,7 @@
|
||||
../../include/site/python3.6/greenlet/greenlet.h,sha256=SlcS2utGqDJj1KnMDK745yitcJKNUIbAUaFA8rN-4sY,3972
|
||||
greenlet-0.4.15.dist-info/INSTALLER,sha256=zuuue4knoyJ-UwPPXg8fezS7VCrXJQrAP7zeNuwvFQg,4
|
||||
greenlet-0.4.15.dist-info/METADATA,sha256=QAeWa2K18gQhCDt1FDxaJts5YpJZ7B8ez3wBioeUmDQ,3304
|
||||
greenlet-0.4.15.dist-info/RECORD,,
|
||||
greenlet-0.4.15.dist-info/WHEEL,sha256=xq3J6sB2oJqjv0tDC7tGUGvne1fOugw1JUmk86QA7UM,106
|
||||
greenlet-0.4.15.dist-info/top_level.txt,sha256=YSnRsCRoO61JGlP57o8iKL6rdLWDWuiyKD8ekpWUsDc,9
|
||||
greenlet.cp36-win_amd64.pyd,sha256=JEgAoI_JxSm30xINTYVDKN9GNWhDtKJZfo2MphzEp3s,28672
|
@ -0,0 +1,5 @@
|
||||
Wheel-Version: 1.0
|
||||
Generator: bdist_wheel (0.31.1)
|
||||
Root-Is-Purelib: false
|
||||
Tag: cp36-cp36m-win_amd64
|
||||
|
@ -0,0 +1 @@
|
||||
greenlet
|
Binary file not shown.
@ -0,0 +1,54 @@
|
||||
#!C:\Users\sgoud\PycharmProjects\EnsoBot\venv\Scripts\python.exe
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
display the reference paths for objects in ``dill.types`` or a .pkl file
|
||||
|
||||
Notes:
|
||||
the generated image is useful in showing the pointer references in
|
||||
objects that are or can be pickled. Any object in ``dill.objects``
|
||||
listed in ``dill.load_types(picklable=True, unpicklable=True)`` works.
|
||||
|
||||
Examples::
|
||||
|
||||
$ get_objgraph FrameType
|
||||
Image generated as FrameType.png
|
||||
"""
|
||||
|
||||
import dill as pickle
|
||||
#pickle.debug.trace(True)
|
||||
#import pickle
|
||||
|
||||
# get all objects for testing
|
||||
from dill import load_types
|
||||
load_types(pickleable=True,unpickleable=True)
|
||||
from dill import objects
|
||||
|
||||
if __name__ == "__main__":
|
||||
import sys
|
||||
if len(sys.argv) != 2:
|
||||
print ("Please provide exactly one file or type name (e.g. 'IntType')")
|
||||
msg = "\n"
|
||||
for objtype in list(objects.keys())[:40]:
|
||||
msg += objtype + ', '
|
||||
print (msg + "...")
|
||||
else:
|
||||
objtype = str(sys.argv[-1])
|
||||
try:
|
||||
obj = objects[objtype]
|
||||
except KeyError:
|
||||
obj = pickle.load(open(objtype,'rb'))
|
||||
import os
|
||||
objtype = os.path.splitext(objtype)[0]
|
||||
try:
|
||||
import objgraph
|
||||
objgraph.show_refs(obj, filename=objtype+'.png')
|
||||
except ImportError:
|
||||
print ("Please install 'objgraph' to view object graphs")
|
||||
|
||||
|
||||
# EOF
|
@ -0,0 +1,22 @@
|
||||
#!C:\Users\sgoud\PycharmProjects\EnsoBot\venv\Scripts\python.exe
|
||||
#
|
||||
# Author: Mike McKerns (mmckerns @caltech and @uqfoundation)
|
||||
# Copyright (c) 2008-2016 California Institute of Technology.
|
||||
# Copyright (c) 2016-2019 The Uncertainty Quantification Foundation.
|
||||
# License: 3-clause BSD. The full license text is available at:
|
||||
# - https://github.com/uqfoundation/dill/blob/master/LICENSE
|
||||
"""
|
||||
unpickle the contents of a pickled object file
|
||||
|
||||
Examples::
|
||||
|
||||
$ undill hello.pkl
|
||||
['hello', 'world']
|
||||
"""
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
import dill
|
||||
for file in sys.argv[1:]:
|
||||
print (dill.load(open(file,'rb')))
|
||||
|
Loading…
Reference in New Issue