2017-11-04 4 views
3

は、私は非常にこのようになり、非常に小さなフラスコのアプリがあります。それが唯一のWeb UIに位置データを供給するために存在するフラスコをdictsとしてnamedtuplesを返し、すべてではない時間

Point = namedtuple('Point', ['lat', 'lng', 'alt']) 

p1 = Point(38.897741, -77.036450, 20) 


def create_app(): 
    app = flask.Flask(__name__) 

    @app.route('/position') 
    def position(): 
     return flask.jsonify({ 
      'vehicle': p1, 
     }) 

    return app 

を。 、あなたが知っている、それは大丈夫ですた...

{ 
    "vehicle": { 
    "alt": 20, 
    "lat": 38.897741, 
    "lng": -77.03645 
    } 
} 

:私はPoint namedtupleは、JSON配列としてレンダリングされることを期待していたが、私の驚きに私はなっていました。私はそれを使って作業することができます。突然、私はない取得辞書だったので、

from unittest import TestCase 
import json 
import tupletest 

    class TupleTestTest(TestCase): 
     def setUp(self): 
      _app = tupletest.create_app() 
      _app.config['TESTING'] = True 
      self.app = _app.test_client() 

     def test_position(self): 
      rv = self.app.get('/position') 
      assert rv.status_code == 200 
      assert rv.mimetype == 'application/json' 
      data = json.loads(rv.get_data()) 
      assert data['vehicle']['lat'] = 38.897741 

...そして、彼らは失敗しました::確かに

>  assert data['vehicle']['lat'] == 38.897741 
E  TypeError: list indices must be integers, not str 

そして、しかし、私はこのような何かを見て、いくつかのユニットテストを、書いていましたテストでは、私は、ファイルへの戻り値を書いた場合、私は持っていた:

{ 
    "vehicle": [ 
    38.897741, 
    -77.03645, 
    20 
    ] 
} 

何。

ここでは何が起こっていますか?私はこの質問の目的のためにこれを再現することすらできません。上記の単体テストは辞書をレンダリングします。私の実際のWebアプリケーションはいつ実行されているのですか?しかし、別のシステムでは、実際のアプリケーションから配列を取得しているようです。

# Use the same json implementation as itsdangerous on which we 
# depend anyways. 
from itsdangerous import json as _json 

itstangerous.pyであり:ソースコードを見てみると

+0

私は名前付きタプルの '_asdict'メソッドを使ってこれを解決しているので、*明示的に*辞書を返すようになっていますが、これがバージョンスキューであるかどうかに関心があります(フラスコ例えば、0.11.1対0.12.2)または他の何か。 – larsks

答えて

2

が、これはフラスコのjsonify.pyである

try: 
    import simplejson as json 
except ImportError: 
    import json 

simplejsonライブラリがデフォルトで有効になってオプションnamedtuple_as_objectを持っています。


サードパーティsimplejsonがインストールされているときに、アプリはそれを使用してJSONオブジェクト(Pythonで辞書)にnamedtupleをシリアライズします。

ライブラリがインストールされていないシステムでは、アプリケーションは標準jsonに戻り、名前付きタプルを配列(リスト)にシリアル化します。

フラスコでsimplejsonを取り付けて輸入する場合、テストプログラムは標準jsonを直接インポートして、実行中とテスト中の動作を変更します。

+0

これが原因です。テストをアプリケーションと一致させるには、 'json'を'フラスコ 'からインポートする必要があります:' flask from import json' –

+0

@VPfB根本的な理由でこの曖昧な問題を掘り下げてくれてありがとう! – larsks

+0

@LuisOrduz 'フラスコ'モジュールから 'json'を使用しても、テストには影響しません。問題はデータ構造がどのようにシリアライズされるかです。様々な 'json'モジュールのどれもが配列を元の' namedtuple'に再構成することはできません(ラベルは直列化プロセスで失われるため)。 – larsks

関連する問題