1

I have a BaseHandler class that subclasses the Tipfy RequestHandler in my AppEngine site. In it, I have setup a "poor man's" browser sniffer for mobile devices with a class attribute (a tuple) containing device names.

In a subsequent method, I loop through the device names in the tuple and check them against the user agent string from the Request object. If I get a match, I set an instance attribute called "is_mobile" to True.

In that method, however, Python is giving me a "TypeError: argument of type 'UserAgent' is not iterable" error, and I can't understand why, since the line it is complaining about is not (as far as I understand) a loop.

Here is the code:

class BaseHandler(RequestHandler, AppEngineAuthMixin, AllSessionMixins):

    mobile_devices = ('Android', 'iPhone', 'iPod', 'Blackberry')

    ....

    def detect_mobile_devices(self):
        found_device = False

        for device in self.__class__.mobile_devices:
            if device in self.request.user_agent:
                found_device = True
                break

        self.is_mobile = found_device

Here is the line Python does not like:

File "/path/to/project/app/apps/remember_things/handlers.py", line 56, in detect_mobile_devices
if device in self.request.user_agent:
tommytwoeyes
  • 483
  • 5
  • 19

1 Answers1

5

The expression

device in self.request.user_agent

will first try to call

self.request.user_agent.__contains__(device)

If this method does not exist, Python tries to iterate over self.request.user_agent and compares each item it encounters to device. Obviously, the type of self.request.user_agent neither allows .__contains__() nor iteration, hence the error message.

Also see the documentation of membership test in Python.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841