I wrote a simple wrapper class to manage an sqlite database connection. I learned from another StackOverflow answer how to use row_factory and recordclass so that the query results will return each row as an instance of dataclass. The dataclass is generated dynamically at runtime with a factory. import sqlite3 import recordclass class DBConnection: def __init__(self, file_path): self.connection = sqlite3.connect(file_path) self.connection.row_factory = self.make_row_factory( recordclass.make_dataclass, fast_new=True, ) self.cursor = self.connection.cursor() def make_row_factory(self, cls_factory, **kw): def row_factory(cursor, row, cls=[None]): rf = cls[0] if rf is None: fields = [col[0] for col in cursor.description] cls[0] = cls_factory("Row", fields, **kw) return cls[0](*row) return rf(*row) return row_factory def query(self, query: str): result = self.cursor.execute(query) return result.fetchall() How can I type hint the query method? def query(self, query: str) -> list[????] In this case the dataclass ends up being db.Row. You can’t type hint list[db.Row] because db.Row doesn’t exist until runtime. Putting hints on the make_row_factory and row_factory methods seems just as challenging. Continue reading...