python - 使用来自 pytest 的 AdWordsClient 时出错 - 检测到递归(相同的本地人和位置)
问题描述
我需要编写一组测试来检查对 google AdWords API 的某些调用是否带来了正确的数据。
为此,我编写了一个生成 google 客户端的夹具方法:
@pytest.fixture
def google_client():
client = adwords.AdWordsClient.LoadFromStorage('tests/googleads.yaml')
client.cache = common.ZeepServiceProxy.NO_CACHE
return client
然后我有一个尝试连接到 Google API 的方法,但在此之前,就在尝试获取报告下载器时
def test_performance_report(google_client):
google_client.SetClientCustomerId(*****)
report_downloader = google_client.GetReportDownloader(version='v201809')
>
它与此堆栈跟踪中断:
tests/test_googleads_api.py:12:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
env/lib/python3.6/site-packages/googleads/adwords.py:478: in GetReportDownloader
return ReportDownloader(self, version, server)
env/lib/python3.6/site-packages/googleads/adwords.py:1321: in __init__
self.proxy_config, self._namespace, self._adwords_client.cache)
env/lib/python3.6/site-packages/googleads/common.py:821: in __init__
data = transport.load(endpoint)
env/lib/python3.6/site-packages/zeep/transports.py:110: in load
content = self._load_remote_data(url)
env/lib/python3.6/site-packages/zeep/transports.py:126: in _load_remote_data
response = self.session.get(url, timeout=self.load_timeout)
env/lib/python3.6/site-packages/requests/sessions.py:546: in get
return self.request('GET', url, **kwargs)
env/lib/python3.6/site-packages/requests/sessions.py:533: in request
resp = self.send(prep, **send_kwargs)
env/lib/python3.6/site-packages/requests/sessions.py:646: in send
r = adapter.send(request, **kwargs)
env/lib/python3.6/site-packages/requests/adapters.py:449: in send
timeout=timeout
env/lib/python3.6/site-packages/urllib3/connectionpool.py:600: in urlopen
chunked=chunked)
env/lib/python3.6/site-packages/urllib3/connectionpool.py:343: in _make_request
self._validate_conn(conn)
env/lib/python3.6/site-packages/urllib3/connectionpool.py:839: in _validate_conn
conn.connect()
env/lib/python3.6/site-packages/urllib3/connection.py:332: in connect
cert_reqs=resolve_cert_reqs(self.cert_reqs),
env/lib/python3.6/site-packages/urllib3/util/ssl_.py:281: in create_urllib3_context
context.options |= options
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py:465: in options
super(SSLContext, SSLContext).options.__set__(self, value)
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py:465: in options
super(SSLContext, SSLContext).options.__set__(self, value)
E RecursionError: maximum recursion depth exceeded
!!! Recursion detected (same locals & position)
只是要注意相同的代码在生产中有效,但是在测试中运行它时它会中断。我不明白出了什么问题,我会很感激任何帮助
我正在运行这个:
平台 darwin -- Python 3.6.7、pytest-4.3.0、py-1.7.0、pluggy-0.8.0 插件:flask-0.14.0、celery-4.2.0
调试:如果我从 python 控制台运行它,它可以工作,但是从测试它不会:
from requests.packages.urllib3.util.ssl_ import create_urllib3_context
create_urllib3_context()
print(ssl.SSLContext)
错误:
env/lib/python3.6/site-packages/urllib3/util/ssl_.py:281: in create_urllib3_context
context.options |= options
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py:465: in options
super(SSLContext, SSLContext).options.__set__(self, value)
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/ssl.py:465: in options
super(SSLContext, SSLContext).options.__set__(self, value)
E RecursionError: maximum recursion depth exceeded while calling a Python object
!!! Recursion detected (same locals & position)
谢谢!
更新 1 我补充说:
import eventlet
eventlet.monkey_patch()
在我的 conftest.py 中的任何其他内容之前,现在我收到此错误:
except OSError as err: # timeout error
> raise URLError(err)
E urllib.error.URLError: <urlopen error [SSL: CERTIFICATE_VERIFY_FAILED] certificate verify failed (_ssl.c:847)>
/Library/Frameworks/Python.framework/Versions/3.6/lib/python3.6/urllib/request.py:1320: URLError
更新 2 第二个问题是 Python OpenSSL 版本,我按照这篇文章的建议解决了它:
ssl.SSLError: [SSL: CERTIFICATE_VERIFY_FAILED] 证书验证失败 (_ssl.c:749)
解决方案
这看起来像本期中描述的gevent
和之间的不良交互requests
确保如果您正在使用gevent
它,您还可以在测试中对其进行修补——您的根目录conftest.py
是放置 gevent 修补代码的好地方:
from gevent import monkey
monkey.patch_all()
推荐阅读
- database - AWS DMS 复制任务交换使用问题
- java - 无法使用 Spring Cloud Contract Wiremock,无法加载 ApplicationContext
- javascript - JavaScript中如何在对象中返回promise的最佳方式?
- r - 在单独的列中添加每个因素的出现范围(数据框,R)
- python - Django 计算字段不会出现在 get_fields()
- java - Android Webiew 不加载索引的 Sdcard (file://sdcard)
- java - 如何使用 jmsra 配置 project-defaults.yml?
- python - 排除 IF 函数中的两列
- swift - 我可以从自定义视图类更改 NavigationController 设置吗
- swiftui - onTapGesture 与其他视图结合的 SwiftUI 错误或代码问题?