Coverage for /pythoncovmergedfiles/medio/medio/usr/local/lib/python3.11/site-packages/pandas/io/clipboards.py: 93%
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
Shortcuts on this page
r m x toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1"""io on the clipboard"""
3from __future__ import annotations
5from io import StringIO
6from typing import TYPE_CHECKING
7import warnings
9from pandas._libs import lib
10from pandas.util._decorators import set_module
11from pandas.util._exceptions import find_stack_level
12from pandas.util._validators import check_dtype_backend
14from pandas.core.dtypes.generic import ABCDataFrame
16from pandas import (
17 get_option,
18 option_context,
19)
21if TYPE_CHECKING:
22 from pandas._typing import DtypeBackend
25@set_module("pandas")
26def read_clipboard(
27 sep: str = r"\s+",
28 dtype_backend: DtypeBackend | lib.NoDefault = lib.no_default,
29 **kwargs,
30): # pragma: no cover
31 r"""
32 Read text from clipboard and pass to :func:`~pandas.read_csv`.
34 Parses clipboard contents similar to how CSV files are parsed
35 using :func:`~pandas.read_csv`.
37 Parameters
38 ----------
39 sep : str, default '\\s+'
40 A string or regex delimiter. The default of ``'\\s+'`` denotes
41 one or more whitespace characters.
43 dtype_backend : {'numpy_nullable', 'pyarrow'}
44 Back-end data type applied to the resultant :class:`DataFrame`
45 (still experimental). If not specified, the default behavior
46 is to not use nullable data types. If specified, the behavior
47 is as follows:
49 * ``"numpy_nullable"``: returns nullable-dtype-backed :class:`DataFrame`
50 * ``"pyarrow"``: returns pyarrow-backed nullable
51 :class:`ArrowDtype` :class:`DataFrame`
53 .. versionadded:: 2.0
55 **kwargs
56 See :func:`~pandas.read_csv` for the full argument list.
58 Returns
59 -------
60 DataFrame
61 A parsed :class:`~pandas.DataFrame` object.
63 See Also
64 --------
65 DataFrame.to_clipboard : Copy object to the system clipboard.
66 read_csv : Read a comma-separated values (csv) file into DataFrame.
67 read_fwf : Read a table of fixed-width formatted lines into DataFrame.
69 Examples
70 --------
71 >>> df = pd.DataFrame([[1, 2, 3], [4, 5, 6]], columns=["A", "B", "C"])
72 >>> df.to_clipboard() # doctest: +SKIP
73 >>> pd.read_clipboard() # doctest: +SKIP
74 A B C
75 0 1 2 3
76 1 4 5 6
77 """
78 encoding = kwargs.pop("encoding", "utf-8")
80 # only utf-8 is valid for passed value because that's what clipboard
81 # supports
82 if encoding is not None and encoding.lower().replace("-", "") != "utf8":
83 raise NotImplementedError("reading from clipboard only supports utf-8 encoding")
85 check_dtype_backend(dtype_backend)
87 from pandas.io.clipboard import clipboard_get
88 from pandas.io.parsers import read_csv
90 text = clipboard_get()
92 # Try to decode (if needed, as "text" might already be a string here).
93 try:
94 text = text.decode(kwargs.get("encoding") or get_option("display.encoding"))
95 except AttributeError:
96 pass
98 # Excel copies into clipboard with \t separation
99 # inspect no more then the 10 first lines, if they
100 # all contain an equal number (>0) of tabs, infer
101 # that this came from excel and set 'sep' accordingly
102 lines = text[:10000].split("\n")[:-1][:10]
104 # Need to remove leading white space, since read_csv
105 # accepts:
106 # a b
107 # 0 1 2
108 # 1 3 4
110 counts = {x.lstrip(" ").count("\t") for x in lines}
111 if len(lines) > 1 and len(counts) == 1 and counts.pop() != 0:
112 sep = "\t"
113 # check the number of leading tabs in the first line
114 # to account for index columns
115 index_length = len(lines[0]) - len(lines[0].lstrip(" \t"))
116 if index_length != 0:
117 kwargs.setdefault("index_col", list(range(index_length)))
119 elif not isinstance(sep, str):
120 raise ValueError(f"{sep=} must be a string")
122 # Regex separator currently only works with python engine.
123 # Default to python if separator is multi-character (regex)
124 if len(sep) > 1 and kwargs.get("engine") is None:
125 kwargs["engine"] = "python"
126 elif len(sep) > 1 and kwargs.get("engine") == "c":
127 warnings.warn(
128 "read_clipboard with regex separator does not work properly with c engine.",
129 stacklevel=find_stack_level(),
130 )
132 return read_csv(StringIO(text), sep=sep, dtype_backend=dtype_backend, **kwargs)
135def to_clipboard(
136 obj, excel: bool | None = True, sep: str | None = None, **kwargs
137) -> None: # pragma: no cover
138 """
139 Attempt to write text representation of object to the system clipboard
140 The clipboard can be then pasted into Excel for example.
142 Parameters
143 ----------
144 obj : the object to write to the clipboard
145 excel : bool, defaults to True
146 if True, use the provided separator, writing in a csv
147 format for allowing easy pasting into excel.
148 if False, write a string representation of the object
149 to the clipboard
150 sep : optional, defaults to tab
151 other keywords are passed to to_csv
153 Notes
154 -----
155 Requirements for your platform
156 - Linux: xclip, or xsel (with PyQt4 modules)
157 - Windows:
158 - OS X:
159 """
160 encoding = kwargs.pop("encoding", "utf-8")
162 # testing if an invalid encoding is passed to clipboard
163 if encoding is not None and encoding.lower().replace("-", "") != "utf8":
164 raise ValueError("clipboard only supports utf-8 encoding")
166 from pandas.io.clipboard import clipboard_set
168 if excel is None:
169 excel = True
171 if excel:
172 try:
173 if sep is None:
174 sep = "\t"
175 buf = StringIO()
177 # clipboard_set (pyperclip) expects unicode
178 obj.to_csv(buf, sep=sep, encoding="utf-8", **kwargs)
179 text = buf.getvalue()
181 clipboard_set(text)
182 return
183 except TypeError:
184 warnings.warn(
185 "to_clipboard in excel mode requires a single character separator.",
186 stacklevel=find_stack_level(),
187 )
188 elif sep is not None:
189 warnings.warn(
190 "to_clipboard with excel=False ignores the sep argument.",
191 stacklevel=find_stack_level(),
192 )
194 if isinstance(obj, ABCDataFrame):
195 # str(df) has various unhelpful defaults, like truncation
196 with option_context("display.max_colwidth", None):
197 objstr = obj.to_string(**kwargs)
198 else:
199 objstr = str(obj)
200 clipboard_set(objstr)