  Gradual typing enables developers to annotate types of their own choosing,
offering a flexible middle ground between no type annotations and a fully
statically typed language. As more and more code bases get type-annotated,
static type checkers detect an increasingly large number of type errors.
Unfortunately, fixing these errors requires manual effort, hampering the
adoption of gradual typing in practice. This paper presents PyTy, an automated
program repair approach targeted at statically detectable type errors in
Python. The problem of repairing type errors deserves specific attention
because it exposes particular repair patterns, offers a warning message with
hints about where and how to apply a fix, and because gradual type checking
serves as an automatic way to validate fixes. We addresses this problem through
three contributions: (i) an empirical study that investigates how developers
fix Python type errors, showing a diverse set of fixing strategies with some
recurring patterns; (ii) an approach to automatically extract type error fixes,
which enables us to create a dataset of 2,766 error-fix pairs from 176 GitHub
repositories, named PyTyDefects; (iii) the first learning-based repair
technique for fixing type errors in Python. Motivated by the relative data
scarcity of the problem, the neural model at the core of PyTy is trained via
cross-lingual transfer learning. Our evaluation shows that PyTy offers fixes
for ten frequent categories of type errors, successfully addressing 85.4% of
281 real-world errors. This effectiveness outperforms state-of-the-art large
language models asked to repair type errors (by 2.1x) and complements a
previous technique aimed at type errors that manifest at runtime. Finally, 20
out of 30 pull requests with PyTy-suggested fixes have been merged by
developers, showing the usefulness of PyTy in practice.
