2017-12-23 10 views
0

私のコード上の特定のデコレータを無視して、関連する機能をスキップしたいのですが、単体テストの一部として実行している場合に限ります。これはできますか?例えばPython:ユニット(鼻)テスト中にデコレータを無視する方法は?

私はそうのようなnumbaデコレータで定義され、関数fを持っている:私はnumbaのマジックが起こることを望んでいない上記の関数を呼び出す単体テストを実行すると

@numba.jit 
def f(a, b): 
    return a + b 

、などいくつかのプラットフォームでは処理が遅くなり、エラーが発生する可能性があります。 numbaのジャストインタイム(および/またはすべてのnumba)デコレータを適用せずにテストを実行するように鼻に指示する場所を設定することは可能ですか?

+1

私が気づいていないのは、私はそれがうまくいくかどうか分かりません。自分で書く必要があると思います。例えば、 'f = numba 'を使ってモジュール内の上位レベルにその関数を公開することができます。jit(f) '形式を使用して、元のラップされていないバージョンを直接テストにインポートします。 – jonrsharpe

答えて

1

機能を変更しない独自のデコレータを使用すると、鼻を騙すことができます。

def jit(func): 
    return func 

とあなたのPYTHONPATHに置か: この機能が含まれているファイルnumba.pyを書きます。 いずれかが、このファイルが置かれているディレクトリからテストを実行したり、最初の行として でテストファイルを次の操作を行います。

import sys 

sys.path.insert(0, 'path/to/dir/with/myfile') 

また、あなたがあなたのファイルがあるディレクトリに環境変数PYTHONPATHを設定することができます。

のWindows:

set PYTHONPATH=%PYTHONPATH%;path/to/dir/with/myfile 

のUnix/Macの場合:

export PYTHONPATH=$PYTHONPATH$:path/to/dir/with/myfile 
+0

ハッキー、確かに、それは私が思うように動作します。 –

+0

私のテストのために働いた。 –

+0

ええ、それはデコレータと他のものの混合物を持つライブラリにはあまり一般化できないかもしれません。しかし、numbaの場合、それは良い解決策です。おそらく他のライブラリでは、 'module.decorator = lambda f:f'のようなものになります。 –

2

あなたはあなたがコントロールすることができ、新たなデコレータとデコレータにパッチを適用できますと

import functools 

def patch(parent, obj_name, switch_reg, switch_name): 
    def gen_switcher(): 
     def wrapper(func): 
      ori_wrapped = ori_decorator(func) 
      @functools.wraps(func) 
      def _(*args, **kwargs): 
       if switch_reg.get(switch_name, False): 
        func_to_call = func 
       else: 
        func_to_call = ori_wrapped 
       print(func_to_call) 
       return func_to_call(*args, **kwargs) 
      return _ 
     return wrapper 
    ori_decorator = getattr(parent, obj_name) 
    setattr(parent, obj_name, gen_switcher()) 

# have to patch the decorator before applying it 
import numba 
switchs = {} 
patch(numba, 'jit', switchs, 'DISABLE_NUMBA_JIT') 

@numba.jit 
def f(a, b): 
    return a + b 

f(1, 2) 

利回り:と、その後

CPUDispatcher(<function f at 0x10a5f90d0>) 

# this part could be rewrited as a context manager  
switchs['DISABLE_NUMBA_JIT'] = True 
f(1, 2) 

GET:numbaについては

<function f at 0x10a5f90d0> 
+0

これはもっと簡単な解決策に見えるので私が気にするよりも魔法のようですが、 "bravo!"それにもかかわらず。ご協力いただきありがとうございます。 –

+0

@ JamesAdams私はあなたの問題が単にgoogleとdocを読んで解決できるとは予想していません。 – georgexsh

1

私はあなたのユニットテスト一部非飾らに機能を分離う - と、あなたの本当の機能をするデコレータを持っており、単にヘルパー関数を呼び出す:

@numba.jit 
def f(a, b): 
    return f_undecorated(a, b) 

def f_undecorated(a, b): 
    return a + b 

書き込みユニットテストはf_undecoratedです。

+0

これは面白い/巧妙なアプローチです。環境内の何かで猿にする必要がないため、すべてがコードになります。しかし、コード/複雑さが増しています(実際は名目上です)。それが私のために働いている上記の答えと比較してどのように比較されているか分かりません(助言してください)。あなたのお手伝いをどうもありがとうございます、私はあなたの努力に感謝します。 –

関連する問題