47

Why do I get this error? Can someone solve this problem for me? I tried to call the display function from class project in Progress.display() or anybody has other solution on how to display the users input?

And how can I input Stages class and Progress class at the same time ? thanks for the helpp

super().display()
RuntimeError: super(): no arguments

Here's the code

class Project:
    def __init__(self, name="", job="", **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.job = job

    def display():
        print("name: ", (self.name))
        print("job: ", (self.job))

    @staticmethod
    def prompt_init():
        return dict(name=input("name: "), job=input("job: "))


class Stages(Project):
    def __init__(self, stages="", **kwargs):
        super().__init__(**kwargs)
        self.stages = stages

    def display(self):
        super().display()
        print("stages: ", (self.stages))

    @staticmethod
    def prompt_init():
        parent_init = Project.prompt_init()

        choice = None
        while choice not in (1, 2, 3, 4, 5, 6):

            print("Insert your stage now: ")
            print("1. Planning")
            print("2. Analysis")
            print("3. Design")
            print("4. Implementation")
            print("5. Testing")
            print("6. Release")

            choice = input("enter your choice: ")
            choice = int(choice)

            if choice == 1:
                stages = "Planning"
            elif choice == 2:
                stages = "Analysis"
            elif choice == 3:
                stages = "Design"
            elif choice == 4:
                stages = "Implementation"
            elif choice == 5:
                stages = "Testing"
            elif choice == 6:
                stages = "Release"
            else:
                print("no such input, please try again")

            print(name)
            print(stages)


class Progress(Project):
    def __init__(self, progress="", **kwargs):
        super().__init__(**kwargs)
        self.progress = progress

    def display(self):
        super().display()
        print("progress: ", (self.progress))

    @staticmethod
    def prompt_init():
        parent_init = Project.prompt_init()

        choice = None
        while choice not in (1, 2, 3, 4):

            print("1. 25%")
            print("2. 50%")
            print("3. 75%")
            print("4. 100%")

            choice = input("enter your choice[1-4]: ")
            choice = int(choice)

            if choice == 1:
                progress = "25%"
            elif choice == 2:
                progress = "50%"
            elif choice == 3:
                progress = "75%"
            elif choice == 4:
                progress = "100%"
            else:
                print("no such input, please try again")

            print(progress)
        parent_init.update({"progress": progress})
        return parent_init


class A(Stages, Progress):
    def prompt_init():
        init = Stages.prompt_init()
        init.update(Progress.prompt_init())
        return init

    prompt_init = staticmethod(prompt_init)


class New:
    type_map = {("stages", "progress"): A}

    def add_project_test(self, name, job, stages):
        init_args = Project.prompt_init()
        self.project_list.append(Project(**init_args))

    def __init__(self):
        self.project_list = []

    def display_project():
        for project in self.project_list:
            project.display()
            print()

    def add_progress(self):
        init_args = Progress.prompt_init()
        self.project_list.append(Progress(**init_args))

    def add_project(self):
        ProjectClass = self.type_map[A]
        init_args = ProjectClass.prompt_init()
        self.property_list.append(ProjectClass(**init_args))


my_list = New()
my_list.add_progress()
my_list.display_project()
AKX
  • 152,115
  • 15
  • 115
  • 172
Justin Junias
  • 493
  • 2
  • 5
  • 9
  • 1
    Possible duplicate of [super() and @staticmethod interaction](https://stackoverflow.com/questions/26788214/super-and-staticmethod-interaction) – Green Cloak Guy Nov 27 '18 at 22:13
  • 4
    For anyone else who finds this problem and title, but this isn't the problem: did you perhaps try to call `super().__init__()` in the class itself rather than in a `def __init__(self):` method? The same error is raised. – Michael Scott Asato Cuthbert Dec 16 '20 at 23:10

4 Answers4

43

Not 100% solution to the question, but same error. Posted with love for Googlers who have the same issue as me.

Using Python 3, I got this error because I forgot to include self in the method. Simple thing, but sometimes the most simple things trip you up when you're tired.

class foo(object):
    def bar(*args):
        super().bar(*args)

=> RuntimeError: super(): no arguments

Remember to include your self

class foo(object):
    def bar(self, *args):
        super().bar(*args)
Kobato
  • 726
  • 1
  • 7
  • 15
38

Not really an answer for this question, but I got this same error when trying to call super while in a pdb shell and ended up going down a rabbit hole trying to figure it out. You need to add the parent class you want to call super on and self to the call in order for it to run - super(<ParentClass>, self) - in pdb. Or at least just know that super won't work as expected in pdb. I didn't really need to call it there, but it blocked me from figuring out why something else wasn't working.

Micah.Fay
  • 559
  • 6
  • 8
  • 5
    same for those using PyCharm (which runs pdb in the backend) – DankMasterDan Aug 31 '21 at 13:03
  • 2
    The same situation for users of VS code. – Gary Wang Mar 29 '22 at 10:00
  • +1 Pycharm. But why you wrote that it has to be `ParentClass`? It can be any class you wish to start method lookup. For people who have this issue, they are calling `super(the_Lowest_SubClass, self)`, not the parent class. – Rick Apr 28 '22 at 10:50
  • Someone told me that `super()` without arguments can only be used in class definition. Souce code is here https://github.com/python/cpython/blob/cd1fbbc81761dc26ce6daf724d57d48e965e5817/Objects/typeobject.c#L9060-L9061 . Though I don't understand much about the souce code. – Rick Apr 30 '22 at 04:06
30

Every time you use super() in a method, you need to be in an instance method or a class method. Your staticmethods don't know what their superclasses are. Observe:

class Funky:
    def groove(self):
        print("Smooth")

    @staticmethod
    def fail():
        print("Ouch!")

    @classmethod
    def wail(cls):
        print("Whee!")


class Donkey(Funky):
    def groove(self):
        print(super())

    @staticmethod
    def fail():
        try:
            print(super())
        except RuntimeError as e:
            print("Oh no! There was a problem with super!")
            print(e)

    @classmethod
    def wail(cls):
        print(super())


a_donkey = Donkey()
a_donkey.groove()
a_donkey.fail()
a_donkey.wail()

Outputs:

<super: <class 'Donkey'>, <Donkey object>>
Oh no! There was a problem with super!
super(): no arguments
<super: <class 'Donkey'>, <Donkey object>>

Here's your code, debugged and with some extra functionality and tests:

class Project:
    def __init__(self, name="", job="", **kwargs):
        super().__init__(**kwargs)
        self.name = name
        self.job = job

    def display(self):
        print("name: ", self.name)
        print("job: ", self.job)

    @staticmethod
    def prompt_init():
        return dict(name=input("name: "), job=input("job: "))


class Progress(Project):
    def __init__(self, progress="", **kwargs):
        super().__init__(**kwargs)
        self.progress = progress

    def display(self):
        super().display()
        print("progress: ", self.progress)

    @staticmethod
    def prompt_init():
        parent_init = Project.prompt_init()
        progress = input("your progress: ")
        parent_init.update({
            "progress": progress
        })
        return parent_init


class New:
    def __init__(self):
        self.project_list = []

    def display_project(self):
        for project in self.project_list:
            project.display()
            print()

    def add_project(self):
        init_args = Project.prompt_init()
        self.project_list.append(Project(**init_args))

    def add_progress(self):
        init_args = Progress.prompt_init()
        self.project_list.append(Progress(**init_args))


my_list = New()
my_list.add_project()
my_list.add_progress()
my_list.display_project()
Rob Bricheno
  • 4,467
  • 15
  • 29
  • thanks for the help friend ! really appreciate it, can I ask you one more thing ?? now there's Stages class other than Progress on my code. how can i input them at the same time ?? any idea? – Justin Junias Nov 27 '18 at 22:54
  • @JustinJunias are you sure that Stages is a class? Or is it maybe an attribute of a `Progress` class? Like, maybe `Progress` could have a variable like the existing `self.progress` and you could make a new method called `set_stage(a_stage)` (or `advance_stage()`) which updates `self.progress`? You probably also change `prompt_init` of `progress` to not take user input for the `progress` variable and instead always set the starting `progress` to "Added to system" or something. Just an idea :-) – Rob Bricheno Nov 27 '18 at 22:58
  • what does cls passed as an argument mean? – Golden Lion Apr 29 '22 at 18:27
  • 1
    @GoldenLion because we used the \@classmethod decorator, cls will contain the actual class object here. It's a lot like how in a normal (instance) method the first argument "self" is populated with the instance of the class, but in a class method (by convention, in this case PEP8) we use "cls" and is populated with the class itself. – Rob Bricheno May 01 '22 at 07:07
2

You might not have to use super() at all, just reference the super class directly. For example, I was writing a Django test like this one, but in my case the AnimalTestCase was inheriting a ParentTestCase. I wanted the fixture property in AnimalTestCase to use all the same fixtures in ParentTestCase, and add a couple more. But calling super() never worked. In the end, I realized that I could reference ParentTestCase as it was.

fixtures = ParentTestCase.fixtures + ['more']

class ParentTestCase(TestCase):
    fixtures = ['bacteria', 'fungus', 'stalagtites', 'stalagmites']

    def setUp(self):
        # Test definitions as before.
        call_setup_methods()


class AnimalTestCase(ParentTestCase):
    fixtures = ParentTestCase.fixtures + ['vertebrata', 'invertebrate']

    def test_fluffy_animals(self):
        # A test that uses the fixtures.
        call_some_test_code()
Joshua Swain
  • 571
  • 2
  • 4
  • 22