amolenaar / roles

Library for Role based development
BSD 3-Clause "New" or "Revised" License
57 stars 7 forks source link

RoleType conflict with SQLAlchemy #2

Closed showei closed 4 years ago

showei commented 8 years ago

Dear Arjan,

I'm trying to use roles 0.10 py3 branch together with Flask and SQLAlchemy. But when I apply a role(metaclass=RoleType) to a model(db.model), I got "TypeError: metaclass conflict".

I saw at roles/django.py you did something for Django, I tried it to SQLAlchemy but can't make it work. I'm wondering if you have some time, maybe you can help me with it a little bit. Some snippets and tracebacks:

from flask_sqlalchemy import SQLAlchemy
db = SQLAlchemy(app)
class User(db.model):
    def __init__(self, password):
        self.password = password
    def get_pass(self):
        return self.password

from roles import RoleType
class LoginVerifier(metaclass RoleType):
    def login_verify(self, target_pass):
        if self.get_pass() == target_pass:
            return True;

from roles.context import context
class LoginInteraction:
    def __init__(self, verifier):
        self.verifier = verifier
        self.login_context = context(self, verifier=LoginVerifier)

    def perform_login(self, target_pass):
        with self.login_context as ctx:
            if ctx.verifier.login_verify(target_pass):
                print("login succuss")

When I try to run:

user = User("abcd")
login = LoginInteraction(user)
login.perform_login("abcd")

I got:

File "login_test.py", line 18, in <module>
    login.perform_login("abcd")
  File "/[some path]/login_interaction.py", line 11, in perform_login
    with self.login_context as ctx:
  File "/[some path]/roles/roles/context.py", line 28, in __enter__
    role.assign(getattr(ctx, var))
  File "/[some path]/roles/roles/role.py", line 368, in assign
    rolecls = self.newclass(cls, rolebases)
  File "/[some path]/roles/roles/role.py", line 162, in wrapper
    cache[key] = result = func(*args)
  File "/[some path]/roles/roles/role.py", line 344, in newclass
    rolecls = type(self.newclassname(rolebases), rolebases, d)
TypeError: metaclass conflict: the metaclass of a derived class must be a (non-strict) subclass of the metaclasses of all its bases

Thank you in advance for your help!