diff --git a/.github/workflows/build_and_test.yml b/.github/workflows/build_and_test.yml
index 674e59508510c..f202a7d49c9a2 100644
--- a/.github/workflows/build_and_test.yml
+++ b/.github/workflows/build_and_test.yml
@@ -678,7 +678,7 @@ jobs:
# See also https://issues.apache.org/jira/browse/SPARK-35375.
# Pin the MarkupSafe to 2.0.1 to resolve the CI error.
# See also https://issues.apache.org/jira/browse/SPARK-38279.
- python3.9 -m pip install 'sphinx<3.1.0' mkdocs pydata_sphinx_theme nbsphinx numpydoc 'jinja2<3.0.0' 'markupsafe==2.0.1' 'pyzmq<24.0.0'
+ python3.9 -m pip install 'sphinx<3.1.0' mkdocs pydata_sphinx_theme 'sphinx-copybutton==0.5.2' nbsphinx numpydoc 'jinja2<3.0.0' 'markupsafe==2.0.1' 'pyzmq<24.0.0'
python3.9 -m pip install ipython_genutils # See SPARK-38517
python3.9 -m pip install sphinx_plotly_directive 'numpy>=1.20.0' pyarrow pandas 'plotly>=4.8'
python3.9 -m pip install 'docutils<0.18.0' # See SPARK-39421
diff --git a/LICENSE b/LICENSE
index 1735d3208f2e2..74686d7ffa388 100644
--- a/LICENSE
+++ b/LICENSE
@@ -218,11 +218,6 @@ docs/js/vendor/bootstrap.js
connector/spark-ganglia-lgpl/src/main/java/com/codahale/metrics/ganglia/GangliaReporter.java
-Python Software Foundation License
-----------------------------------
-
-python/docs/source/_static/copybutton.js
-
BSD 3-Clause
------------
diff --git a/dev/create-release/spark-rm/Dockerfile b/dev/create-release/spark-rm/Dockerfile
index 85155b67bd5a3..cd57226f5e017 100644
--- a/dev/create-release/spark-rm/Dockerfile
+++ b/dev/create-release/spark-rm/Dockerfile
@@ -42,7 +42,7 @@ ARG APT_INSTALL="apt-get install --no-install-recommends -y"
# We should use the latest Sphinx version once this is fixed.
# TODO(SPARK-35375): Jinja2 3.0.0+ causes error when building with Sphinx.
# See also https://issues.apache.org/jira/browse/SPARK-35375.
-ARG PIP_PKGS="sphinx==3.0.4 mkdocs==1.1.2 numpy==1.20.3 pydata_sphinx_theme==0.8.0 ipython==7.19.0 nbsphinx==0.8.0 numpydoc==1.1.0 jinja2==2.11.3 twine==3.4.1 sphinx-plotly-directive==0.1.3 pandas==1.5.3 pyarrow==3.0.0 plotly==5.4.0 markupsafe==2.0.1 docutils<0.17 grpcio==1.56.0 protobuf==4.21.6 grpcio-status==1.56.0 googleapis-common-protos==1.56.4"
+ARG PIP_PKGS="sphinx==3.0.4 mkdocs==1.1.2 numpy==1.20.3 pydata_sphinx_theme==0.8.0 ipython==7.19.0 nbsphinx==0.8.0 numpydoc==1.1.0 jinja2==2.11.3 twine==3.4.1 sphinx-plotly-directive==0.1.3 sphinx-copybutton==0.5.2 pandas==1.5.3 pyarrow==3.0.0 plotly==5.4.0 markupsafe==2.0.1 docutils<0.17 grpcio==1.56.0 protobuf==4.21.6 grpcio-status==1.56.0 googleapis-common-protos==1.56.4"
ARG GEM_PKGS="bundler:2.3.8"
# Install extra needed repos and refresh.
diff --git a/dev/requirements.txt b/dev/requirements.txt
index 38a9b2447108c..597417aba1f3d 100644
--- a/dev/requirements.txt
+++ b/dev/requirements.txt
@@ -37,6 +37,7 @@ numpydoc
jinja2<3.0.0
sphinx<3.1.0
sphinx-plotly-directive
+sphinx-copybutton<0.5.3
docutils<0.18.0
# See SPARK-38279.
markupsafe==2.0.1
diff --git a/licenses/LICENSE-copybutton.txt b/licenses/LICENSE-copybutton.txt
deleted file mode 100644
index 45be6b83a53be..0000000000000
--- a/licenses/LICENSE-copybutton.txt
+++ /dev/null
@@ -1,49 +0,0 @@
-PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
---------------------------------------------
-
-1. This LICENSE AGREEMENT is between the Python Software Foundation
-("PSF"), and the Individual or Organization ("Licensee") accessing and
-otherwise using this software ("Python") in source or binary form and
-its associated documentation.
-
-2. Subject to the terms and conditions of this License Agreement, PSF hereby
-grants Licensee a nonexclusive, royalty-free, world-wide license to reproduce,
-analyze, test, perform and/or display publicly, prepare derivative works,
-distribute, and otherwise use Python alone or in any derivative version,
-provided, however, that PSF's License Agreement and PSF's notice of copyright,
-i.e., "Copyright (c) 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
-2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019 Python Software Foundation;
-All Rights Reserved" are retained in Python alone or in any derivative version
-prepared by Licensee.
-
-3. In the event Licensee prepares a derivative work that is based on
-or incorporates Python or any part thereof, and wants to make
-the derivative work available to others as provided herein, then
-Licensee hereby agrees to include in any such work a brief summary of
-the changes made to Python.
-
-4. PSF is making Python available to Licensee on an "AS IS"
-basis. PSF MAKES NO REPRESENTATIONS OR WARRANTIES, EXPRESS OR
-IMPLIED. BY WAY OF EXAMPLE, BUT NOT LIMITATION, PSF MAKES NO AND
-DISCLAIMS ANY REPRESENTATION OR WARRANTY OF MERCHANTABILITY OR FITNESS
-FOR ANY PARTICULAR PURPOSE OR THAT THE USE OF PYTHON WILL NOT
-INFRINGE ANY THIRD PARTY RIGHTS.
-
-5. PSF SHALL NOT BE LIABLE TO LICENSEE OR ANY OTHER USERS OF PYTHON
-FOR ANY INCIDENTAL, SPECIAL, OR CONSEQUENTIAL DAMAGES OR LOSS AS
-A RESULT OF MODIFYING, DISTRIBUTING, OR OTHERWISE USING PYTHON,
-OR ANY DERIVATIVE THEREOF, EVEN IF ADVISED OF THE POSSIBILITY THEREOF.
-
-6. This License Agreement will automatically terminate upon a material
-breach of its terms and conditions.
-
-7. Nothing in this License Agreement shall be deemed to create any
-relationship of agency, partnership, or joint venture between PSF and
-Licensee. This License Agreement does not grant permission to use PSF
-trademarks or trade name in a trademark sense to endorse or promote
-products or services of Licensee, or any third party.
-
-8. By copying, installing or otherwise using Python, Licensee
-agrees to be bound by the terms and conditions of this License
-Agreement.
-
diff --git a/python/docs/source/_static/copybutton.js b/python/docs/source/_static/copybutton.js
deleted file mode 100644
index 896faad3f9df1..0000000000000
--- a/python/docs/source/_static/copybutton.js
+++ /dev/null
@@ -1,67 +0,0 @@
-// Copyright 2014 PSF. Licensed under the PYTHON SOFTWARE FOUNDATION LICENSE VERSION 2
-// File originates from the cpython source found in Doc/tools/sphinxext/static/copybutton.js
-
-$(document).ready(function() {
- /* Add a [>>>] button on the top-right corner of code samples to hide
- * the >>> and ... prompts and the output and thus make the code
- * copyable. */
- var div = $('.highlight-python .highlight,' +
- '.highlight-default .highlight,' +
- '.highlight-python3 .highlight')
- var pre = div.find('pre');
-
- // get the styles from the current theme
- pre.parent().parent().css('position', 'relative');
- var hide_text = 'Hide the prompts and output';
- var show_text = 'Show the prompts and output';
- var border_width = pre.css('border-top-width');
- var border_style = pre.css('border-top-style');
- var border_color = pre.css('border-top-color');
- var button_styles = {
- 'cursor':'pointer', 'position': 'absolute', 'top': '0', 'right': '0',
- 'border-color': border_color, 'border-style': border_style,
- 'border-width': border_width, 'color': border_color, 'text-size': '75%',
- 'font-family': 'monospace', 'padding-left': '0.2em', 'padding-right': '0.2em',
- 'border-radius': '0 3px 0 0',
- 'user-select': 'none'
- }
-
- // create and add the button to all the code blocks that contain >>>
- div.each(function(index) {
- var jthis = $(this);
- if (jthis.find('.gp').length > 0) {
- var button = $('>>>');
- button.css(button_styles)
- button.attr('title', hide_text);
- button.data('hidden', 'false');
- jthis.prepend(button);
- }
- // tracebacks (.gt) contain bare text elements that need to be
- // wrapped in a span to work with .nextUntil() (see later)
- jthis.find('pre:has(.gt)').contents().filter(function() {
- return ((this.nodeType == 3) && (this.data.trim().length > 0));
- }).wrap('');
- });
-
- // define the behavior of the button when it's clicked
- $('.copybutton').click(function(e){
- e.preventDefault();
- var button = $(this);
- if (button.data('hidden') === 'false') {
- // hide the code output
- button.parent().find('.go, .gp, .gt').hide();
- button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'hidden');
- button.css('text-decoration', 'line-through');
- button.attr('title', show_text);
- button.data('hidden', 'true');
- } else {
- // show the code output
- button.parent().find('.go, .gp, .gt').show();
- button.next('pre').find('.gt').nextUntil('.gp, .go').css('visibility', 'visible');
- button.css('text-decoration', 'none');
- button.attr('title', hide_text);
- button.data('hidden', 'false');
- }
- });
-});
-
diff --git a/python/docs/source/conf.py b/python/docs/source/conf.py
index 0f57cb37ceeb1..a0d087de176ff 100644
--- a/python/docs/source/conf.py
+++ b/python/docs/source/conf.py
@@ -63,6 +63,7 @@
'sphinx.ext.viewcode',
'sphinx.ext.mathjax',
'sphinx.ext.autosummary',
+ 'sphinx_copybutton',
'nbsphinx', # Converts Jupyter Notebook to reStructuredText files for Sphinx.
# For ipython directive in reStructuredText files. It is generated by the notebook.
'IPython.sphinxext.ipython_console_highlighting',
@@ -70,6 +71,9 @@
'sphinx_plotly_directive', # For visualize plot result
]
+# sphinx copy button
+copybutton_exclude = '.linenos, .gp, .go'
+
# plotly plot directive
plotly_include_source = True
plotly_html_show_formats = False
@@ -416,9 +420,6 @@
# If false, no index is generated.
#epub_use_index = True
-def setup(app):
- # The app.add_javascript() is deprecated.
- getattr(app, "add_js_file", getattr(app, "add_javascript", None))('copybutton.js')
# Skip sample endpoint link (not expected to resolve)
linkcheck_ignore = [r'https://kinesis.us-east-1.amazonaws.com']