2017-05-31 8 views
3
import hashlib 


def my_function(bytes_): 
    """ 
    >>> my_function(b'\0') 
    '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' 
    """ 
    return hashlib.sha256(bytes_).hexdigest() 


if __name__ == "__main__": 
    import doctest 
    doctest.testmod() 

予想される動作を含むことができません: 1試験はとValueError:ソースコード列はヌルバイトを

実際の挙動を渡し:ValueError例外がdoctest.py内から上昇させます。

私は同じ結果とb'\x00'リテラルとしても使用することを試みました。 doctestでnullバイトを使用する方法は?正確にここでの問題は何ですか?また、修正が必要なのか、あまりにも醜い回避策がありますか?

+0

は、なぜあなたはあなたのドキュメントのNULLバイトを_want_でしょうか?ドキュメントに 'my_function(b '\ 0')'ではなく 'my_function(b '\ 0')'を読み込ませたいとします。私はここに何かを逃していますかあなたは生の弦をそこに使用したいと確信しています... –

+0

これはMCVEです。コードがnullバイトを特定の方法で処理するという事実は、*私のアプリケーションでは実際には関連して必要です。 – wim

+0

ただ、気づい:[ピクルス](https://github.com/python/cpython/blob/3.6/Lib/pickletools.py#L252)は、これと同じ二重解析問題に対処しなければならないのdoctestを持っています。 – wim

答えて

3

あなたのdoctestは二重解析されています。まず、Pythonはドキュメンテーション文字列自体にNULLバイトに\0を変換するために、次にdoctest試みは、Pythonコードとして>>>後の事を実行するために、バックスラッシュ処理を施し、バックスラッシュ処理が既に適用されているため、エラーが発生しました。

また、これはちょうどあなたのドキュメンテーション文字列を印刷しようとしている、またはあなたの関数にhelpを呼び出そうと誰のための問題だろう。正規表現と同様に

、バックスラッシュ処理の第1層を回避するために、生の文字列表記を使用します。

def my_function(bytes_): 
    r""" 
    >>> my_function(b'\0') 
    '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' 
    """ 
    return hashlib.sha256(bytes_).hexdigest() 
0

あなたが別のバックスラッシュでエスケープする必要がバックスラッシュを格納するための文字列をしたいです。それ以外の場合は、次の文字をエスケープしようとしています。あなたのケースでは

b'\0'はそれゆえ、ヌル文字で自分の誤りを\0に置き換えられます。 代わりにお試しください:

def my_function(bytes_): 
    """ 
    >>> my_function(b'\\0') 
    '6e340b9cffb37a989ca544e6bb780a2c78901d3fb33738768511a30617afa01d' 
    """ 
    return hashlib.sha256(bytes_).hexdigest() 
+0

これは実際には機能しますが、不思議な事故によってのみ起こります。 'rb '\ 0'のsha256は6e340bのように始まっていませんが、86f80f ... – wim

+0

のようになりました。つまりdoctestが誤解を招いています。 – wim