Why does the addition of noise improve coherence between two signals? Taking a simple example of the coherence between two signals, each composed of two sinusoids of frequency 100 and 200 Hz, I expect the coherence to show two peaks in the spectrum located at precisely these two frequencies. The script below can be used to study the effect of adding noise An =0.1 or no noise An = 0. before taking the coherence. This produces in the case of added noise 

and in the case of no noise 

It is clear that with no noise there are many false peaks in coherence. 

Question: Can someone show me mathematically speaking why this is the case?

import numpy as np
import matplotlib.pyplot as plt
from scipy import signal

t0, t1 = 0, 2.
fs = 2000
dt = 1./fs
t = np.arange(t0,t1-dt,dt)

#f1, f2 = 50, 50
#x1 = np.sin(2*np.pi*f1*t)
#x2 = np.sin(2*np.pi*f2*t+2*np.pi*0.)

An = 0.1            # Noise amplitude
f1, f2 = 100, 200   # Signal frequencies
p1, p2 = 0.25, 0.5  # Phase shifts (times pi)

x1 = np.cos(2*np.pi*f1*t) + np.sin(2*np.pi*f2*t) + An*np.random.randn(len(t));
x2 = 0.5*np.cos(2*np.pi*f1*t-np.pi*p1) + 0.35*np.sin(2*np.pi*f2*t-np.pi*p2) + An*np.random.randn(len(t));

fcoh, coh = signal.coherence(x1, x2, fs, window='hamming', nperseg=400, noverlap=0)

fig2, ax2 = plt.subplots(1,1)
ax2.plot(fcoh, coh**2,"k-")
ax2.set_ylim([-0.1,1.1])
ax2.set_xlabel(r"$f$ [Hz]")
ax2.set_ylabel(r"Coherence")
ax2.grid("on")
To elaborate on @user28715's answer:
Even with a minuscule amount of noise say An = 0.0000001 you will get a clean graph like your first graph. Python's implementation of the Welch method certainly uses finite-precision floating point numbers and quantization errors in the input and from the calculation steps such as windowing and Fast Fourier Transform (FFT) propagate to the results. From SciPy docs:

Cxy = abs(Pxy)**2/(Pxx*Pyy), where Pxx and Pyy are power spectral
density estimates of X and Y, and Pxy is the cross spectral density
estimate of X and Y.

The normalizing division in the equation means that the values of Pxx and Pyy can be arbitrarily close to 0 while still giving large Cxy.