Update clipboard Qt-bindings for flexiblity and Python3 compatibility
State: closed

This should prevent any conflicts with other qt-bindings packages when embedding pandas in a Qt-based gui and should also provide compatibility with Python3 since PyQt4 may not be available for the latest releases.

- [ ] closes #17722



Labels:
name: IO Data
description: IO issues that don't fit into a more specific label
name: Compat
description: pandas objects compatability with Numpy or Python functions

Comments:
# [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=h1) Report
> Merging [#17723](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=desc) into [master](https://codecov.io/gh/pandas-dev/pandas/commit/e6eac0b308af9869ee123caa8c256bd8a7cc126b?src=pr&el=desc) will **decrease** coverage by `0.05%`.
> The diff coverage is `60%`.

[![Impacted file tree graph](https://codecov.io/gh/pandas-dev/pandas/pull/17723/graphs/tree.svg?token=eZ4WkYLtcO&src=pr&width=650&height=150)](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree)

```diff
@@            Coverage Diff             @@
##           master   #17723      +/-   ##
==========================================
- Coverage   91.35%   91.29%   -0.06%     
==========================================
  Files         163      164       +1     
  Lines       49695    49747      +52     
==========================================
+ Hits        45401    45419      +18     
- Misses       4294     4328      +34
```

| Flag | Coverage Δ | |
|---|---|---|
| #multiple | `89.09% <60%> (-0.05%)` | :arrow_down: |
| #single | `40.48% <60%> (+0.75%)` | :arrow_up: |

| [Impacted Files](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree) | Coverage Δ | |
|---|---|---|
| [pandas/io/clipboard/\_\_init\_\_.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL2lvL2NsaXBib2FyZC9fX2luaXRfXy5weQ==) | `56.86% <40%> (-19.33%)` | :arrow_down: |
| [pandas/io/clipboard/clipboards.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL2lvL2NsaXBib2FyZC9jbGlwYm9hcmRzLnB5) | `32.18% <80%> (+8.13%)` | :arrow_up: |
| [pandas/io/gbq.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL2lvL2dicS5weQ==) | `25% <0%> (-58.34%)` | :arrow_down: |
| [pandas/plotting/\_converter.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL3Bsb3R0aW5nL19jb252ZXJ0ZXIucHk=) | `63.44% <0%> (-1.82%)` | :arrow_down: |
| [pandas/tseries/offsets.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL3RzZXJpZXMvb2Zmc2V0cy5weQ==) | `96.7% <0%> (-0.31%)` | :arrow_down: |
| [pandas/core/resample.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvcmVzYW1wbGUucHk=) | `96.16% <0%> (-0.19%)` | :arrow_down: |
| [pandas/core/dtypes/missing.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvZHR5cGVzL21pc3NpbmcucHk=) | `90.62% <0%> (-0.12%)` | :arrow_down: |
| [pandas/core/indexes/datetimes.py](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree#diff-cGFuZGFzL2NvcmUvaW5kZXhlcy9kYXRldGltZXMucHk=) | `95.39% <0%> (-0.11%)` | :arrow_down: |
| ... and [16 more](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=tree-more) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=continue).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=footer). Last update [e6eac0b...53ee4bc](https://codecov.io/gh/pandas-dev/pandas/pull/17723?src=pr&el=lastupdated). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments).

Should update `io.rst` too. 
I will make all these updates within a couple of days 
@asweigart just pushed some commits to pyperclip, more than I was tackling here, but I reverted the code to his latest commits regarding this issue.  Behavior now is to import qtpy, then PyQt5 if that fails, then PyQt4 if that fails.  Should not break for anyone who was using this functionality previously.  Documentation was also updated as requested.  I am waiting for CI checks to pass, and will check back to make sure that they do
switched to vim key-binding recently, getting used to it, but it throws me
off once in awhile.  I added it back

On Mon, Oct 30, 2017 at 7:50 AM, Jeff Reback <notifications@github.com>
wrote:

> *@jreback* commented on this pull request.
> ------------------------------
>
> In pandas/io/clipboard/clipboards.py
> <https://github.com/pandas-dev/pandas/pull/17723#discussion_r147692402>:
>
> >
>      def copy_qt(text):
>          cb = app.clipboard()
>          cb.setText(text)
>
> -    def paste_qt():
>
> why did you remove this?
>
> —
> You are receiving this because you authored the thread.
> Reply to this email directly, view it on GitHub
> <https://github.com/pandas-dev/pandas/pull/17723#pullrequestreview-72822092>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AJaj13JjJSeVHQUuXG77-5w_ne_G-GCzks5sxcX8gaJpZM4PpDks>
> .
>

it appears I violated style standards with 2 greater than 80 character lines.  I should have read the contribution documentation more carefully.  Apologies, I will review that, fix the lines, and update.
ideally would like to enhance 1 or more of our CI builds to use qtpy. Some of them are already testing  via xsel/python-gtk2. they are a bit flaky though. can you add in pyqt to a couple of builds (that don't otherwise add the x selections).  the clipboard tests themselves exercise this.
@jreback, I've never done that, but in the spirit of learning I will try, but will be careful before making any changes.  On a second note, the last round of tests failed because ModuleNotFoundError was not recognized as a valid exception.  Why is that?  I changed the exception to be ImportError instead, which is valid and should work, but I was wondering why the error with ModuleNotFoundError.
> ModuleNotFoundError
is python3 only. ImportError will be raised for py2
I'm coming here from spyder-ide/spyder#5795. This problem is also generating odd errors for us in Spyder, so I want to chime in to see when this is going to be merged and if there's something I can do to help with.

@jreback and @TomAugspurger, I think Pandas should depend directly on `qtpy`. `qtpy` is a tiny dependency and it would make the code added by @dvincentwest (which looks right to me) very, very simple, instead of a lot of try/excepts (which are already done in `qtpy` itself).

Besides, it would be easier to handle future renames or changes in Qt by depending on `qtpy` because `qtpy` will take care of them.
Thanks.

I don't think adding qtpy as a dependency is worthwhile, since `read_clipiboard` isn't a core part of pandas.

@dvincentwest could you add a release note? I think in `doc/source/whatsnew/v0.22.0.txt`. Other than that, the changes here look good.
does installing ``qtpy`` actually installing a pyqt binding? e.g the ``qt`` package?

No, qtpy is only a compatibility later so that you can write bindings agnostic applications. It still requires either Pyqt(4 or 5) or Pyside(1 or 2)
> No, qtpy is only a compatibility later so that you can write bindings agnostic applications. It still requires either Pyqt(4 or 5) or Pyside(1 or 2)

ok can you make that clear in the install.rst instructions. also do add to one of the ci builds.
yes, I will try to get this done tomorrow...
@jreback @TomAugspurger , the Python 2.7 appveyor build appears to have gone over the 1 hour time-limit.  I am not sure why, and I don't really know what to do about that next.

I did add pyqt (conda label for PyQt5) and qtpy to the `ci/requirements-3.6_BUILD_TEST.sh` script but I have never dealt with CI before so I think you should have a quick look to make sure I did what you were looking for.
thanks @dvincentwest 
And my thanks to you guys for maintaining the project