Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TypeError when calling isinstance on a TrameApp decorated object #594

Open
2 of 5 tasks
MattTheCuber opened this issue Sep 23, 2024 · 8 comments
Open
2 of 5 tasks

Comments

@MattTheCuber
Copy link

MattTheCuber commented Sep 23, 2024

Describe the bug

Using isinstance on a @TrameApp() decorated class throws a TypeError.

TypeError: isinstance() arg 2 must be a type, a tuple of types, or a union

To Reproduce

Steps to reproduce the behavior:

  1. Run the following code.

Code

from trame.decorators import TrameApp


@TrameApp()
class TestApp:
    server = None


t = TestApp()
print(isinstance(t, TestApp))

Expected behavior

I would assume isinstance would work. This is not a critical problem though as we have other workarounds.

The problem is that the @TrameApp() decorator returns a function that instantiates the class instead of returning a class itself. The TypeError is thrown because we are checking if a object is an instance of a function, which is not possible to check.

Maybe isinstance would never be a good way to handle this, either way it would be very useful to have a good way of checking the type of our app's instances.

Platform:

OS:

  • Windows
  • MacOS
  • Linux
  • Android
  • iOS
@jourdain
Copy link
Collaborator

That is a good issue but I'm not sure how to solve that... maybe by doing the following

from trame.decorators import TrameApp


class TestApp:
    server = None


t = TrameApp()(TestApp)()
print(isinstance(t, TestApp))

@MattTheCuber
Copy link
Author

That is a solution, although fairly hard to follow in practice

@jourdain
Copy link
Collaborator

yes, I agree and I'm not sure how to solve that.

@MattTheCuber
Copy link
Author

I asked Chat and it suggested creating a wrapper class with the decorator.

class TrameApp:
    def __call__(self, klass):
        class WrappedClass(klass):
            ...

        return WrappedClass

It could work, but then it could introduce other problems with type checking since type(t) would return WrappedClass instead of TestApp.

@psavery
Copy link
Collaborator

psavery commented Sep 23, 2024

We might be able to re-design the class a little bit to support this. I might look into it later this week.

@MattTheCuber
Copy link
Author

MattTheCuber commented Sep 23, 2024

I just found another issue that the function wrapper may be causing. Not quite sure why this is occuring though:

from trame.decorators import TrameApp


@TrameApp()
class TestApp:
    server = None


@TrameApp()
class TestApp2(TestApp):
    server = None


t = TestApp()
t2 = TestApp2()
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Cell In[2], line 10
      4 @TrameApp()
      5 class TestApp:
      6     server = None
      9 @TrameApp()
---> 10 class TestApp2(TestApp):
     11     server = None
     14 t = TestApp()

TypeError: function() argument 'code' must be code, not str

If this a separate problem, I can make a new issue. I will look into it more tomorrow probably.

@jourdain
Copy link
Collaborator

I think this is related because the decorated TestApp is actually a function and not a class which prevent you from inheriting it.

@MattTheCuber
Copy link
Author

Hey @psavery, I just wanted to check in on the status of this?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants