【发布时间】:2014-10-27 22:40:53
【问题描述】:
我正在尝试在字符串中输出与 http 请求相关的数据:
r = requests.post(url, data, params)
assert r.status_code == 200, '\nurl - {}\nresponse status - {}\nrequest headers - {}\nrequest body - {}\nresponse headers - {}\nresponse body - {}'.format(
r.url, r.status_code, r.request.headers, r.request.body, r.headers, r.text)
在我的本地机器 (python 2.7.5) 上运行它效果很好,所有相关数据都显示并格式化。
从 Jenkins 构建作业执行此操作时,它会返回异常:
assert r.status_code == 200, '\nurl - {url}\nresponse status - {status}\nrequest headers - {r_headers!s}\nrequest body - {r_body}\nresponse headers - {headers}\nresponse body - {body}'.format( url=r.url, status=r.status_code, r_headers=r.request.headers, r_body=r.request.body, headers=r.headers, body=r.text) TypeError: float argument required, not dicttest_watch.py:58: 类型错误
通过将 .format 方法更改为一次只报告一个变量进行一些调试,我发现 Jenkins 作业在插入请求标头时存在字符串格式问题。是的,它是一个字典,但是 .format() 方法应该可以很好地处理这个问题。为什么抱怨类型?
完整的回溯并不是很有帮助:
assert r.status_code == 400, 'Negative test failure' \ '\nurl - {url}\nresponse status - {status}\nrequest headers - {r_headers!s}\nrequest body - {r_body}\nresponse headers - {headers}\nresponse body - {body}'.format( url=r.url, status=r.status_code, r_headers=r.request.headers, r_body=r.request.body, headers=r.headers, body=r.text)E TypeError: float argument required, not dict
test_watch.py:58: 类型错误
总结一下:这适用于我的本地机器,请求标头以字符串形式输出:
assert r.status_code == 400, 'Negative test failure' \
'\nrequest headers - {r.request.headers}'.format(r=r)
从 Jenkins 构建服务器运行相同的代码:
assert r.status_code == 400, 'Negative test failure' \ '\nrequest headers - {r.request.headers}'.format(r=r) TypeError: float argument required, not dict test_watch.py:58: TypeError
更新:我更改了代码以捕获 TypeError,然后引发了一个自定义 AssertionError,以相同的方式从相同的部分构建(我复制/粘贴)。这非常令人困惑,为什么 .format 以一种方式工作,而另一种则完全失败?
try:
assert r.status_code == 400, 'Negative test failure' \
'\nurl - {r.url}\nresponse status - {r.status_code}\nrequest headers - {r.request.headers}\nrequest body - {r.request.body}\nresponse headers - {r.headers}\nresponse body - {r.text}'.format(r=r)
except TypeError as e:
message = 'TypeError raised! {}'.format(e)
message += '\nurl - {r.url}\nresponse status - {r.status_code}\nrequest headers - {r.request.headers}\nrequest body - {r.request.body}\nresponse headers - {r.headers}\nresponse body - {r.text}'.format(r=r)
raise AssertionError(message)
执行此代码时,我得到:
E AssertionError: TypeError raised! float argument required, not dict
E url - http://api4.qa.ebay.com/user/v1/watchlist/watch?listingStatus=BLARGLE&limit=25
E response status - 200
E request headers - {<good headers outputted as a dict>}
E request body - <good content here>
E response headers - {no problems}
E response body - {all my data was printed!}
【问题讨论】:
-
只是给
format的小费,你可以像'name: {me.name}, age {me.age}'.format(me=some_object)一样使用它。 -
您是否尝试过将其拆分为 5 个单独的
format调用来验证它是{headers}部分,而不是仅仅猜测? -
发布整个回溯是个好主意,以防您错过了我们发现的相关内容。
-
只是补充@abarnert 的观点:如何你知道究竟是什么引发了 TypeError?
-
好的,我看不出有任何方法可以从
str.format中获取float argument required, not dict。即使您明确使用了{headers:f},您也会得到non-empty format string passed to object.__format__(因为dict没有__format__的覆盖)。 (你会在 2.6 中得到一个稍微不同的错误,因为它会首先将 dict 转换为str,然后尝试改为f,但它仍然不是你要报告的那个。)
标签: python python-requests string.format