This might not completely answer your question, but realize that that error message is Python accurately detecting an abrupt break in the pipe consuming the standard out from pip list, in this case just after the fifth line.
As is common with many programs, data comes out in two different streams: standard out (stdout) and standard error (stderr). Since you are at the terminal, you see both as text to the screen. The desired output (i.e., the "Package" and "Version" information) is streaming to the standard output while the error message is actually going to standard error.
If you did want to capture the standard output to a file (via the > redirect), that error message would still end up on the screen instead of in the file:
pip list | head -n5 > pip_list.txt
ERROR: Pipe to stdout was broken
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='utf-8'>
BrokenPipeError: [Errno 32] Broken pipe
You could get a similar list via pip freeze, which doesn't seem to complain when a pipe quits pulling information from it:
pip freeze | head -n5
attrs==21.2.0
Automat==20.2.0
Babel==2.8.0
bcrypt==3.2.0
blinker==1.4
Since pip freeze can be used to make a requirements.txt file, it may be closer to what you want anyway. Also, unlike pip list you don't have the two-line header that you might want to skip.
If you really really do want to use pip list but not get that error message, you could just redirect stderr to /dev/null (a virtual nowhere, a black hole) via the 2> redirect:
pip list 2> /dev/null | head -n5
Package Version
------------------ ----------------
attrs 21.2.0
Automat 20.2.0
Babel 2.8.0
head. As I know it would need to change Python code inpipto catchBrokenPipe