Service __len__ not found Unexpected error, recovered safely
python3.8
My code:
from googleads import adwords def execute_request(): adwords_client = adwords.AdWordsClient.LoadFromStorage(path="google_general/googleads.yaml") campaign_service = adwords_client.GetService('CampaignService', version='v201809') pass context["dict_list"] = execute_request()
Traceback:
Traceback (most recent call last): File "/home/michael/pycharm-community-2019.3.2/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_xml.py", line 282, in frame_vars_to_xml xml += var_to_xml(v, str(k), evaluate_full_value=eval_full_val) File "/home/michael/pycharm-community-2019.3.2/plugins/python-ce/helpers/pydev/_pydevd_bundle/pydevd_xml.py", line 369, in var_to_xml elif hasattr(v, "__len__") and not is_string(v): File "/home/michael/PycharmProjects/ads3/venv/lib/python3.8/site-packages/googleads/common.py", line 694, in __getattr__ raise googleads.errors.GoogleAdsValueError('Service %s not found' % attr) googleads.errors.GoogleAdsValueError: Service __len__ not found Unexpected error, recovered safely.
googleads.yaml about logging
logging: version: 1 disable_existing_loggers: False formatters: default_fmt: format: ext://googleads.util.LOGGER_FORMAT handlers: default_handler: class: logging.StreamHandler formatter: default_fmt level: DEBUG loggers: # Configure root logger "": handlers: [default_handler] level: DEBUG
I've just started studying the API. Namely, I'm trying to execute my first request (https://developers.google.com/adwords/api/docs/guides/first-api-call#make_your_first_api_call)
Could you help me with this problem? At least how to localize it more precisely.
This seems to be a problem which results from the way the PyCharm debugger inspects live objects during debugging.
Specifically, it checks if a given object has the __len__ attribute/method in the code of var_to_xml, most likely to determine an appropriate representation of the object for the debugger interface (which seems to require constructing an XML representation).
googleads service objects such as your campaign_service, however, use some magic to be able to call the defined SOAP methods on them without requiring to hard-code all of them. The code looks like this:
def __getattr__(self, attr): """Support service.method() syntax.""" if self._WsdlHasMethod(attr): if attr not in self._method_proxies: self._method_proxies[attr] = self._CreateMethod(attr) return self._method_proxies[attr] else: raise googleads.errors.GoogleAdsValueError('Service %s not found' % attr)This means that the debugger's check for a potential __len__ attribute is intercepted, and because the CampaignService does not have a SOAP operation called __len__, an exception is raised.
You can validate this by running your snippet in the regular way (i.e. not debugging it) and checking if that works.
An actual fix would seem to either require that PyCharm's debugger changes the way it inspects objects (not calling hasattr(v, "__len__")) or that googleads modifies the way it implements __getattr__, for example by actually implementing a __len__ method that just raises AttributeError.
Hi, dorian. Thank you for your great answer. But what IDE do you recommend to use instead of PyCharm?
Corresponding ticket in PyCharm's bug tracker youtrack.jetbrains.com/issue/PY-39954 Workaround is to edit the debugger source code and wrap the problematic place with try/except till the next update youtrack.jetbrains.com/issue/…
@Michael, I use PyCharm myself. The fact that JetBrains cared enough to directly comment here validates that choice :)