3

Hi

I have some code on my CI failing (local runs do not fail). The problem is that class instance fails isinstance() check.

Code:

File: main.py

class MyController(SuperController):
    # Overrides default definition of get_variables_context()
    from my_options import get_variables_context

File: my_options.py

...
def get_variables_context(self: SuperController, **kwargs):
    from main import MyController
    self: MyController

    print(f"type(self) is {type(self)} (it {'IS' if (isinstance(self, MyController)) else 'IS NOT'} a subclass of MyController)")
    _super = super(MyController, self).get_variables_context(**kwargs) or dict()
    _super.update(result)
    return _super

Got output and error:

type(self) is <class '__main__.SomeController'> (it IS NOT a subclass of SomeController
Traceback (most recent call last):
  File "main.py", line 24, in <module>
    SomeController.main(**params)
  File "/builds/RND/my/rcv-nginx/tests/nginx_tests/flow.py", line 391, in main
    _tests_suite, _, _ = self.prepare()
  File "/builds/RND/my/rcv-nginx/tests/nginx_tests/flow.py", line 359, in prepare
    context['variables_context'] = self.get_variables_context(**context)
  File "/builds/RND/my/tests/integration/my_options.py", line 81, in get_variables_context
    _super = super(SomeController, self).get_variables_context(**kwargs) or dict()
TypeError: super(type, obj): obj must be an instance or subtype of type
Peter Zaitcev
  • 316
  • 1
  • 14

1 Answers1

4

I've found the solution while investigating the root cause.

In the local run, ...

I actually call the python unittest which then calls main.py which then creates a class MyController which then calls my_options.py, and the class is added to the loaded module 'main'. Then, MyController.get_variables_context asks for the module 'main', which is already loaded, then for the class MyController in that module, so the same type instance is returned and type check succeeds.

In the CI run, ...

I call directly main.py with the argument "test" (which should create a controller and run all tests from it via unittest), so the class MyController is created inside module __main__. MyController.get_variables_context still asks for the MyController class in main.py, but the module 'main' is not loaded here, so python loads it, creates new class MyController, and then returns it.

So, basically the answer is ...

to move MyController from main.py to the other file, i.e. controller.py

Peter Zaitcev
  • 316
  • 1
  • 14
  • This is not a blog. – shaik moeed Jul 18 '19 at 15:11
  • 1
    Actually, I was going to post the question but found the answer while writing it – Peter Zaitcev Jul 18 '19 at 15:18
  • 7
    @shaikmoeed Self-answered questions are encouraged, especially if the OP takes care to actually frame it as a question and an answer to that question. I've seen "questions" that literally just dump some information, with no answer (self or otherwise) provided or expected. – chepner Jul 18 '19 at 15:56