18

I am having trouble with scripting bridge for python

I am trying to list the attributes of the iTunes object

iTunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")

using

>>> from pprint import pprint
>>> from Foundation import *
>>> from ScriptingBridge import *
>>> iTunes = SBApplication.applicationWithBundleIdentifier_("com.apple.iTunes")
>>> pprint (vars(iTunes))

I get back

Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute

anyone know how to get around this?

Ashley Hughes
  • 571
  • 1
  • 6
  • 18

4 Answers4

17

Try dir(iTunes). It's similar to vars, but more directly used with objects.

Ned Batchelder
  • 364,293
  • 75
  • 561
  • 662
  • 2
    @AshleyHughes It works in the sense that no exception is thrown, but it doesn't actually list everything available in these weird wrappings. For instance, there is no 'applicationWithBundleIdentifier_' in `dir(SBApplication)`. – mmgp Jan 19 '13 at 04:36
  • I just wanted to see what information I can see IE is something playing, which it doesn't support but trackName returns None so I'm using that – Ashley Hughes Jan 19 '13 at 04:45
  • Class methods for Cocoa aren't in dir(aClass) but in dir(type(aClass)). The reason for this is that a number of Cocoa classes have class methods with the same name as an instance method and because of this PyObjC makes class methods methods of the metaclass of the class (as opposed to classmethod objects in the class as is done for regular Python classes) – Ronald Oussoren May 17 '13 at 07:04
10

for something similar to vars(obj), when obj is not accessible as a dict, I use a kludge like this:

>>> obj = open('/tmp/test.tmp')
>>> print vars(obj)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: vars() argument must have __dict__ attribute
>>> print dict([attr, getattr(obj, attr)] for attr in dir(obj) if not attr.startswith('_'))

{'softspace': 0, 'encoding': None, 'flush': <built-in method flush of file object at 0xf7472b20>, 'readlines': <built-in method readlines of file object at 0xf7472b20>, 'xreadlines': <built-in method xreadlines of file object at 0xf7472b20>, 'close': <built-in method close of file object at 0xf7472b20>, 'seek': <built-in method seek of file object at 0xf7472b20>, 'newlines': None, 'errors': None, 'readinto': <built-in method readinto of file object at 0xf7472b20>, 'next': <method-wrapper 'next' of file object at 0xf7472b20>, 'write': <built-in method write of file object at 0xf7472b20>, 'closed': False, 'tell': <built-in method tell of file object at 0xf7472b20>, 'isatty': <built-in method isatty of file object at 0xf7472b20>, 'truncate': <built-in method truncate of file object at 0xf7472b20>, 'read': <built-in method read of file object at 0xf7472b20>, 'readline': <built-in method readline of file object at 0xf7472b20>, 'fileno': <built-in method fileno of file object at 0xf7472b20>, 'writelines': <built-in method writelines of file object at 0xf7472b20>, 'name': '/tmp/test.tmp', 'mode': 'r'}

I'm sure this could be improved upon, such as to filter out functions with if not callable(getattr(obj, attr):

>>> print dict([attr, getattr(obj, attr)] for attr in dir(obj) if not attr.startswith('_') and not callable(getattr(obj, attr)))
{'errors': None, 'name': '/tmp/test.tmp', 'encoding': None, 'softspace': 0, 'mode': 'r', 'closed': False, 'newlines': None}
jcomeau_ictx
  • 37,688
  • 6
  • 92
  • 107
0

This comes pretty late, but for a different problem (but the same error), the following worked for me:

json.dumps(your_variable)

Make sure you have imported JSON in your script before this.

import json

You will need to find a way to read JSON in a clean format.

Naveed Hasan
  • 641
  • 7
  • 19
  • this will not work for many objects, such as a Python file object. you get the error ```>>> json.dumps(f) Traceback (most recent call last): File "", line 1, in TypeError: is not JSON serializable``` – jcomeau_ictx Jul 05 '15 at 02:38
0
def dump(obj):
    if hasattr(obj, '__dict__'): 
        return vars(obj) 
    else:
        return {attr: getattr(obj, attr, None) for attr in obj.__slots__} 

Use instead of vars() :)

kolypto
  • 31,774
  • 17
  • 105
  • 99