Frankly, this is a mess. Code 2 should not be used for --install-types or blocking errors IMO - 2 is de-facto standard for "please do not invoke me like this". "Run again" and "invalid syntax" have so little in common that I struggle to understand the reason to combine them under one code.
Originally posted by @sterliakov in #19548
It would probably be acceptable to pick whatever we want to be the exit code --install-types gives when mypy needs to be re-run afterwards, but 3 seems a good choice.