I know it won’t make everyone happy, but I think we should ignore __replace__ for the purpose of variance even if it introduces a soundness hole. The current situation means that it’s impossible to get covariance for dataclasses or NamedTuples that hit this situation, even if you never use __replace__, and covariance is often very useful and convenient.
Type checkers that wish to plug the soundness hole here can warn about unsafe calls to __replace__ (or copy.replace).