Skip to content

Commit 412988e

Browse files
dvincentwestjreback
authored andcommitted
Update clipboard Qt-bindings for flexiblity and Python3 compatibility (#17723)
1 parent aaee541 commit 412988e

File tree

6 files changed

+42
-16
lines changed

6 files changed

+42
-16
lines changed

ci/requirements-3.6_BUILD_TEST.sh

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,4 +4,4 @@ source activate pandas
44

55
echo "install 36 BUILD_TEST"
66

7-
conda install -n pandas -c conda-forge pyarrow dask
7+
conda install -n pandas -c conda-forge pyarrow dask pyqt qtpy

doc/source/install.rst

+7-6
Original file line numberDiff line numberDiff line change
@@ -251,12 +251,13 @@ Optional Dependencies
251251
* `Jinja2 <http://jinja.pocoo.org/>`__: Template engine for conditional HTML formatting.
252252
* `s3fs <http://s3fs.readthedocs.io/>`__: necessary for Amazon S3 access (s3fs >= 0.0.7).
253253
* `blosc <https://pypi.python.org/pypi/blosc>`__: for msgpack compression using ``blosc``
254-
* One of `PyQt4
255-
<http://www.riverbankcomputing.com/software/pyqt/download>`__, `PySide
256-
<http://qt-project.org/wiki/Category:LanguageBindings::PySide>`__, `pygtk
257-
<http://www.pygtk.org/>`__, `xsel
258-
<http://www.vergenet.net/~conrad/software/xsel/>`__, or `xclip
259-
<https://github.com/astrand/xclip/>`__: necessary to use
254+
* One of
255+
`qtpy <https://github.com/spyder-ide/qtpy>`__ (requires PyQt or PySide),
256+
`PyQt5 <https://www.riverbankcomputing.com/software/pyqt/download5>`__,
257+
`PyQt4 <http://www.riverbankcomputing.com/software/pyqt/download>`__,
258+
`pygtk <http://www.pygtk.org/>`__,
259+
`xsel <http://www.vergenet.net/~conrad/software/xsel/>`__, or
260+
`xclip <https://github.com/astrand/xclip/>`__: necessary to use
260261
:func:`~pandas.read_clipboard`. Most package managers on Linux distributions will have ``xclip`` and/or ``xsel`` immediately available for installation.
261262
* For Google BigQuery I/O - see `here <https://pandas-gbq.readthedocs.io/en/latest/install.html#dependencies>`__
262263

doc/source/io.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -3053,7 +3053,7 @@ We can see that we got the same content back, which we had earlier written to th
30533053

30543054
.. note::
30553055

3056-
You may need to install xclip or xsel (with gtk or PyQt4 modules) on Linux to use these methods.
3056+
You may need to install xclip or xsel (with gtk, PyQt5, PyQt4 or qtpy) on Linux to use these methods.
30573057

30583058
.. _io.pickle:
30593059

doc/source/whatsnew/v0.22.0.txt

+1
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ Other Enhancements
4444
- :class:`pandas.io.formats.style.Styler` now has method ``hide_columns()`` to determine whether columns will be hidden in output (:issue:`14194`)
4545
- Improved wording of ``ValueError`` raised in :func:`to_datetime` when ``unit=`` is passed with a non-convertible value (:issue:`14350`)
4646
- :func:`Series.fillna` now accepts a Series or a dict as a ``value`` for a categorical dtype (:issue:`17033`)
47+
- :func:`pandas.read_clipboard` updated to use qtpy, falling back to PyQt5 and then PyQt4, adding compatibility with Python3 and multiple python-qt bindings (:issue:`17722`)
4748

4849
.. _whatsnew_0220.api_breaking:
4950

pandas/io/clipboard/__init__.py

+20-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,8 @@
1818
On Linux, install xclip or xsel via package manager. For example, in Debian:
1919
sudo apt-get install xclip
2020
21-
Otherwise on Linux, you will need the gtk or PyQt4 modules installed.
21+
Otherwise on Linux, you will need the gtk, qtpy or PyQt modules installed.
22+
qtpy also requires a python-qt-bindings module: PyQt4, PyQt5, PySide, PySide2
2223
2324
gtk and PyQt4 modules are not available for Python 3,
2425
and this module does not work with PyGObject yet.
@@ -34,9 +35,9 @@
3435
init_klipper_clipboard, init_no_clipboard)
3536
from .windows import init_windows_clipboard
3637

37-
# `import PyQt4` sys.exit()s if DISPLAY is not in the environment.
38+
# `import qtpy` sys.exit()s if DISPLAY is not in the environment.
3839
# Thus, we need to detect the presence of $DISPLAY manually
39-
# and not load PyQt4 if it is absent.
40+
# and not load qtpy if it is absent.
4041
HAS_DISPLAY = os.getenv("DISPLAY", False)
4142
CHECK_CMD = "where" if platform.system() == "Windows" else "which"
4243

@@ -68,9 +69,23 @@ def determine_clipboard():
6869
return init_gtk_clipboard()
6970

7071
try:
71-
# Check if PyQt4 is installed
72-
import PyQt4 # noqa
72+
# qtpy is a small abstraction layer that lets you write
73+
# applications using a single api call to either PyQt or PySide
74+
# https://pypi.python.org/pypi/QtPy
75+
import qtpy # noqa
7376
except ImportError:
77+
# If qtpy isn't installed, fall back on importing PyQt5, or PyQt5
78+
try:
79+
import PyQt5 # noqa
80+
except ImportError:
81+
try:
82+
import PyQt4 # noqa
83+
except ImportError:
84+
pass # fail fast for all non-ImportError exceptions.
85+
else:
86+
return init_qt_clipboard()
87+
else:
88+
return init_qt_clipboard()
7489
pass
7590
else:
7691
return init_qt_clipboard()

pandas/io/clipboard/clipboards.py

+12-3
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,19 @@ def paste_gtk():
4646

4747
def init_qt_clipboard():
4848
# $DISPLAY should exist
49-
from PyQt4.QtGui import QApplication
5049

51-
# use the global instance if it exists
52-
app = QApplication.instance() or QApplication([])
50+
# Try to import from qtpy, but if that fails try PyQt5 then PyQt4
51+
try:
52+
from qtpy.QtWidgets import QApplication
53+
except ImportError:
54+
try:
55+
from PyQt5.QtWidgets import QApplication
56+
except ImportError:
57+
from PyQt4.QtGui import QApplication
58+
59+
app = QApplication.instance()
60+
if app is None:
61+
app = QApplication([])
5362

5463
def copy_qt(text):
5564
cb = app.clipboard()

0 commit comments

Comments
 (0)