The list of differences is quite long, and even though most of them are edge cases, it's not hard to get bitten by one on a project of any substantial size:
https://doc.pypy.org/cpython_differences.html
It's not that people are writing weird code, it's that you have a package that does something clever but safe, and then another package using it that calls it in a way that's unexpected but not documented as unsafe, and layers and layers of that compound until you have things like exceptions raised because non-string keys are getting set on type objects.
At the end of the day, Python isn't a terribly well-specified language. CPython behavior is functionally the specification. "Make it match CPython but faster" isn't really an option because it kills your ability to do a lot of the things that make PyPy fast. And if that was all it took, we wouldn't still be arguing over a JIT inside CPython. Pyston was an honest attempt at doing that, but it has been dead for years partially because it hit many of these walls.