How to fix "TypeError" when printing my class object?

Python 3.11 on Windows 10 Pro in cmd.exe window.

I’m making an options class to hold all the option values from the command line when I run the program. When I need to pass options into a function I just pass the whole instance variable with all the options. I’m trying to make it easy to print the contents of my options class. But I get an error *** TypeError: __str__ returned non-string (type NoneType) in both my repr and str functions in my class.

And I don’t know how to debug into a class so I don’t know which line exactly is causing the problem. Here’s my class and the instance variable.

class clsOptions: # Command line options
    r'''
    This holds all command line options.
    '''
    def __init__(self):
        r'''These are class variables we need to use with initial values. '''
        self.deleteinv = False # Should we delete inventory?
        self.excelfile = '' # Input Excel filename
        self.exceltab = ''  # Excel tab to read from input filename. Case sensitive!
        self.isbnlist = []  # List of ISBNs from command line.
        self.overwrite = False # Should we overwrite any output files?
    def __repr__(self):
        # Usage: print(options)
        # Print boolean variables first, then strings, then lists.
        procname = str(inspect.stack()[0][3]) + ":"
        print(f"{procname} This holds command line options.")
        print(f"deleteinv={self.deleteinv}")
        print(f"overwrite={self.overwrite}")
        print(f"excelfile={self.excelfile}")
        print(f"exceltab={self.exceltab}")
        print(f"isbnlist={str(self.isbnlist)}")
        
    def __str__(self):
        print(f"This is __str__")
        
    def print(self):
        # Usage: options.print()
        pass
        # print(f"")
        
options = clsOptions()

In the debugger when I type

  1. p(options) it runs the repr class function.
  2. print(options) it runs the str function in my class.
  3. In both cases I get the same error but I’m not sure which line the error is in, in the class.

Thank you.

As the error messages say __str__ and __repr__ should return a string. You are not supposed to print inside of them. Instead, built up a string via concatenation of everything you would want to print and return that string.

You’re right. One tutorial on the web said to use print. But when I returned a string it works. Here’s what I have now.

class clsOptions: # Command line options
    r'''
    This holds all command line options.
    '''
    def __init__(self):
        r'''These are class variables we need to use 
        with initial values.'''
        self.deleteinv = False # Should we delete inventory?
        self.excelfile = '' # Input Excel filename
        self.exceltab = ''  # Excel tab to read from input filename. Case sensitive!
        self.isbnlist = []  # List of ISBNs from command line.
        self.overwrite = False # Should we overwrite any output files?
    def __repr__(self):
        r'''Usage: in debugger p(options)
        Print boolean variables first, then strings, then lists.
        '''
        procname = str(inspect.stack()[0][3]) + ":"
        s = f"{procname} This holds command line options."
        s = s + f"\ndeleteinv={self.deleteinv}"
        s = s + f"\noverwrite={self.overwrite}"
        s = s + f"\nexcelfile={self.excelfile}"
        s = s + f"\nexceltab={self.exceltab}"
        s = s + f"\nisbnlist={str(self.isbnlist)}"
        return s
        
    def __str__(self):
        r'''Used with print(options)'''
        s = f"This is __str__"
        s = s + f"\ndeleteinv={self.deleteinv}"
        s = s + f"\noverwrite={self.overwrite}"
        s = s + f"\nexcelfile={self.excelfile}"
        s = s + f"\nexceltab={self.exceltab}"
        s = s + f"\nisbnlist={str(self.isbnlist)}"
        return s
        
    def print(self):
        # Usage: options.print()
        pass
        # print(f"")
        
options = clsOptions()

The internet is a minefield of bad information sometimes.

It certainly is. If you’re already comfortable with what return and print respectively do (and the fact that they are not at all related), and you read a proper description of the methods you’re working with (for example, from the documentation), then it’s clear that the print advice is nonsense. That’s why it’s important to focus on fundamentals at the start, not just on specific tasks you want to be able to complete.