Repository: beetbox/beets

Issue:
Broken pipe on piping `list` output on Python 3
### Problem

I'm trying to write a quick dirty script to play the first result of a search, looking much like you'd expect:

```sh
mpv --no-audio-display "$(beet ls -p $@ | head -n 1)"
```

However, there's something in the formatting of the output that `head` doesn't like:

```sh
$ beet ls -p home
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3
/media/beets/5 Seconds of Summer/LIVESOS/07 Long Way Home.mp3
/media/beets/5 Seconds of Summer/Sounds Good Feels Good/12 Broken Home.mp3
/media/beets/American Authors/What We Live For/07 Go Big or Go Home.mp3
/media/beets/Boys Like Girls/Crazy World/09 Take Me Home.mp3
...
```

However

```sh
beet -vv ls -p home | head -n 1                                                                                                                                                                   user configuration: /home/shagaru/.config/beets/config.yaml
data directory: /home/shagaru/.config/beets
plugin paths: 
Sending event: pluginload
library database: /media/Music/library.db
library directory: /media/Music
Sending event: library_opened
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

```

Trying to cheat and run it through `echo` instead produces the following:

```sh
$ echo -e $(beet ls -p home) | head -n 1
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3 /media/beets/5 Seconds of Summer/LIVESOS/07 Long Way Home.mp3 /media/beets/5 Seconds of Summer/Sounds Good Feels Good/12 Broken Home.mp3 /media/beets/American Authors/What We Live For/07 Go Big or Go Home.mp3 /media/beets/Boys Like Girls/Crazy World/09 Take Me Home.mp3 ...
```

as one string, so it seems like the proper line-ending characters aren't being properly generated. This may be expected of Python output, I don't know; I haven't written using it.

End question I suppose is there any way around how Python handles printing lines short of rewriting that entire part of the program?

### Setup

* OS: GNU/Linux
* Python version: 3.5.2
* beets version: 1.4.4
* Turning off plugins made problem go away (yes/no): no

My configuration (output of `beet config`) shouldn't matter, because it's a question of how the program functions inherently.
Broken pipe on piping `list` output on Python 3
### Problem

I'm trying to write a quick dirty script to play the first result of a search, looking much like you'd expect:

```sh
mpv --no-audio-display "$(beet ls -p $@ | head -n 1)"
```

However, there's something in the formatting of the output that `head` doesn't like:

```sh
$ beet ls -p home
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3
/media/beets/5 Seconds of Summer/LIVESOS/07 Long Way Home.mp3
/media/beets/5 Seconds of Summer/Sounds Good Feels Good/12 Broken Home.mp3
/media/beets/American Authors/What We Live For/07 Go Big or Go Home.mp3
/media/beets/Boys Like Girls/Crazy World/09 Take Me Home.mp3
...
```

However

```sh
beet -vv ls -p home | head -n 1                                                                                                                                                                   user configuration: /home/shagaru/.config/beets/config.yaml
data directory: /home/shagaru/.config/beets
plugin paths: 
Sending event: pluginload
library database: /media/Music/library.db
library directory: /media/Music
Sending event: library_opened
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

```

Trying to cheat and run it through `echo` instead produces the following:

```sh
$ echo -e $(beet ls -p home) | head -n 1
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3 /media/beets/5 Seconds of Summer/LIVESOS/07 Long Way Home.mp3 /media/beets/5 Seconds of Summer/Sounds Good Feels Good/12 Broken Home.mp3 /media/beets/American Authors/What We Live For/07 Go Big or Go Home.mp3 /media/beets/Boys Like Girls/Crazy World/09 Take Me Home.mp3 ...
```

as one string, so it seems like the proper line-ending characters aren't being properly generated. This may be expected of Python output, I don't know; I haven't written using it.

End question I suppose is there any way around how Python handles printing lines short of rewriting that entire part of the program?

### Setup

* OS: GNU/Linux
* Python version: 3.5.2
* beets version: 1.4.4
* Turning off plugins made problem go away (yes/no): no

My configuration (output of `beet config`) shouldn't matter, because it's a question of how the program functions inherently.
Broken pipe on piping `list` output on Python 3
### Problem

I'm trying to write a quick dirty script to play the first result of a search, looking much like you'd expect:

```sh
mpv --no-audio-display "$(beet ls -p $@ | head -n 1)"
```

However, there's something in the formatting of the output that `head` doesn't like:

```sh
$ beet ls -p home
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3
/media/beets/5 Seconds of Summer/LIVESOS/07 Long Way Home.mp3
/media/beets/5 Seconds of Summer/Sounds Good Feels Good/12 Broken Home.mp3
/media/beets/American Authors/What We Live For/07 Go Big or Go Home.mp3
/media/beets/Boys Like Girls/Crazy World/09 Take Me Home.mp3
...
```

However

```sh
beet -vv ls -p home | head -n 1                                                                                                                                                                   user configuration: /home/shagaru/.config/beets/config.yaml
data directory: /home/shagaru/.config/beets
plugin paths: 
Sending event: pluginload
library database: /media/Music/library.db
library directory: /media/Music
Sending event: library_opened
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3
Exception ignored in: <_io.TextIOWrapper name='<stdout>' mode='w' encoding='UTF-8'>
BrokenPipeError: [Errno 32] Broken pipe

```

Trying to cheat and run it through `echo` instead produces the following:

```sh
$ echo -e $(beet ls -p home) | head -n 1
/media/beets/5 Seconds of Summer/5 Seconds of Summer/09 Long Way Home.mp3 /media/beets/5 Seconds of Summer/LIVESOS/07 Long Way Home.mp3 /media/beets/5 Seconds of Summer/Sounds Good Feels Good/12 Broken Home.mp3 /media/beets/American Authors/What We Live For/07 Go Big or Go Home.mp3 /media/beets/Boys Like Girls/Crazy World/09 Take Me Home.mp3 ...
```

as one string, so it seems like the proper line-ending characters aren't being properly generated. This may be expected of Python output, I don't know; I haven't written using it.

End question I suppose is there any way around how Python handles printing lines short of rewriting that entire part of the program?

### Setup

* OS: GNU/Linux
* Python version: 3.5.2
* beets version: 1.4.4
* Turning off plugins made problem go away (yes/no): no

My configuration (output of `beet config`) shouldn't matter, because it's a question of how the program functions inherently.


Discussion:
Thank you! I can reproduce this, and it looks like it's a new problem on Python 3. We actually have a [specific exception handler](https://github.com/beetbox/beets/blob/6185c6ad4ba689ed438c2075699eb12b24ef5daf/beets/ui/__init__.py#L1276-L1279) for closed pipes on Python 2, but the same technique apparently doesn't work on Python 3. I don't fully understand what's going on with the "Exception ignored" mechanism… some further digging is required here.
Thank you! I can reproduce this, and it looks like it's a new problem on Python 3. We actually have a [specific exception handler](https://github.com/beetbox/beets/blob/6185c6ad4ba689ed438c2075699eb12b24ef5daf/beets/ui/__init__.py#L1276-L1279) for closed pipes on Python 2, but the same technique apparently doesn't work on Python 3. I don't fully understand what's going on with the "Exception ignored" mechanism… some further digging is required here.
Thank you! I can reproduce this, and it looks like it's a new problem on Python 3. We actually have a [specific exception handler](https://github.com/beetbox/beets/blob/6185c6ad4ba689ed438c2075699eb12b24ef5daf/beets/ui/__init__.py#L1276-L1279) for closed pipes on Python 2, but the same technique apparently doesn't work on Python 3. I don't fully understand what's going on with the "Exception ignored" mechanism… some further digging is required here.

Resolving patch:
diff --git a/beets/ui/__init__.py b/beets/ui/__init__.py
--- a/beets/ui/__init__.py
+++ b/beets/ui/__init__.py
@@ -1276,7 +1276,7 @@ def main(args=None):
     except IOError as exc:
         if exc.errno == errno.EPIPE:
             # "Broken pipe". End silently.
-            pass
+            sys.stderr.close()
         else:
             raise
     except KeyboardInterrupt:


Test patch: