Q:

Smartly handle different permissions with inheritance

I have to manage permissions and I have different user types, as for
example a couple here.
def not_allowed(*args, **kwargs): return False

class User(object):
    def __init__(self, userid):
        self.userid = userid

    def __getattr__(self, attr):
        return not_allowed

    def view_profile(self)
        return True

class Admin(User):
    def edit_comment(self):
        return True

class Expert(User):
    def delete_post(self):
        return True

user = {'userid': 'user', 'roles': ['admin', 'expert']}

Now I want to be able to have MultiRole type, which in theory should
simply be able to do everything that its roles are able to do.
I tried with something like this:
class MultiRoleUser(User):
    """A multirole user has all the power of all the roles together
    """
    def __init__(self, userid, roles):
        super(MultiRoleUser, self).__init__(userid)
        self.roles = roles

    def __getattr__(self, attr):
        all_funcs = [getattr(x, attr) for x in self.roles]
        return any(x() for x in all_funcs)

Which should be used as
u = MultiRoleUser('userid', [Admin, Expert])

But it doesn't work, ideally I would like to call the methods for all
the classes passed in and do a or (with any).
The problem is that to call the methods I need to have an object of
that type..
In theory I might even just use a dictionary for each role instead,
but I liked the default to false trick which makes, and sometimes I
also need a function to compute the permission.
Any suggestions?

A:

Although I tend to agree that you probably don't want to reinvent the wheel on this, below is version of your attempt that appears to work AFAIK. 
Basically, I first I had switch to explicit new-style classes by making them derived from object so that the super() call would work, then second, I changed the self.roles = roles initialization in the MultiRoleUser class to create the instances needed. Lastly I changed how the MultiRoleUser.__getattr__()used them to handle role classes that didn't have the sought permission attribute.
def not_allowed(*args, **kwargs): return False

class User(object):
    def __init__(self, userid):
        self.userid = userid

    def __getattr__(self, attr):
        return not_allowed

    def view_profile(self):
        return True

class Admin(User):
    def edit_comment(self):
        return True

class Expert(User):
    def delete_post(self):
        return True

class MultiRoleUser(User):
    """A multirole user has all the power of all the roles together"""
    def __init__(self, userid, roles):
        super(MultiRoleUser, self).__init__(userid)
        self.roles = [role(userid) for role in roles] # create instances needed

    def __getattr__(self, attr):
        all_funcs = [getattr(x, attr, None) for x in self.roles]
        return any(x() for x in all_funcs if x) # check permission if there was one

u = MultiRoleUser('userid', [Admin, Expert])

print 'u.edit_comment:', u.edit_comment
print 'u.delete_post:', u.delete_post

BTW, I think a better Python implementation would use sets and operations with them to accomplish what you're trying to do.

