The solution I found was to use an alias & subquery.
with _Session() as s:
stmt = select(Student.latest_exams).join(Student).where(Student.name=='Joe Bloggs')
exam_alias = aliased(Exam, stmt.subquery())
results = s.execute(select(exam_alias))