Não é o --context , mas o \s* no início do seu padrão de expressão regular.
Parece que ag não pesquisa linha por linha como o normal grep , mas olha o arquivo inteiro de uma só vez (ou pelo menos várias linhas por vez). Um pouco como este Perl one-liner seria:
perl -0777 -ne 'print "$&\n" while /^\s*(def|class)\s+[_A-Za-z]*/msg' ../prog.py
Portanto, como \s corresponde a qualquer espaço em branco, incluindo novas linhas, ele corresponde à linha vazia anterior, à nova linha, aos espaços à frente da próxima e, em seguida, à palavra-chave def . Se você adicionar uma linha vazia antes da linha blah , ela não será impressa, pois blah não se ajusta ao padrão.
Para se livrar da correspondência indesejada, use /^ *... ou /^[ \t]*... em vez de /^\s*... . (espaço + asterisco no primeiro)