Showing posts with label Python. Show all posts
Showing posts with label Python. Show all posts

Friday, October 26, 2012

How do you find where a python attribute "comes from"?

I work on a python project in the visual-effects industry called pymel, and someone recently asked me about the 'vtx' "attribute" on a mesh object - where it came from, and how they would find that out.  The answer is that it's added using the __getattr__ method on the Mesh class... but this got me thinking - is there a general way to find where a given attribute "comes from?"

When classes use tricks like __getattr__, it's hard to determine - standard methods like using dir or searching through the mro's __dict__ entries won't help.

The only way I could think of to find out it's from a __getattr__ would be to march up the mro chain, looking for __getattrs__, and testing them - to see if they return a result for the desired attribute, and at what point that result changes.

So, I wrote a function which does just that... and while it's at it, also checks the __dict__, __slots__, and __getattribute__.  It even does a last-ditch check to see if it's a c-compiled object. It's designed to generally tell you, "where the heck did this attribute come from"?
In order to get all (or at least, most) of the edge cases right, it ended up being way more complex than I'd originally imagined.. but it seems to get things right nearly all of the time. Hopefully it helps someone!

Thursday, July 9, 2009

Getting the type of OS

Just something that came up recently - how to use python to find what OS the user is running.

If you only need the general "type" of os (ie, Windows, Mac OSX, Linux), I've found the best solution is to use os.name first, as it's result is guaranteed to be one of only a few values, and then platform.system() to get finer grained results (ie, differentiate between OSX and *nix).

The problem with just using platform.system() is that it's return value isn't "guaranteed" be one of a few values, as the Python community learned when Vista was released. Whereas previous versions of Windows would return "Windows", Vista returns "Microsoft". While this may be considered a bug, it taught me that it's probably safest to just use os.name when possible, and only resort to other methods when this doesn't provide enough information.

Unfortunately, this is the case when trying to differentiate OSX and Unix/Linux - os.name returns 'posix' for both. So there, we resort to platform.system(), which will return 'Darwin' or 'Linux'.

Of course, you may need more fine-grained information, and there's other functions that can help with that - platform.uname(), platform.system_alias(), platform.uname(), maya.cmds.about() if Maya is initialized, etc.