2016-03-01 5 views
5

私のrpcコードでエッジケースをテストするためにピクルできないオブジェクトを簡単に作成する方法はありますか?ピクルできないオブジェクトを作成します

それはする必要があります:

  • (Pythonや漬物の将来のバージョンでは壊れないと予想)

    1. シンプル
    2. 信頼性の高いクロスプラットフォームを

    編集:使用用途ルックスこのようなもの:

    class TestRPCServer: 
        def foo(self): 
         return MagicalUnpicklableObject() 
    
    def test(): 
        with run_rpc_server_and_connect_to_it() as proxy: 
         with nose.assert_raises(pickle.PickleError): 
          proxy.foo() 
    
  • +0

    をあなたは何を構築していますか?問題のオブジェクトのサンプルコードがありますか? – GLaDOS

    答えて

    6

    あなたが必要とするのは、テストピッタリのために例外をスローするオブジェクトであれば、__getstate__ methodを爆破することができます。

    >>> class C: 
    ...  def __getstate__(self): 
    ...   raise Exception 
    ... 
    >>> pickle.dumps(C()) 
    Traceback (most recent call last): 
        File "<stdin>", line 1, in <module> 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps 
        Pickler(file, protocol).dump(obj) 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump 
        self.save(obj) 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 286, in save 
        f(self, obj) # Call unbound method with explicit self 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 723, in save_inst 
        stuff = getstate() 
        File "<stdin>", line 3, in __getstate__ 
    Exception 
    

    それほど簡単ではありません。


    あなたはあまり人工的なシナリオをしたい場合は、ファイルハンドル、またはソケットのようなOSのリソースを使用するオブジェクト、またはスレッドを考えるが、など

    >>> with open('spam.txt', 'w') as f: 
    ...  pickle.dumps(f) 
    ... 
    Traceback (most recent call last): 
        File "<stdin>", line 2, in <module> 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 1374, in dumps 
        Pickler(file, protocol).dump(obj) 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 224, in dump 
        self.save(obj) 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/pickle.py", line 306, in save 
        rv = reduce(self.proto) 
        File "/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/copy_reg.py", line 70, in _reduce_ex 
        raise TypeError, "can't pickle %s objects" % base.__name__ 
    TypeError: can't pickle file objects 
    
    +0

    最初のやり方は、私が必要としているものです。実際には不要なPickleErrorを投げようとしたため、私は立ち往生しました。カスタム例外クラスを作成し、それをスローするだけで十分です。 – cube

    2

    あなたは、そのオブジェクトの明示的なリストが必要な場合pickleとより高度なシリアライザdillの両方を使用して、このファイルには標準ライブラリオブジェクトの多少の包括的なリストが含まれています。これは、各オブジェクト(通常は1ライナー)を作成する簡単な方法を提供し、適用可能であれば、さまざまなバージョンのPythonのバリエーションを示します。例えば

    https://github.com/uqfoundation/dill/blob/cccbea9b715e16b742288e1e5a21a687a4d4081b/dill/_objects.py#L255

    dillのような先進的なシリアライザはありませんが、pickleは、次のオブジェクトに失敗します:

    >>> import dill 
    >>> dill.dumps(Ellipsis) 
    b'\x80\x03cdill.dill\n_eval_repr\nq\x00X\x08\x00\x00\x00Ellipsisq\x01\x85q\x02Rq\x03.' 
    

    高度なシリアライザはまたところで、ファイルオブジェクトなどに取り組むことができます。

    >>> dill.dumps(open('foo.pkl', 'w')) 
    b'\x80\x03cdill.dill\n_create_filehandle\nq\x00(X\x07\x00\x00\x00foo.pklq\x01X\x01\x00\x00\x00wq\x02K\x00\x89cdill.dill\n_get_attr\nq\x03cdill.dill\n_import_module\nq\x04X\x02\x00\x00\x00ioq\x05\x85q\x06Rq\x07X\x04\x00\x00\x00openq\x08\x86q\tRq\n\x89K\x00X\x00\x00\x00\x00q\x0btq\x0cRq\r.' 
    

    ただし、pickleおよびdill (およびその他の高度なシリアライザ)発電機のように、直接のpython FrameTypeに結び付けられているいずれかのタイプに失敗します:

    >>> dill.dumps((i for i in [])) 
    Traceback (most recent call last): 
        File "<stdin>", line 1, in <module> 
        File "/Users/mmckerns/lib/python3.4/site-packages/dill-0.2.6.dev0-py3.4.egg/dill/dill.py", line 243, in dumps 
        dump(obj, file, protocol, byref, fmode, recurse)#, strictio) 
        File "/Users/mmckerns/lib/python3.4/site-packages/dill-0.2.6.dev0-py3.4.egg/dill/dill.py", line 236, in dump 
        pik.dump(obj) 
        File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pickle.py", line 412, in dump 
        self.save(obj) 
        File "/opt/local/Library/Frameworks/Python.framework/Versions/3.4/lib/python3.4/pickle.py", line 499, in save 
        rv = reduce(self.proto) 
    TypeError: can't pickle generator objects 
    
    関連する問題