Skip to content
Newer
Older
100644 223 lines (181 sloc) 6.63 KB
b2cb30d @asweigart Updating pyperclip
authored
1 """
2 Pyperclip
3
4 A cross-platform clipboard module for Python. (only handles plain text for now)
5 By Al Sweigart al@inventwithpython.com
6 BSD License
7
8 Usage:
9 import pyperclip
10 pyperclip.copy('The text to be copied to the clipboard.')
11 spam = pyperclip.paste()
12
13 On Windows, no additional modules are needed.
14 On Mac, this module makes use of the pbcopy and pbpaste commands, which should come with the os.
15 On Linux, this module makes use of the xclip or xsel commands, which should come with the os. Otherwise run "sudo apt-get install xclip" or "sudo apt-get install xsel"
16 Otherwise on Linux, you will need the gtk or PyQt4 modules installed.
17
18 The gtk module is not available for Python 3, and this module does not work with PyGObject yet.
19 """
20
21 __version__ = '1.5.6'
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
22
23 import platform, os
b2cb30d @asweigart Updating pyperclip
authored
24 from subprocess import call, Popen, PIPE
25
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
26
b2cb30d @asweigart Updating pyperclip
authored
27 def _pasteWindows():
28 CF_UNICODETEXT = 13
29 d = ctypes.windll
30 d.user32.OpenClipboard(None)
31 handle = d.user32.GetClipboardData(CF_UNICODETEXT)
32 data = ctypes.c_wchar_p(handle).value
33 d.user32.CloseClipboard()
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
34 return data
35
b2cb30d @asweigart Updating pyperclip
authored
36
37 def _copyWindows(text):
38 GMEM_DDESHARE = 0x2000
39 CF_UNICODETEXT = 13
40 d = ctypes.windll # cdll expects 4 more bytes in user32.OpenClipboard(None)
41 try: # Python 2
42 if not isinstance(text, unicode):
43 text = text.decode('mbcs')
44 except NameError:
45 if not isinstance(text, str):
46 text = text.decode('mbcs')
47 d.user32.OpenClipboard(None)
48 d.user32.EmptyClipboard()
49 hCd = d.kernel32.GlobalAlloc(GMEM_DDESHARE, len(text.encode('utf-16-le')) + 2)
50 pchData = d.kernel32.GlobalLock(hCd)
51 ctypes.cdll.msvcrt.wcscpy(ctypes.c_wchar_p(pchData), text)
52 d.kernel32.GlobalUnlock(hCd)
53 d.user32.SetClipboardData(CF_UNICODETEXT, hCd)
54 d.user32.CloseClipboard()
55
56
57 def _pasteCygwin():
58 CF_UNICODETEXT = 13
59 d = ctypes.cdll
60 d.user32.OpenClipboard(None)
61 handle = d.user32.GetClipboardData(CF_UNICODETEXT)
62 data = ctypes.c_wchar_p(handle).value
63 d.user32.CloseClipboard()
64 return data
65
66
67 def _copyCygwin(text):
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
68 GMEM_DDESHARE = 0x2000
b2cb30d @asweigart Updating pyperclip
authored
69 CF_UNICODETEXT = 13
70 d = ctypes.cdll
71 try: # Python 2
72 if not isinstance(text, unicode):
73 text = text.decode('mbcs')
74 except NameError:
75 if not isinstance(text, str):
76 text = text.decode('mbcs')
77 d.user32.OpenClipboard(None)
78 d.user32.EmptyClipboard()
79 hCd = d.kernel32.GlobalAlloc(GMEM_DDESHARE, len(text.encode('utf-16-le')) + 2)
80 pchData = d.kernel32.GlobalLock(hCd)
81 ctypes.cdll.msvcrt.wcscpy(ctypes.c_wchar_p(pchData), text)
82 d.kernel32.GlobalUnlock(hCd)
83 d.user32.SetClipboardData(CF_UNICODETEXT, hCd)
84 d.user32.CloseClipboard()
85
86
87 def _copyOSX(text):
88 text = str(text)
89 p = Popen(['pbcopy', 'w'], stdin=PIPE)
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
90 try:
91 # works on Python 3 (bytes() requires an encoding)
b2cb30d @asweigart Updating pyperclip
authored
92 p.communicate(input=bytes(text, 'utf-8'))
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
93 except TypeError:
b2cb30d @asweigart Updating pyperclip
authored
94 # works on Python 2 (bytes() only takes one argument)
95 p.communicate(input=bytes(text))
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
96
97
b2cb30d @asweigart Updating pyperclip
authored
98 def _pasteOSX():
99 p = Popen(['pbpaste', 'r'], stdout=PIPE)
100 stdout, stderr = p.communicate()
101 return bytes.decode(stdout)
102
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
103
b2cb30d @asweigart Updating pyperclip
authored
104 def _pasteGtk():
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
105 return gtk.Clipboard().wait_for_text()
106
b2cb30d @asweigart Updating pyperclip
authored
107
108 def _copyGtk(text):
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
109 global cb
110 text = str(text)
111 cb = gtk.Clipboard()
112 cb.set_text(text)
113 cb.store()
114
b2cb30d @asweigart Updating pyperclip
authored
115
116 def _pasteQt():
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
117 return str(cb.text())
118
b2cb30d @asweigart Updating pyperclip
authored
119
120 def _copyQt(text):
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
121 text = str(text)
122 cb.setText(text)
123
124
b2cb30d @asweigart Updating pyperclip
authored
125 def _copyXclip(text):
126 p = Popen(['xclip', '-selection', 'c'], stdin=PIPE)
127 try:
128 # works on Python 3 (bytes() requires an encoding)
129 p.communicate(input=bytes(text, 'utf-8'))
130 except TypeError:
131 # works on Python 2 (bytes() only takes one argument)
132 p.communicate(input=bytes(text))
133
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
134
b2cb30d @asweigart Updating pyperclip
authored
135 def _pasteXclip():
136 p = Popen(['xclip', '-selection', 'c', '-o'], stdout=PIPE)
137 stdout, stderr = p.communicate()
138 return bytes.decode(stdout)
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
139
140
b2cb30d @asweigart Updating pyperclip
authored
141 def _copyXsel(text):
142 p = Popen(['xsel', '-i'], stdin=PIPE)
143 try:
144 # works on Python 3 (bytes() requires an encoding)
145 p.communicate(input=bytes(text, 'utf-8'))
146 except TypeError:
147 # works on Python 2 (bytes() only takes one argument)
148 p.communicate(input=bytes(text))
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
149
b2cb30d @asweigart Updating pyperclip
authored
150
151 def _pasteXsel():
152 p = Popen(['xsel', '-o'], stdout=PIPE)
153 stdout, stderr = p.communicate()
154 return bytes.decode(stdout)
155
156
157
158 # Determine the OS/platform and set the copy() and paste() functions accordingly.
159 if 'cygwin' in platform.system().lower():
160 _functions = 'Cygwin' # for debugging
161 import ctypes
162 paste = _pasteCygwin
163 copy = _copyCygwin
164 elif os.name == 'nt' or platform.system() == 'Windows':
165 _functions = 'Windows' # for debugging
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
166 import ctypes
b2cb30d @asweigart Updating pyperclip
authored
167 paste = _pasteWindows
168 copy = _copyWindows
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
169 elif os.name == 'mac' or platform.system() == 'Darwin':
b2cb30d @asweigart Updating pyperclip
authored
170 _functions = 'OS X pbcopy/pbpaste' # for debugging
171 paste = _pasteOSX
172 copy = _copyOSX
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
173 elif os.name == 'posix' or platform.system() == 'Linux':
b2cb30d @asweigart Updating pyperclip
authored
174 # Determine which command/module is installed, if any.
175 xclipExists = call(['which', 'xclip'],
176 stdout=PIPE, stderr=PIPE) == 0
177
178 xselExists = call(['which', 'xsel'],
179 stdout=PIPE, stderr=PIPE) == 0
180
181 gtkInstalled = False
182 try:
183 # Check it gtk is installed.
184 import gtk
185 gtkInstalled = True
186 except ImportError:
187 pass
188
189 if not gtkInstalled:
190 # Check if PyQt4 is installed.
191 PyQt4Installed = False
192 try:
193 import PyQt4.QtCore
194 import PyQt4.QtGui
195 PyQt4Installed = True
196 except ImportError:
197 pass
198
199 # Set one of the copy & paste functions.
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
200 if xclipExists:
b2cb30d @asweigart Updating pyperclip
authored
201 _functions = 'xclip command' # for debugging
202 paste = _pasteXclip
203 copy = _copyXclip
204 elif gtkInstalled:
205 _functions = 'gtk module' # for debugging
206 paste = _pasteGtk
207 copy = _copyGtk
208 elif PyQt4Installed:
209 _functions = 'PyQt4 module' # for debugging
210 app = PyQt4.QtGui.QApplication([])
211 cb = PyQt4.QtGui.QApplication.clipboard()
212 paste = _pasteQt
213 copy = _copyQt
214 elif xselExists:
215 # TODO: xsel doesn't seem to work on Raspberry Pi (my test Linux environment). Putting this as the last method tried.
216 _functions = 'xsel command' # for debugging
217 paste = _pasteXsel
218 copy = _copyXsel
fb8aa2e @asweigart Various changes. This completely breaks the unit tests, I know. I'll …
authored
219 else:
b2cb30d @asweigart Updating pyperclip
authored
220 raise Exception('Pyperclip requires the xclip or xsel application, or the gtk or PyQt4 module.')
221 else:
222 raise RuntimeError('pyperclip does not support your system.')
Something went wrong with that request. Please try again.