Problem with super()

I am having a problem with super().

As I understand it, this code is the correct pattern for single inheritance:

class V
    """ Docstring """
    
    def __init__(self, a, b):
        self.a = a
        self.b = b


class V2(V):
    """ Docstring """
    
    def __init__(a, b, c, d):
        super().__init__(a, b)
        self.c = c
        self.d = d

As far as I can see, my code follows the same pattern, just with more parameters.

class Star:
    """ Parent class, star data from RECONSNearest100 Stars """
    
    def __init__(self, nomen, idcodes, spectral, colour abs_mag, est_mass, num_obj, rect3, notes):
        """ The parameters are: 
            nomen, a string, the name of the star
            idcodes, a dictionary, designations from various star-catalogues
            spectral, a string, star's spectral class, like 'G2 V'
            colour, a 3-tuple, RGB values based on the spectral class
            abs_mag, a float, the magnitude calculated if the star were 10 parsecs away
            est_mass, a float, the star's mass expressed in solar masses, about 2 x 10^30 kg
            num_obj, a string, in the form '1+nP', given that the star has n planets
            rect3, a 3-tuple, XYZ rectangular coordinates relative to Sol
            notes, a string, interesting details not addressed elsewhere
        Now assign the variables:
        """
        
        self.nomen = nomen
        self.idcodes = idcodes
        self.spectral = spectral
        self.colour = colour
        self.abs_mag = abs_mag
        self.est_mass = est_mass
        self.num_obj = num_obj
        self.rect3 = rect3
        self.notes = notes
    
    def some_method(self, **args):
        # Do stuff here


class Steorra (Star):
    """ Derived class, data from RECONSNearest100, 
            massaged for game use:
            orbitnum, an int, orbits numbered from the center outwards
            mainworld, a string, the world's name, whether 'BL Ceti c' or something more exotic like "Shannon's World"
            sdate, a namedtuple, denoting the day and year
            avail, a list of lots, what the system has to sell when our ship comes calling
            mon_prod, a float, an abstract measure of productivity, from 0.0 for frontier 
                worlds to 15.0+ for more settled ones
            in_use, a flag, denoting whether the star system has been colonized yet.
    """
    
    def __init__(self, nomen, idcodes, spectral, colour abs_mag, est_mass, num_obj, rect3, notes,
                orbitnum, mainworld, sdate, avail, mon_prod, in_use):
        """ Make the star record into a Steorra record for game use """
        # First, initialize the parent's data
        super().__init__(nomen, idcodes, spectral, colour abs_mag, est_mass, num_obj, rect3, notes)
        # Now initialize the derived class's data
        self.orbitnum = orbitnum
        self.mainworld = mainworld
        self.sdate = sdate
        self.avail = avail
        self.mon_prod = mon_prod
        self.in_use = in_use
    
    def another_method(self, **args):
        # Do more stuff here

When I run this, I get a traceback:

          Star Traders

a game of interstellar commerce
version 0.7


instructions? n
all experts? y
custom game? n
How many players? 2
How many star-systems at the start? 15
How long is the game in years? 5
How many tonnes of cargo can a ship carry? 25
line #1: Star('Sol', Idcodes('SUN', '--',  'Sol'), 'G2.0 V', Colour(255, 255, 0), 4.85, 1, '1+8P', Rect3(0.0, -0.0, 0.0), '8 planets')
  
star: Star(nomen='Sol', idcodes=Idcodes(GJ='SUN', LHS='--', other='Sol'), spectral='G2.0 V', colour=Colour(red=255, green=255, blue=0), abs_mag=4.85, est_mass=1, num_obj='1+8P', rect3=Rect3(x=0.0, y=-0.0, z=0.0), notes='8 planets')
Sol G2.0 V
Traceback (most recent call last):
  File "E:\Binaries\Python311\Scripts\startraders\startrader_new.py", line 1540, in 
    trader_setup(ST)
  File "E:\Binaries\Python311\Scripts\startraders\startrader_new.py", line 699, in trader_setup
    setup_cosmos(num_stars, _starfile)
  File "E:\Binaries\Python311\Scripts\startraders\startrader_new.py", line 618, in setup_cosmos
    steorra = Steorra(nomen, idcodes, spectral, colour, abs_mag, est_mass, num_obj, rect3, note, orbitnum, mainworld, sdate, avail, mon_prod, in_use)
TypeError: Star.__new__() takes 10 positional arguments but 16 were given

Where is the fatal difference?

Here is the function which is called to fill the stars list:

def setup_cosmos(starcount, _starfile='starfile_001.dat'):
    """ Read in values from starfile, to populate the starmap. 
    """
    
    def init_starports():
        """ Initialize the starports with special standing, then initialize all the rrest.
        """
        global stars
        stars[0] = stars[0]._replace(mon_prod=15.0)    # Sol is cosmopolitan
        stars[0] = stars[0]._replace(orbitnum=3,mainworld='Sol c')
        stars[1] = stars[1]._replace(mon_prod=7.5)    # Proxima
        stars[2] = stars[2]._replace(mon_prod=10.0)    # alpha Cen A
        # TODO: write in real exoplanet data!
        for sx in range(3, num_stars):
            u = D3g()-1    # D3g() returns 1 more often: 111223 => 000112
            stars[sx] = stars[sx]._replace(mon_prod=(u*5.0 + D4g()))
            #. end for
        for star in stars:
            star = star._replace(avail=[None]*10)
            #. end for
        return None
    
    global stars
    with open(_starfile, 'r') as starcat:
        num = 0
        for lin in starcat.readlines():
            if lin[0] == '#':
                num += 1
                continue    # Ignore comment lines
            # Unpack the star data
            print("line #{0}: {1}  ".format(num, lin))
            star = eval(lin)
            print(f'star: {star}')
            nomen, idcodes, spectral, colour, abs_mag, est_mass, num_obj, rect3, note = star
            print(nomen, spectral)
            # Make the new Steorra object
            orbitnum = random.randint(1,3) + 2
            mainworld = nomen + ' ' + chr(orbitnum + 96) # eg., BL Ceti c
            sdate = Datei(1, START_YEAR)
            avail = []
            mon_prod = 0.0    
            in_use = False if num > starcount else True
            steorra = Steorra(nomen, idcodes, spectral, colour, abs_mag, est_mass, num_obj, rect3, note, orbitnum, mainworld, sdate, avail, mon_prod, in_use)
            stars.append(steorra)
            num += 1
            if num > starcount:
                break
            #. end for
        starcat.close()
    init_starports()    # Special handling for Sol and a few other starports.
    return None
    #. end def

Any advice would be appreciated. Thanks.

It’s a bit hard to parse all the code (thank you formatting it though!), but I’ll just point out you’re missing a comma in your signatures here, between colour and abs_mag.

I assume that’s not a problem in the real code because it’s a syntax error.

self has been omitted in the call signature of V2.__init__

Perhaps this causes the super call to use whatever the parent class of a’s class is, if that’s Star (instead of V) and give the strange 14 / 10 args error

That code isn’t the code they are debugging.

Well if that really is “as they understand it”, then they misunderstand it

I guess it can be viewed as a symptom on the underlying problem: we aren’t looking at the real code that ran–per my comment about the syntax error, the code in this post wouldn’t run at all.

I don’t see what’s going wrong but it seems likely the problem isn’t in this example.

1 Like

Your Star class has an explicit __new__ method defined for some reason, probably instead of __init__, but for that we would have to see the actual code you are trying to run. Your Sterorra subclass should therefore also implement __new__.

2 Likes

Well, the error message tells us:

There is no Star.__new__ shown in the post, but there presumably is one in your actual code. That, in turn, will cause a problem.