Are the 'bugs' actually triggered in the real-world usage of the code, or are they just 'potential bugs' which would be triggered given specific inputs that don't happen in the current usage of the code?
Might seem like nitpicking, but the 'probability of a bug being triggered in the future' is an important metric for figuring out if large scale refactorings are actually worth the risk of introducing new bugs.
Disclaimer: I'm coming from the static typing hemisphere, but adding type information to a codebase that was originally written with runtime-duck-typing in mind sounds like it might actually make maintainability of the code worse - that's at least my experience after trying to do exactly this in a medium-sized Python codebase - some of the 'typings' ended up so complex and weird that they completely dominated the code and turned what was very simple code at the beginning into an unreadable mess (looking almost like C++ template code). I eventually rolled back the changes. Basically, if I wanted a statically typed language, I wouldn't have chosen Python in the first place for this type of project.
Might seem like nitpicking, but the 'probability of a bug being triggered in the future' is an important metric for figuring out if large scale refactorings are actually worth the risk of introducing new bugs.
Disclaimer: I'm coming from the static typing hemisphere, but adding type information to a codebase that was originally written with runtime-duck-typing in mind sounds like it might actually make maintainability of the code worse - that's at least my experience after trying to do exactly this in a medium-sized Python codebase - some of the 'typings' ended up so complex and weird that they completely dominated the code and turned what was very simple code at the beginning into an unreadable mess (looking almost like C++ template code). I eventually rolled back the changes. Basically, if I wanted a statically typed language, I wouldn't have chosen Python in the first place for this type of project.