After discussion with Google support, it appears that the behavior described above is expected. The virtual repository still collects the union of all the relevant versions across all upstreams, regardless of their priorities. The priority of the upstream repositories is only used to select a specific upstream when a specific version is available across multiple upstreams.
The implication is that with python virtual repositories, in order to ensure that a package will be installed from the private repo, it is necessary to use "==" as version specifier (and make sure that the specified version is indeed in the private repo, and that the private repo has the highest priority).