Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python 3.10 Type Hinting causes Syntax Error

I have defined two classes. A Bookshelf class and a Book class and have defined each with its own methods and type hints. When I run the below code in VS Code using python 3.10 it comes up with the following error:

class Bookshelf: 
SyntaxError: Invalid syntax

Which is referring to the init of the BookShelf class below. Can any of you spot the issue?

class Bookshelf:

    def __init__(self, books: list[Book]):
        self.books = books

    def __str__(self) -> str:
        return f"Bookshelf with {len(self.books)}"


class Book:
    def __init__(self, name: str, page_count: int):
        self.name=name
        self.page_count = page_count
like image 265
Machiavellie Avatar asked Oct 16 '25 00:10

Machiavellie


2 Answers

It is not a SyntaxError, It is a NameError because Book class is not defined yet when you are using it in your type hints.

1. First solution is moving the definition of Book class before the BookShelf.

2. Second solution is use the string instead of the book itself:

def __init__(self, books: list["Book"]):

I think in Python 3.11, They will allow to use it as it is. Evaluation of type annotations are gonna be postponed:

https://peps.python.org/pep-0563/

3. third solution: If you want to have this now, you can import:

from __future__ import annotations

then your code is going to work.

like image 156
SorousH Bakhtiary Avatar answered Oct 18 '25 14:10

SorousH Bakhtiary


Using the code in your question, I'm actually getting a NameError because Book is used in the type hint before it's defined. Moving the Book class above Bookshelf took care of it.

class Book:
    def __init__(self, name: str, page_count: int):
        self.name = name
        self.page_count = page_count


class Bookshelf:
    def __init__(self, books: list[Book]):
        self.books = books

    def __str__(self) -> str:
        return f"Bookshelf with {len(self.books)} books."

atlas = Book("Atlas", 100)
dictionary = Book("Dictionary", 1000)
print(atlas)
print(Bookshelf([atlas, dictionary]))

Output:

<__main__.Book object at 0x7f61af441fd0>
Bookshelf with 2 books.
like image 45
Tim Avatar answered Oct 18 '25 14:10

Tim



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!