diff --git a/.circleci/config.yml b/.circleci/config.yml index 5e58717cc4..b02e989c31 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -339,7 +339,7 @@ jobs: command: | cd packages/python/plotly locale - tox -e py37-core -- -a '!nodev' + tox -e py37-core -- -k 'not nodev' no_output_timeout: 20m - run: name: Commit diff --git a/CHANGELOG.md b/CHANGELOG.md index 0f801f6554..f00ad21c4d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). +## [4.5.3] - 2020-03-05 + +### Updated + +- Removed development dependency on `nose` testing framework [#2217](https://github.com/plotly/plotly.py/pull/2217) + +### Fixed + + - JupyterLab extension now compatible with JupyterLab 2.0 [#2245](https://github.com/plotly/plotly.py/pull/2245) with thanks to [@consideRatio](https://github.com/consideRatio) for the contribution! + ## [4.5.2] - 2020-02-24 ### Fixed @@ -11,6 +21,7 @@ This project adheres to [Semantic Versioning](http://semver.org/). ## [4.5.1] - 2020-02-19 ### Updated + - Updated Plotly.js to version 1.52.2. See the [plotly.js CHANGELOG](https://github.com/plotly/plotly.js/releases/tag/v1.52.2) for more information on bug fixes. ### Fixed diff --git a/README.md b/README.md index 36831a7732..0d230a119e 100644 --- a/README.md +++ b/README.md @@ -26,7 +26,7 @@ ## Quickstart -`pip install plotly==4.5.2` +`pip install plotly==4.5.3` Inside [Jupyter notebook](https://jupyter.org/install) (installable with `pip install "notebook>=5.3" "ipywidgets>=7.2"`): @@ -75,13 +75,13 @@ Built on top of [plotly.js](https://github.com/plotly/plotly.js), `plotly.py` is plotly.py may be installed using pip... ``` -pip install plotly==4.5.2 +pip install plotly==4.5.3 ``` or conda. ``` -conda install -c plotly plotly=4.5.2 +conda install -c plotly plotly=4.5.3 ``` ### Jupyter Notebook Support @@ -128,10 +128,10 @@ set NODE_OPTIONS=--max-old-space-size=4096 jupyter labextension install @jupyter-widgets/jupyterlab-manager@1.1 --no-build # FigureWidget support -jupyter labextension install plotlywidget@1.5.2 --no-build +jupyter labextension install plotlywidget@1.5.3 --no-build # and jupyterlab renderer support -jupyter labextension install jupyterlab-plotly@1.5.2 --no-build +jupyter labextension install jupyterlab-plotly@1.5.3 --no-build # Build extensions (must be done to activate extensions since --no-build is used above) jupyter lab build diff --git a/contributing.md b/contributing.md index 84cc1841d1..78d1727f58 100644 --- a/contributing.md +++ b/contributing.md @@ -1,6 +1,6 @@ # Contributing -The bottom line. Follow your Nose, or our Nose. Write-run-love tests :fist:. +Thank you for contributing to plotly.py! ## Code of Conduct @@ -128,34 +128,40 @@ classes based on the new schema. We take advantage of two tools to run tests: * [`tox`](https://tox.readthedocs.io/en/latest/), which is both a virtualenv management and test tool. -* [`nose`](https://nose.readthedocs.org/en/latest/), which is is an extension of Python's unittest +* [`pytest`](https://docs.pytest.org/en/latest/), a powerful framework for unit testing. -### Running Tests with `nose` +### Running Tests with `pytest` Since our tests cover *all* the functionality, to prevent tons of errors from showing up and having to parse through a messy output, you'll need to install `optional-requirements.txt` as explained above. -After you've done that, go ahead and follow (y)our Nose! +After you've done that, go ahead and run the test suite! ```bash -nosetests -w packages/python/plotly/plotly/tests/ +pytest packages/python/plotly/plotly/tests/ ``` Or for more *verbose* output: ```bash -nosetests -w packages/python/plotly/plotly/tests/ -v +pytest -v packages/python/plotly/plotly/tests/ ``` Either of those will run *every* test we've written for the Python API. You can get more granular by running something like: ```bash -nosetests -w packages/python/plotly/plotly/tests/test_core/ +pytest packages/python/plotly/plotly/tests/test_core/ ``` ... or even more granular by running something like: ```bash -nosetests plotly/tests/test_plotly/test_plot.py +pytest plotly/tests/test_plotly/test_plot.py +``` + +or for a specfic test function + +```bash +pytest plotly/tests/test_plotly/test_plot.py::test_function ``` ### Running tests with `tox` @@ -187,16 +193,16 @@ Where `TOXENV` is the environment list you want to use when invoking `tox` from * `tox` will automatically manage a virtual env for each environment you want to test in. * You only have to run `tox` and know that the module is working in both `Python 2` and `Python 3`. -Finally, `tox` allows you to pass in additional command line arguments that are formatted in (by us) in the `tox.ini` file, see `{posargs}`. This is setup to help with our `nose attr` configuration. To run only tests that are *not* tagged with `slow`, you could use the following command: +Finally, `tox` allows you to pass in additional command line arguments that are formatted in (by us) in the `tox.ini` file, see `{posargs}`. This is setup to help with our configuration of [pytest markers](http://doc.pytest.org/en/latest/example/markers.html), which are set up in `packages/python/plotly/pytest.ini`. To run only tests that are *not* tagged with `nodev`, you could use the following command: ```bash -tox -- -a '!slow' +tox -- -a '!nodev' ``` -Note that anything after `--` is substituted in for `{posargs}` in the tox.ini. For completeness, because it's reasonably confusing, if you want to force a match for *multiple* `nose attr` tags, you comma-separate the tags like so: +Note that anything after `--` is substituted in for `{posargs}` in the tox.ini. For completeness, because it's reasonably confusing, if you want to force a match for *multiple* `pytest` marker tags, you comma-separate the tags like so: ```bash -tox -- -a '!slow','!matplotlib' +tox -- -a '!nodev','!matplotlib' ``` ### Writing Tests diff --git a/doc/python/axes.md b/doc/python/axes.md index eea8f8daed..cdab606651 100644 --- a/doc/python/axes.md +++ b/doc/python/axes.md @@ -741,6 +741,27 @@ fig.update_yaxes(domain=(0.25, 0.75)) fig.show() ``` +#### Synchronizing axes in subplots with `matches` + +Using `facet_col` from `plotly.express` let [zoom](https://help.plot.ly/zoom-pan-hover-controls/#step-3-zoom-in-and-zoom-out-autoscale-the-plot) and [pan](https://help.plot.ly/zoom-pan-hover-controls/#step-6-pan-along-axes) each facet to the same range implicitly. However, if the subplots are created with `make_subplots`, the axis needs to be updated with `matches` parameter to update all the subplots accordingly. + +Zoom in one trace below, to see the other subplots zoomed to the same x-axis range. To pan all the subplots, click and drag from the center of x-axis to the side: + +```python +import plotly.graph_objects as go +from plotly.subplots import make_subplots +import numpy as np + +N = 20 +x = np.linspace(0, 1, N) + +fig = make_subplots(1, 3) +for i in range(1, 4): + fig.add_trace(go.Scatter(x=x, y=np.random.random(N)), 1, i) +fig.update_xaxes(matches='x') +fig.show() +``` + #### Reference See https://plot.ly/python/reference/#layout-xaxis and https://plot.ly/python/reference/#layout-yaxis for more information and chart attribute options! diff --git a/doc/python/facet-plots.md b/doc/python/facet-plots.md index 999a23fd0e..6df50ae549 100644 --- a/doc/python/facet-plots.md +++ b/doc/python/facet-plots.md @@ -118,3 +118,24 @@ fig.show() ```python ``` + +### Synchronizing axes in subplots with `matches` + +Using `facet_col` from `plotly.express` let [zoom](https://help.plot.ly/zoom-pan-hover-controls/#step-3-zoom-in-and-zoom-out-autoscale-the-plot) and [pan](https://help.plot.ly/zoom-pan-hover-controls/#step-6-pan-along-axes) each facet to the same range implicitly. However, if the subplots are created with `make_subplots`, the axis needs to be updated with `matches` parameter to update all the subplots accordingly. + +Zoom in one trace below, to see the other subplots zoomed to the same x-axis range. To pan all the subplots, click and drag from the center of x-axis to the side: + +```python +import plotly.graph_objects as go +from plotly.subplots import make_subplots +import numpy as np + +N = 20 +x = np.linspace(0, 1, N) + +fig = make_subplots(1, 3) +for i in range(1, 4): + fig.add_trace(go.Scatter(x=x, y=np.random.random(N)), 1, i) +fig.update_xaxes(matches='x') +fig.show() +``` diff --git a/doc/python/figurewidget-app.md b/doc/python/figurewidget-app.md index aeeb61013a..99a17c3116 100644 --- a/doc/python/figurewidget-app.md +++ b/doc/python/figurewidget-app.md @@ -31,6 +31,7 @@ jupyter: page_type: example_index permalink: python/figurewidget-app/ thumbnail: thumbnail/multi-widget.jpg + redirect_from: /python/slider-widget/ --- #### NYC Flights Database diff --git a/doc/python/figurewidget.md b/doc/python/figurewidget.md index 63de6a9c8a..3fe143b1d5 100644 --- a/doc/python/figurewidget.md +++ b/doc/python/figurewidget.md @@ -31,6 +31,7 @@ jupyter: page_type: example_index permalink: python/figurewidget/ thumbnail: thumbnail/figurewidget-overview.gif + redirect_from: /python/ipython-widgets/ --- #### Create a Simple FigureWidget diff --git a/doc/python/getting-started.md b/doc/python/getting-started.md index 8428cffe03..157f91a45c 100644 --- a/doc/python/getting-started.md +++ b/doc/python/getting-started.md @@ -49,13 +49,13 @@ Thanks to deep integration with the [orca](https://github.com/plotly/orca) image plotly.py may be installed using pip... ``` -$ pip install plotly==4.5.2 +$ pip install plotly==4.5.3 ``` or conda. ``` -$ conda install -c plotly plotly=4.5.2 +$ conda install -c plotly plotly=4.5.3 ``` This package contains everything you need to write figures to standalone HTML files. @@ -144,10 +144,10 @@ set NODE_OPTIONS=--max-old-space-size=4096 jupyter labextension install @jupyter-widgets/jupyterlab-manager@1.1 --no-build # jupyterlab renderer support -jupyter labextension install jupyterlab-plotly@1.5.2 --no-build +jupyter labextension install jupyterlab-plotly@1.5.3 --no-build # FigureWidget support -jupyter labextension install plotlywidget@1.5.2 --no-build +jupyter labextension install plotlywidget@1.5.3 --no-build # Build extensions (must be done to activate extensions since --no-build is used above) jupyter lab build diff --git a/doc/python/interactive-html-export.md b/doc/python/interactive-html-export.md new file mode 100644 index 0000000000..5c919946c9 --- /dev/null +++ b/doc/python/interactive-html-export.md @@ -0,0 +1,65 @@ +--- +jupyter: + jupytext: + notebook_metadata_filter: all + text_representation: + extension: .md + format_name: markdown + format_version: '1.2' + jupytext_version: 1.3.1 + kernelspec: + display_name: Python 3 + language: python + name: python3 + language_info: + codemirror_mode: + name: ipython + version: 3 + file_extension: .py + mimetype: text/x-python + name: python + nbconvert_exporter: python + pygments_lexer: ipython3 + version: 3.6.8 + plotly: + description: Plotly allows you to save interactive HTML versions of your figures + to your local disk. + display_as: file_settings + language: python + layout: base + name: Interactive HTML Export + order: 30 + page_type: u-guide + permalink: python/interactive-html-export/ + thumbnail: thumbnail/static-image-export.png +--- + +### Interactive vs Static Export + +Plotly figures are interactive when viewed in a web browser: you can hover over data points, pan and zoom axes, and show and hide traces by clicking or double-clicking on the legend. You can export figures either to [static image file formats like PNG, JEPG, SVG or PDF](/python/static-image-export/) or you can export them to HTML files which can be opened in a browser. This page explains how to do the latter. + + +### Saving to an HTML file + +Any figure can be saved an HTML file using the `write_html` method. These HTML files can be opened in any web browser to access the fully interactive figure. + +```python +import plotly.express as px + +fig =px.scatter(x=range(10), y=range(10)) +fig.write_html("path/to/file.html") +``` + + +### Controlling the size of the HTML file + +By default, the resulting HTML file is a fully self-contained HTML file which can be uploaded to a web server or shared via email or other file-sharing mechanisms. The downside to this approach is that the file is very large (5Mb+) because it contains an inlined copy of the Plotly.js library required to make the figure interactive. This can be controlled via the `include_plotlyjs` argument (see below). + + +### Full Parameter Documentation + +```python +import plotly.graph_objects as go + +help(go.Figure.write_html) +``` diff --git a/doc/python/legend.md b/doc/python/legend.md index 9a2996ff17..d11c58305a 100644 --- a/doc/python/legend.md +++ b/doc/python/legend.md @@ -243,7 +243,30 @@ fig.update_layout( fig.show() ``` -### Size of Legend Items +#### Hide the Trace Implicitly + +`Graph_objects` traces have a `visible` attribute. If set to `legendonly`, the trace is hidden from the graph implicitly. Click on the name in the legend to display the hidden trace. + +```python +import plotly.graph_objects as go + +fig = go.Figure() + +fig.add_trace(go.Scatter( + x=[1, 2, 3, 4, 5], + y=[1, 2, 3, 4, 5], +)) + +fig.add_trace(go.Scatter( + x=[1, 2, 3, 4, 5], + y=[5, 4, 3, 2, 1], + visible='legendonly' +)) + +fig.show() +``` + +#### Size of Legend Items In this example [itemsizing](https://plot.ly/python/reference/#layout-legend-itemsizing) attribute determines the legend items symbols remain constant, regardless of how tiny/huge the bubbles would be in the graph. diff --git a/doc/python/marker-style.md b/doc/python/marker-style.md index 865ff1052f..3b54cc0064 100644 --- a/doc/python/marker-style.md +++ b/doc/python/marker-style.md @@ -313,113 +313,29 @@ The basic symbols are: `circle`, `square`, `diamond`, `cross`, `x`, `triangle`, Each basic symbol is also represented by a number. Adding 100 to that number is equivalent to appending the suffix "-open" to a symbol name. Adding 200 is equivalent to appending "-dot" to a symbol name. Adding 300 is equivalent to appending "-open-dot" or "dot-open" to a symbol name. -In the following figures, hover over a symbol to see its name or number. Set the `marker_symbol` attribute equal to that name or number to change the marker symbol in your figure. - -#### Basic Symbols - -```python -import plotly.graph_objects as go - -fig = go.Figure() - -fig.update_layout(title="Basic Symbols") - -fig.update_xaxes(showticklabels=False) -fig.update_yaxes(showticklabels=False) - -for index in range(27): - fig.add_trace(go.Scatter(x=[(index % 6)], y=[index // 6], name="", - marker_symbol=index, marker_color='black', - marker_size=10, showlegend=False, mode="markers+text", - textposition="middle right", text=f'{index}', - hovertemplate=f'Symbol Number: {index}')) - -fig.show() -``` - -#### All Symbols +In the following figure, hover over a symbol to see its name or number. Set the `marker_symbol` attribute equal to that name or number to change the marker symbol in your figure. ```python import plotly.graph_objects as go - -symbols = [0, 'circle', 100, 'circle-open', 200, 'circle-dot', 300, - 'circle-open-dot', 1, 'square', 101, 'square-open', 201, - 'square-dot', 301, 'square-open-dot', 2, 'diamond', 102, - 'diamond-open', 202, 'diamond-dot', 302, - 'diamond-open-dot', 3, 'cross', 103, 'cross-open', 203, - 'cross-dot', 303, 'cross-open-dot', 4, 'x', 104, 'x-open', - 204, 'x-dot', 304, 'x-open-dot', 5, 'triangle-up', 105, - 'triangle-up-open', 205, 'triangle-up-dot', 305, - 'triangle-up-open-dot', 6, 'triangle-down', 106, - 'triangle-down-open', 206, 'triangle-down-dot', 306, - 'triangle-down-open-dot', 7, 'triangle-left', 107, - 'triangle-left-open', 207, 'triangle-left-dot', 307, - 'triangle-left-open-dot', 8, 'triangle-right', 108, - 'triangle-right-open', 208, 'triangle-right-dot', 308, - 'triangle-right-open-dot', 9, 'triangle-ne', 109, - 'triangle-ne-open', 209, 'triangle-ne-dot', 309, - 'triangle-ne-open-dot', 10, 'triangle-se', 110, - 'triangle-se-open', 210, 'triangle-se-dot', 310, - 'triangle-se-open-dot', 11, 'triangle-sw', 111, - 'triangle-sw-open', 211, 'triangle-sw-dot', 311, - 'triangle-sw-open-dot', 12, 'triangle-nw', 112, - 'triangle-nw-open', 212, 'triangle-nw-dot', 312, - 'triangle-nw-open-dot', 13, 'pentagon', 113, - 'pentagon-open', 213, 'pentagon-dot', 313, - 'pentagon-open-dot', 14, 'hexagon', 114, 'hexagon-open', - 214, 'hexagon-dot', 314, 'hexagon-open-dot', 15, - 'hexagon2', 115, 'hexagon2-open', 215, 'hexagon2-dot', - 315, 'hexagon2-open-dot', 16, 'octagon', 116, - 'octagon-open', 216, 'octagon-dot', 316, - 'octagon-open-dot', 17, 'star', 117, 'star-open', 217, - 'star-dot', 317, 'star-open-dot', 18, 'hexagram', 118, - 'hexagram-open', 218, 'hexagram-dot', 318, - 'hexagram-open-dot', 19, 'star-triangle-up', 119, - 'star-triangle-up-open', 219, 'star-triangle-up-dot', 319, - 'star-triangle-up-open-dot', 20, 'star-triangle-down', - 120, 'star-triangle-down-open', 220, - 'star-triangle-down-dot', 320, - 'star-triangle-down-open-dot', 21, 'star-square', 121, - 'star-square-open', 221, 'star-square-dot', 321, - 'star-square-open-dot', 22, 'star-diamond', 122, - 'star-diamond-open', 222, 'star-diamond-dot', 322, - 'star-diamond-open-dot', 23, 'diamond-tall', 123, - 'diamond-tall-open', 223, 'diamond-tall-dot', 323, - 'diamond-tall-open-dot', 24, 'diamond-wide', 124, - 'diamond-wide-open', 224, 'diamond-wide-dot', 324, - 'diamond-wide-open-dot', 25, 'hourglass', 125, - 'hourglass-open', 26, 'bowtie', 126, 'bowtie-open', 27, - 'circle-cross', 127, 'circle-cross-open', 28, 'circle-x', - 128, 'circle-x-open', 29, 'square-cross', 129, - 'square-cross-open', 30, 'square-x', 130, 'square-x-open', - 31, 'diamond-cross', 131, 'diamond-cross-open', 32, - 'diamond-x', 132, 'diamond-x-open', 33, 'cross-thin', 133, - 'cross-thin-open', 34, 'x-thin', 134, 'x-thin-open', 35, - 'asterisk', 135, 'asterisk-open', 36, 'hash', 136, - 'hash-open', 236, 'hash-dot', 336, 'hash-open-dot', 37, - 'y-up', 137, 'y-up-open', 38, 'y-down', 138, - 'y-down-open', 39, 'y-left', 139, 'y-left-open', 40, - 'y-right', 140, 'y-right-open', 41, 'line-ew', 141, - 'line-ew-open', 42, 'line-ns', 142, 'line-ns-open', 43, - 'line-ne', 143, 'line-ne-open', 44, 'line-nw', 144, - 'line-nw-open'] - -fig = go.Figure() - -fig.update_layout(title="Custom Marker Symbols", height=800) - -fig.update_xaxes(showticklabels=False) -fig.update_yaxes(showticklabels=False) - -for index, symbol in enumerate(symbols[::2]): - fig.add_trace(go.Scatter(x=[(index % 16)], y=[(index // 16)], - marker_symbol=symbol, marker_color=index, - marker_size=20, showlegend=False, mode="markers+text", - name='', - hovertemplate=f'Symbol Name: {symbols[2*index + 1]}
Symbol Number: {symbols[2*index]}', - textfont_size=8 - )) - +from plotly.validators.scatter.marker import SymbolValidator + +raw_symbols = SymbolValidator().values +namestems = [] +namevariants = [] +symbols = [] +for i in range(0,len(raw_symbols),2): + name = raw_symbols[i+1] + symbols.append(raw_symbols[i]) + namestems.append(name.replace("-open", "").replace("-dot", "")) + namevariants.append(name[len(namestems[-1]):]) + +fig = go.Figure(go.Scatter(mode="markers", x=namevariants, y=namestems, marker_symbol=symbols, + marker_line_color="midnightblue", marker_color="lightskyblue", + marker_line_width=2, marker_size=15, + hovertemplate="name: %{y}%{x}
number: %{marker.symbol}")) +fig.update_layout(title="Mouse over symbols for name & number!", + xaxis_range=[-1,4], yaxis_range=[len(set(namestems)),-1], + margin=dict(b=0,r=0), xaxis_side="top", height=1200, width=400) fig.show() ``` diff --git a/doc/python/static-image-export.md b/doc/python/static-image-export.md index 16dd6c0abe..387fbdd24d 100644 --- a/doc/python/static-image-export.md +++ b/doc/python/static-image-export.md @@ -35,10 +35,12 @@ jupyter: thumbnail: thumbnail/static-image-export.png --- - -### Static Image Export -It's possible to programmatically export figures as high quality static images while fully offline. +### Interactive vs Static Export + +Plotly figures are interactive when viewed in a web browser: you can hover over data points, pan and zoom axes, and show and hide traces by clicking or double-clicking on the legend. You can export figures either to static image file formats like PNG, JEPG, SVG or PDF or you can [export them to HTML files which can be opened in a browser and remain interactive](/python/interactive-html-export/). This page explains how to do the former. + + #### Install Dependencies Static image generation requires the [orca](https://github.com/plotly/orca) commandline utility and the [psutil](https://github.com/giampaolo/psutil) and [requests](https://2.python-requests.org/en/master/) Python libraries. There are 3 general approach to installing these dependencies. diff --git a/doc/python/subplots.md b/doc/python/subplots.md index d1f411797d..50cf161d45 100644 --- a/doc/python/subplots.md +++ b/doc/python/subplots.md @@ -296,6 +296,28 @@ fig.update_layout(height=600, width=600, fig.show() ``` +### Subplots with Shared Colorscale + +To share colorscale information in multiple subplots, you can use [coloraxis](https://plot.ly/javascript/reference/#scatter-marker-line-coloraxis). + +```python +from plotly.subplots import make_subplots +import plotly.graph_objects as go + +fig = make_subplots(rows=1, cols=2, shared_yaxes=True) + +fig.add_trace(go.Bar(x=[1, 2, 3], y=[4, 5, 6], + marker=dict(color=[4, 5, 6], coloraxis="coloraxis")), + 1, 1) + +fig.add_trace(go.Bar(x=[1, 2, 3], y=[2, 3, 5], + marker=dict(color=[2, 3, 5], coloraxis="coloraxis")), + 1, 2) + +fig.update_layout(coloraxis=dict(colorscale='Bluered_r'), showlegend=False) +fig.show() +``` + #### Custom Sized Subplot with Subplot Titles The `specs` argument to `make_subplots` is used to configure per-subplot options. `specs` must be a 2-dimension list with dimensions that match those provided as the `rows` and `cols` arguments. The elements of `specs` may either be `None`, indicating no subplot should be initialized starting with this grid cell, or a dictionary containing subplot options. The `colspan` subplot option specifies the number of grid columns that the subplot starting in the given cell should occupy. If unspecified, `colspan` defaults to 1. diff --git a/packages/javascript/jupyterlab-plotly/package-lock.json b/packages/javascript/jupyterlab-plotly/package-lock.json index da0d9da013..8a2339f6f6 100644 --- a/packages/javascript/jupyterlab-plotly/package-lock.json +++ b/packages/javascript/jupyterlab-plotly/package-lock.json @@ -1,6 +1,6 @@ { "name": "jupyterlab-plotly", - "version": "1.5.2", + "version": "1.5.3", "lockfileVersion": 1, "requires": true, "dependencies": { @@ -30,12 +30,120 @@ } }, "@jupyterlab/rendermime-interfaces": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/@jupyterlab/rendermime-interfaces/-/rendermime-interfaces-1.3.0.tgz", - "integrity": "sha512-04ohT/xdTcdp/TKuNMqY1MLwh7IWyjbMrQXiuwanE8xo52fIe6OIK0DENwc6VDMej1+8NVSU7rX42urLCex0sA==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@jupyterlab/rendermime-interfaces/-/rendermime-interfaces-2.0.0.tgz", + "integrity": "sha512-1BRpxIppycFmJtV5kq+BVcQT80k3PflMmDsSITXFUspX20SiEktjZcSfzUplTwkp6pSXlr2QCLTV2rQE00dGNA==", + "requires": { + "@lumino/coreutils": "1.4.2", + "@lumino/widgets": "1.11.1" + } + }, + "@lumino/algorithm": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lumino/algorithm/-/algorithm-1.2.3.tgz", + "integrity": "sha512-XBJ/homcm7o8Y9G6MzYvf0FF7SVqUCzvkIO01G2mZhCOnkZZhZ9c4uNOcE2VjSHNxHv2WU0l7d8rdhyKhmet+A==" + }, + "@lumino/collections": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@lumino/collections/-/collections-1.2.3.tgz", + "integrity": "sha512-lrSTb7kru/w8xww8qWqHHhHO3GkoQeXST2oNkOEbWNEO4wuBIHoKPSOmXpUwu58UykBUfd5hL5wbkeTzyNMONg==", + "requires": { + "@lumino/algorithm": "1.2.3" + } + }, + "@lumino/commands": { + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/@lumino/commands/-/commands-1.10.1.tgz", + "integrity": "sha512-HGtXtqKD1WZJszJ42u2DyM3sgxrLal66IoHSJjbn2ygcEVCKDK73NSzoaQtXFtiissMedzKl8aIRXB3uyeEOlw==", + "requires": { + "@lumino/algorithm": "1.2.3", + "@lumino/coreutils": "1.4.2", + "@lumino/disposable": "1.3.5", + "@lumino/domutils": "1.1.7", + "@lumino/keyboard": "1.1.6", + "@lumino/signaling": "1.3.5", + "@lumino/virtualdom": "1.6.1" + } + }, + "@lumino/coreutils": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/@lumino/coreutils/-/coreutils-1.4.2.tgz", + "integrity": "sha512-SmQ4YDANe25rZd0bLoW7LVAHmgySjkrJmyNPnPW0GrpBt2u4/6D+EQJ8PCCMNWuJvrljBCdlmgOFsT38qYhfcw==" + }, + "@lumino/disposable": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@lumino/disposable/-/disposable-1.3.5.tgz", + "integrity": "sha512-IWDAd+nysBnwLhEtW7M62PVk84OEex9OEktZsS6V+19n/o8/Rw4ccL0pt0GFby01CsVK0YcELDoDaMUZsMiAmA==", + "requires": { + "@lumino/algorithm": "1.2.3", + "@lumino/signaling": "1.3.5" + } + }, + "@lumino/domutils": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/@lumino/domutils/-/domutils-1.1.7.tgz", + "integrity": "sha512-NPysY8XfpCvLNvDe+z1caIUPxOLXWRPQMUAjOj/EhggRyXadan6Lm/5uO6M9S5gW/v9QUXT4+1Sxe3WXz0nRCA==" + }, + "@lumino/dragdrop": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/@lumino/dragdrop/-/dragdrop-1.5.1.tgz", + "integrity": "sha512-MFg/hy6hHdPwBZypBue5mlrBzjoNrtBQzzJW+kbM5ftAOvS99ZRgyMMlMQcbsHd+6yib9NOQ64Hd8P8uZEWTdw==", + "requires": { + "@lumino/coreutils": "1.4.2", + "@lumino/disposable": "1.3.5" + } + }, + "@lumino/keyboard": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@lumino/keyboard/-/keyboard-1.1.6.tgz", + "integrity": "sha512-W6pqe0TXRfGOoz1ZK1PRmuGZUWpmdoJArrzwmduUf0t2r06yl56S7w76gxrB7ExTidNPPaOWydGIosPgdgZf5A==" + }, + "@lumino/messaging": { + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/@lumino/messaging/-/messaging-1.3.3.tgz", + "integrity": "sha512-J+0m1aywl64I9/dr9fzE9IwC+eq90T5gUi1hCXP1MFnZh4aLUymmRV5zFw1CNh/vYlNnEu72xxEuhfCfuhiy8g==", + "requires": { + "@lumino/algorithm": "1.2.3", + "@lumino/collections": "1.2.3" + } + }, + "@lumino/properties": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/@lumino/properties/-/properties-1.1.6.tgz", + "integrity": "sha512-QnZa1IB7sr4Tawf0OKvwgZAptxDRK7DUAMJ71zijXNXH4FlxyThzOWXef51HHFsISKYa8Rn3rysOwtc62XkmXw==" + }, + "@lumino/signaling": { + "version": "1.3.5", + "resolved": "https://registry.npmjs.org/@lumino/signaling/-/signaling-1.3.5.tgz", + "integrity": "sha512-6jniKrLrJOXKJmaJyU7hr6PBzE4GJ5Wms5hc/yzNKKDBxGSEPdtNJlW3wTNUuSTTtF/9ItN8A8ZC/G0yIu53Tw==", + "requires": { + "@lumino/algorithm": "1.2.3" + } + }, + "@lumino/virtualdom": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/@lumino/virtualdom/-/virtualdom-1.6.1.tgz", + "integrity": "sha512-+KdzSw8TCPwvK6qhZr4xTyp6HymvEb2Da0xPdi4RsVUNhYf2gBI03uidXHx76Vx5OIbEgCn1B+0srxvm2ZbWsQ==", "requires": { - "@phosphor/coreutils": "1.3.1", - "@phosphor/widgets": "1.8.1" + "@lumino/algorithm": "1.2.3" + } + }, + "@lumino/widgets": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/@lumino/widgets/-/widgets-1.11.1.tgz", + "integrity": "sha512-f4QDe6lVNPcjL8Vb20BiP0gzbT1rx0/1Hc719u5oW9c0Z/xrXMWwNhnb/zYM/kBBVBe3omLmCfJOiNuE0oZl0A==", + "requires": { + "@lumino/algorithm": "1.2.3", + "@lumino/commands": "1.10.1", + "@lumino/coreutils": "1.4.2", + "@lumino/disposable": "1.3.5", + "@lumino/domutils": "1.1.7", + "@lumino/dragdrop": "1.5.1", + "@lumino/keyboard": "1.1.6", + "@lumino/messaging": "1.3.3", + "@lumino/properties": "1.1.6", + "@lumino/signaling": "1.3.5", + "@lumino/virtualdom": "1.6.1" } }, "@mapbox/geojson-area": { @@ -100,113 +208,6 @@ "resolved": "https://registry.npmjs.org/@mapbox/whoots-js/-/whoots-js-3.1.0.tgz", "integrity": "sha512-Es6WcD0nO5l+2BOQS4uLfNPYQaNDfbot3X1XUoloz+x0mPDS3eeORZJl06HXjwBG1fOGwCRnzK88LMdxKRrd6Q==" }, - "@phosphor/algorithm": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@phosphor/algorithm/-/algorithm-1.1.3.tgz", - "integrity": "sha512-+dkdYTBglR+qGnLVQdCvYojNZMGxf+xSl1Jeksha3pm7niQktSFz2aR5gEPu/nI5LM8T8slTpqE4Pjvq8P+IVA==" - }, - "@phosphor/collections": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@phosphor/collections/-/collections-1.1.3.tgz", - "integrity": "sha512-J2U1xd2e5LtqoOJt4kynrjDNeHhVpJjuY2/zA0InS5kyOuWmvy79pt/KJ22n0LBNcU/fjkImqtQmbrC2Z4q2xQ==", - "requires": { - "@phosphor/algorithm": "1.1.3" - } - }, - "@phosphor/commands": { - "version": "1.6.3", - "resolved": "https://registry.npmjs.org/@phosphor/commands/-/commands-1.6.3.tgz", - "integrity": "sha512-PYNHWv6tbXAfAtKiqXuT0OBJvwbJ+RRTV60MBykMF7Vqz9UaZ9n2e/eB2EAGEFccF0PnjTCvBEZgarwwMVi8Hg==", - "requires": { - "@phosphor/algorithm": "1.1.3", - "@phosphor/coreutils": "1.3.1", - "@phosphor/disposable": "1.2.0", - "@phosphor/domutils": "1.1.3", - "@phosphor/keyboard": "1.1.3", - "@phosphor/signaling": "1.2.3" - } - }, - "@phosphor/coreutils": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/@phosphor/coreutils/-/coreutils-1.3.1.tgz", - "integrity": "sha512-9OHCn8LYRcPU/sbHm5v7viCA16Uev3gbdkwqoQqlV+EiauDHl70jmeL7XVDXdigl66Dz0LI11C99XOxp+s3zOA==" - }, - "@phosphor/disposable": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@phosphor/disposable/-/disposable-1.2.0.tgz", - "integrity": "sha512-4PoWoffdrLyWOW5Qv7I8//owvZmv57YhaxetAMWeJl13ThXc901RprL0Gxhtue2ZxL2PtUjM1207HndKo2FVjA==", - "requires": { - "@phosphor/algorithm": "1.1.3", - "@phosphor/signaling": "1.2.3" - } - }, - "@phosphor/domutils": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@phosphor/domutils/-/domutils-1.1.3.tgz", - "integrity": "sha512-5CtLAhURQXXHhNXfQydDk/luG1cDVnhlu/qw7gz8/9pht0KXIAmNg/M0LKxx2oJ9+YMNCLVWxAnHAU0yrDpWSA==" - }, - "@phosphor/dragdrop": { - "version": "1.3.3", - "resolved": "https://registry.npmjs.org/@phosphor/dragdrop/-/dragdrop-1.3.3.tgz", - "integrity": "sha512-+SrlGsVQwY8OHCWxE/Zvihpk6Rc6bytJDqOUUTZqdL8hvM9QZeopAFioPDxuo1pTj87Um6cR4ekvbTU4KZ/90w==", - "requires": { - "@phosphor/coreutils": "1.3.1", - "@phosphor/disposable": "1.2.0" - } - }, - "@phosphor/keyboard": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@phosphor/keyboard/-/keyboard-1.1.3.tgz", - "integrity": "sha512-dzxC/PyHiD6mXaESRy6PZTd9JeK+diwG1pyngkyUf127IXOEzubTIbu52VSdpGBklszu33ws05BAGDa4oBE4mQ==" - }, - "@phosphor/messaging": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@phosphor/messaging/-/messaging-1.2.3.tgz", - "integrity": "sha512-89Ps4uSRNOEQoepB/0SDoyPpNUWd6VZnmbMetmeXZJHsuJ1GLxtnq3WBdl7UCVNsw3W9NC610pWaDCy/BafRlg==", - "requires": { - "@phosphor/algorithm": "1.1.3", - "@phosphor/collections": "1.1.3" - } - }, - "@phosphor/properties": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@phosphor/properties/-/properties-1.1.3.tgz", - "integrity": "sha512-GiglqzU77s6+tFVt6zPq9uuyu/PLQPFcqZt914ZhJ4cN/7yNI/SLyMzpYZ56IRMXvzK9TUgbRna6URE3XAwFUg==" - }, - "@phosphor/signaling": { - "version": "1.2.3", - "resolved": "https://registry.npmjs.org/@phosphor/signaling/-/signaling-1.2.3.tgz", - "integrity": "sha512-DMwS0m9OgfY5ljpTsklRQPUQpTyg4obz85FyImRDacUVxUVbas95djIDEbU4s1TMzdHBBO+gfki3V4giXUvXzw==", - "requires": { - "@phosphor/algorithm": "1.1.3" - } - }, - "@phosphor/virtualdom": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/@phosphor/virtualdom/-/virtualdom-1.1.3.tgz", - "integrity": "sha512-V8PHhhnZCRa5esrC4q5VthqlLtxTo9ZV1mZ6b4YEloapca1S1nggZSQhrSlltXQjtYNUaWJZUZ/BlFD8wFtIEQ==", - "requires": { - "@phosphor/algorithm": "1.1.3" - } - }, - "@phosphor/widgets": { - "version": "1.8.1", - "resolved": "https://registry.npmjs.org/@phosphor/widgets/-/widgets-1.8.1.tgz", - "integrity": "sha512-OY5T0nAioYTitPks/lCHm7a6QpjRB/XviIT2j6WtYm5J1U8MluIPpClqZ/NQbZfm23BYpmJeiQQyZA+5YphsDA==", - "requires": { - "@phosphor/algorithm": "1.1.3", - "@phosphor/commands": "1.6.3", - "@phosphor/coreutils": "1.3.1", - "@phosphor/disposable": "1.2.0", - "@phosphor/domutils": "1.1.3", - "@phosphor/dragdrop": "1.3.3", - "@phosphor/keyboard": "1.1.3", - "@phosphor/messaging": "1.2.3", - "@phosphor/properties": "1.1.3", - "@phosphor/signaling": "1.2.3", - "@phosphor/virtualdom": "1.1.3" - } - }, "@plotly/d3-sankey": { "version": "0.7.2", "resolved": "https://registry.npmjs.org/@plotly/d3-sankey/-/d3-sankey-0.7.2.tgz", @@ -4228,9 +4229,9 @@ } }, "typescript": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.1.6.tgz", - "integrity": "sha512-tDMYfVtvpb96msS1lDX9MEdHrW4yOuZ4Kdc4Him9oU796XldPYF/t2+uKoX0BBa0hXXwDlqYQbXY5Rzjzc5hBA==", + "version": "3.7.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-3.7.5.tgz", + "integrity": "sha512-/P5lkRXkWHNAbcJIiHPfRoKqyd7bsyCma1hZNUGfn20qm64T6ZBlrzprymeu918H+mB/0rIg2gGK/BXkhhYgBw==", "dev": true }, "uglify-js": { diff --git a/packages/javascript/jupyterlab-plotly/package.json b/packages/javascript/jupyterlab-plotly/package.json index f57b5ba5d9..3fa2beecdc 100644 --- a/packages/javascript/jupyterlab-plotly/package.json +++ b/packages/javascript/jupyterlab-plotly/package.json @@ -1,6 +1,6 @@ { "name": "jupyterlab-plotly", - "version": "1.5.2", + "version": "1.5.3", "description": "The plotly JupyterLab extension", "author": "The plotly.py team", "license": "MIT", @@ -28,14 +28,14 @@ "devDependencies": { "rimraf": "^2.6.1", "ify-loader": "^1.1.0", - "typescript": "~3.1.1" + "typescript": "~3.7.0" }, "dependencies": { "plotly.js": "^1.52.1", "@types/plotly.js": "1.44.28", - "@jupyterlab/rendermime-interfaces": "^1.3.0", - "@phosphor/messaging": "^1.2.3", - "@phosphor/widgets": "^1.8.1", + "@jupyterlab/rendermime-interfaces": "^1.3.0 || ^2.0.0", + "@lumino/messaging": "^1.2.3", + "@lumino/widgets": "^1.8.1", "lodash": "^4.17.4" }, "jupyterlab": { diff --git a/packages/javascript/jupyterlab-plotly/src/javascript-renderer-extension.ts b/packages/javascript/jupyterlab-plotly/src/javascript-renderer-extension.ts index 90197b158c..b724e5df55 100644 --- a/packages/javascript/jupyterlab-plotly/src/javascript-renderer-extension.ts +++ b/packages/javascript/jupyterlab-plotly/src/javascript-renderer-extension.ts @@ -1,9 +1,9 @@ // Copyright (c) Jupyter Development Team. // Distributed under the terms of the Modified BSD License. -import { Widget } from '@phosphor/widgets'; +import { Widget } from '@lumino/widgets'; -import { Message } from '@phosphor/messaging'; +import { Message } from '@lumino/messaging'; import { IRenderMime } from '@jupyterlab/rendermime-interfaces'; diff --git a/packages/javascript/plotlywidget/package-lock.json b/packages/javascript/plotlywidget/package-lock.json index 40a8aa604c..6273fc79f8 100644 --- a/packages/javascript/plotlywidget/package-lock.json +++ b/packages/javascript/plotlywidget/package-lock.json @@ -1,6 +1,6 @@ { "name": "plotlywidget", - "version": "1.5.2", + "version": "1.5.3", "lockfileVersion": 1, "requires": true, "dependencies": { diff --git a/packages/javascript/plotlywidget/package.json b/packages/javascript/plotlywidget/package.json index 4eb14c5132..7bd03cf5c7 100644 --- a/packages/javascript/plotlywidget/package.json +++ b/packages/javascript/plotlywidget/package.json @@ -1,6 +1,6 @@ { "name": "plotlywidget", - "version": "1.5.2", + "version": "1.5.3", "description": "The plotly JupyterLab extension", "author": "The plotly.py team", "license": "MIT", diff --git a/packages/python/chart-studio/chart_studio/tests/test_core/test_tools/test_get_embed.py b/packages/python/chart-studio/chart_studio/tests/test_core/test_tools/test_get_embed.py index bbb6499fca..77709176e5 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_core/test_tools/test_get_embed.py +++ b/packages/python/chart-studio/chart_studio/tests/test_core/test_tools/test_get_embed.py @@ -2,7 +2,7 @@ from unittest import TestCase -from nose.tools import raises +import pytest import chart_studio.tools as tls from _plotly_utils.exceptions import PlotlyError @@ -13,10 +13,10 @@ def test_get_valid_embed(): tls.get_embed(url) -@raises(PlotlyError) def test_get_invalid_embed(): url = "https://plot.ly/~PlotBot/a/" - tls.get_embed(url) + with pytest.raises(PlotlyError): + tls.get_embed(url) class TestGetEmbed(TestCase): diff --git a/packages/python/chart-studio/chart_studio/tests/test_optional/test_matplotlylib/test_plot_mpl.py b/packages/python/chart-studio/chart_studio/tests/test_optional/test_matplotlylib/test_plot_mpl.py index ac35292846..a4b2bf52a5 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_optional/test_matplotlylib/test_plot_mpl.py +++ b/packages/python/chart-studio/chart_studio/tests/test_optional/test_matplotlylib/test_plot_mpl.py @@ -7,13 +7,12 @@ """ from __future__ import absolute_import -from nose.plugins.attrib import attr -from nose.tools import raises import _plotly_utils.exceptions from plotly import optional_imports from chart_studio.plotly import plotly as py from unittest import TestCase +import pytest matplotlylib = optional_imports.get_module("plotly.matplotlylib") @@ -21,26 +20,25 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib class PlotMPLTest(TestCase): def setUp(self): py.sign_in("PlotlyImageTest", "786r5mecv0", plotly_domain="https://plot.ly") - @raises(_plotly_utils.exceptions.PlotlyGraphObjectError) def test_update_type_error(self): fig, ax = plt.subplots() ax.plot([1, 2, 3]) update = [] - py.plot_mpl(fig, update=update, filename="nosetests", auto_open=False) + with pytest.raises(_plotly_utils.exceptions.PlotlyGraphObjectError): + py.plot_mpl(fig, update=update, filename="nosetests", auto_open=False) - @raises(KeyError) def test_update_validation_error(self): fig, ax = plt.subplots() ax.plot([1, 2, 3]) update = {"invalid": "anything"} - py.plot_mpl(fig, update=update, filename="nosetests", auto_open=False) + with pytest.raises(KeyError): + py.plot_mpl(fig, update=update, filename="nosetests", auto_open=False) - @attr("slow") def test_update(self): fig, ax = plt.subplots() ax.plot([1, 2, 3]) diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_file/test_file.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_file/test_file.py index 3b3746414a..4dccef1446 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_file/test_file.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_file/test_file.py @@ -8,14 +8,12 @@ import random import string -from nose.plugins.attrib import attr from chart_studio import plotly as py from chart_studio.exceptions import PlotlyRequestError from chart_studio.tests.utils import PlotlyTestCase -@attr("slow") class FolderAPITestCase(PlotlyTestCase): def setUp(self): super(FolderAPITestCase, self).setUp() diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_figure/test_get_figure.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_figure/test_get_figure.py index 69b6da830c..b0c4ca68ba 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_figure/test_get_figure.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_figure/test_get_figure.py @@ -10,7 +10,6 @@ from unittest import skipIf import six -from nose.plugins.attrib import attr import _plotly_utils.exceptions from chart_studio import exceptions @@ -38,7 +37,6 @@ def is_trivial(obj): class GetFigureTest(PlotlyTestCase): - @attr("slow") def test_get_figure(self): un = "PlotlyImageTest" ak = "786r5mecv0" @@ -46,7 +44,6 @@ def test_get_figure(self): py.sign_in(un, ak) py.get_figure("PlotlyImageTest", str(file_id)) - @attr("slow") def test_get_figure_with_url(self): un = "PlotlyImageTest" ak = "786r5mecv0" @@ -62,7 +59,6 @@ def test_get_figure_invalid_1(self): with self.assertRaises(exceptions.PlotlyError): py.get_figure(url) - @attr("slow") def test_get_figure_invalid_2(self): un = "PlotlyImageTest" ak = "786r5mecv0" @@ -80,7 +76,6 @@ def test_get_figure_invalid_3(self): with self.assertRaises(ValueError): py.get_figure(url) - @attr("slow") def test_get_figure_does_not_exist(self): un = "PlotlyImageTest" ak = "786r5mecv0" @@ -89,7 +84,6 @@ def test_get_figure_does_not_exist(self): with self.assertRaises(_plotly_utils.exceptions.PlotlyError): py.get_figure(url) - @attr("slow") def test_get_figure_raw(self): un = "PlotlyImageTest" ak = "786r5mecv0" diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_requests/test_get_requests.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_requests/test_get_requests.py index a57487f310..1f7c96369f 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_requests/test_get_requests.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_get_requests/test_get_requests.py @@ -9,7 +9,6 @@ import requests import six -from nose.plugins.attrib import attr import json as _json from chart_studio.tests.utils import PlotlyTestCase @@ -25,7 +24,6 @@ class GetRequestsTest(PlotlyTestCase): - @attr("slow") def test_user_does_not_exist(self): username = "user_does_not_exist" api_key = "invalid-apikey" @@ -47,7 +45,6 @@ def test_user_does_not_exist(self): self.assertEqual(response.status_code, 404) self.assertEqual(content["error"], error_message) - @attr("slow") def test_file_does_not_exist(self): username = "PlotlyImageTest" api_key = "786r5mecv0" @@ -68,7 +65,6 @@ def test_file_does_not_exist(self): self.assertEqual(response.status_code, 404) self.assertEqual(content["error"], error_message) - @attr("slow") def test_wrong_api_key(self): # TODO: does this test the right thing? username = "PlotlyImageTest" api_key = "invalid-apikey" @@ -85,7 +81,6 @@ def test_wrong_api_key(self): # TODO: does this test the right thing? # Locked File # TODO - @attr("slow") def test_private_permission_defined(self): username = "PlotlyImageTest" api_key = "786r5mecv0" @@ -105,7 +100,6 @@ def test_private_permission_defined(self): # Private File that is shared # TODO - @attr("slow") def test_missing_headers(self): file_owner = "get_test_user" file_id = 0 @@ -121,7 +115,6 @@ def test_missing_headers(self): content = _json.loads(response.content.decode("unicode_escape")) self.assertEqual(response.status_code, 422) - @attr("slow") def test_valid_request(self): username = "PlotlyImageTest" api_key = "786r5mecv0" diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_grid/test_grid.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_grid/test_grid.py index 669dd46f55..ac542e70fb 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_grid/test_grid.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_grid/test_grid.py @@ -11,7 +11,6 @@ import string from unittest import skip -from nose.plugins.attrib import attr from chart_studio import plotly as py from chart_studio.exceptions import InputError, PlotlyRequestError @@ -54,11 +53,9 @@ def upload_and_return_grid(self): return g # Nominal usage - @attr("slow") def test_grid_upload(self): self.upload_and_return_grid() - @attr("slow") def test_grid_upload_in_new_folder(self): g = self.get_grid() path = "new folder: {0}/grid in folder {1}".format( @@ -66,7 +63,6 @@ def test_grid_upload_in_new_folder(self): ) py.grid_ops.upload(g, path, auto_open=False) - @attr("slow") def test_grid_upload_in_existing_folder(self): g = self.get_grid() folder = random_filename() @@ -75,19 +71,16 @@ def test_grid_upload_in_existing_folder(self): path = "existing folder: {0}/grid in folder {1}".format(folder, filename) py.grid_ops.upload(g, path, auto_open=False) - @attr("slow") def test_column_append(self): g = self.upload_and_return_grid() new_col = Column([1, 5, 3], "new col") py.grid_ops.append_columns([new_col], grid=g) - @attr("slow") def test_row_append(self): g = self.upload_and_return_grid() new_rows = [[1, 2], [10, 20]] py.grid_ops.append_rows(new_rows, grid=g) - @attr("slow") def test_plot_from_grid(self): g = self.upload_and_return_grid() url = py.plot( @@ -97,7 +90,6 @@ def test_plot_from_grid(self): ) return url, g - @attr("slow") def test_get_figure_from_references(self): url, g = self.test_plot_from_grid() fig = py.get_figure(url) @@ -143,7 +135,6 @@ def test_row_append_of_non_uploaded_grid(self): py.grid_ops.append_rows(rows, grid=g) # Input Errors - @attr("slow") def test_unequal_length_rows(self): g = self.upload_and_return_grid() rows = [[1, 2], ["to", "many", "cells"]] @@ -158,7 +149,6 @@ def test_duplicate_columns(self): Grid([c1, c2]) # Test delete - @attr("slow") def test_delete_grid(self): g = self.get_grid() fn = random_filename() diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_image/test_image.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_image/test_image.py index d9c5253c82..594454d7f1 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_image/test_image.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_image/test_image.py @@ -5,79 +5,60 @@ import os import itertools import warnings - -from nose.plugins.attrib import attr +import pytest import _plotly_utils.exceptions from chart_studio.plotly import plotly as py -from chart_studio.tests.utils import PlotlyTestCase - - -@attr("slow") -class TestImage(PlotlyTestCase): - def setUp(self): - super(TestImage, self).setUp() - py.sign_in("PlotlyImageTest", "786r5mecv0") - self.data = [{"x": [1, 2, 3], "y": [3, 1, 6]}] - - -def _generate_image_get_returns_valid_image_test(image_format, width, height, scale): - def test(self): - # TODO: better understand why this intermittently fails. See #649 - num_attempts = 5 - for i in range(num_attempts): - if i > 0: - warnings.warn("image test intermittently failed, retrying...") - try: - image = py.image.get(self.data, image_format, width, height, scale) - if image_format in ["png", "jpeg"]: - assert imghdr.what("", image) == image_format - return - except (KeyError, _plotly_utils.exceptions.PlotlyError): - if i == num_attempts - 1: - raise - return test - - -def _generate_image_save_as_saves_valid_image(image_format, width, height, scale): - def _test(self): - f, filename = tempfile.mkstemp(".{}".format(image_format)) - py.image.save_as( - self.data, - filename, - format=image_format, - width=width, - height=height, - scale=scale, - ) - if image_format in ["png", "jpeg"]: - assert imghdr.what(filename) == image_format - else: - assert os.path.getsize(filename) > 0 +from chart_studio.tests.utils import PlotlyTestCase - os.remove(filename) - return _test +@pytest.fixture +def setup_image(): + py.sign_in("PlotlyImageTest", "786r5mecv0") + data = [{"x": [1, 2, 3], "y": [3, 1, 6]}] + return data -kwargs = { - "format": ["png", "jpeg", "pdf", "svg", "emf"], - "width": [None, 300], - "height": [None, 300], - "scale": [None, 5], -} -for args in itertools.product( - kwargs["format"], kwargs["width"], kwargs["height"], kwargs["scale"] +@pytest.mark.parametrize("image_format", ("png", "jpeg", "pdf", "svg", "emf")) +@pytest.mark.parametrize("width", (None, 300)) +@pytest.mark.parametrize("height", (None, 300)) +@pytest.mark.parametrize("scale", (None, 3)) +def test_image_get_returns_valid_image_test( + setup_image, image_format, width, height, scale ): - for test_generator in [ - _generate_image_get_returns_valid_image_test, - _generate_image_save_as_saves_valid_image, - ]: - - _test = test_generator(*args) - arg_string = ", ".join([str(a) for a in args]) - test_name = test_generator.__name__.replace("_generate", "test") - test_name += "({})".format(arg_string) - setattr(TestImage, test_name, _test) + # TODO: better understand why this intermittently fails. See #649 + data = setup_image + num_attempts = 2 + for i in range(num_attempts): + if i > 0: + warnings.warn("image test intermittently failed, retrying...") + try: + image = py.image.get(data, image_format, width, height, scale) + if image_format in ["png", "jpeg"]: + assert imghdr.what("", image) == image_format + return + except (KeyError, _plotly_utils.exceptions.PlotlyError): + if i == num_attempts - 1: + raise + + +@pytest.mark.parametrize("image_format", ("png", "jpeg", "pdf", "svg", "emf")) +@pytest.mark.parametrize("width", (None, 300)) +@pytest.mark.parametrize("height", (None, 300)) +@pytest.mark.parametrize("scale", (None, 3)) +def test_image_save_as_saves_valid_image( + setup_image, image_format, width, height, scale +): + data = setup_image + f, filename = tempfile.mkstemp(".{}".format(image_format)) + py.image.save_as( + data, filename, format=image_format, width=width, height=height, scale=scale, + ) + if image_format in ["png", "jpeg"]: + assert imghdr.what(filename) == image_format + else: + assert os.path.getsize(filename) > 0 + + os.remove(filename) diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_meta/test_meta.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_meta/test_meta.py index d26fb8c601..2af3ff9df3 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_meta/test_meta.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_meta/test_meta.py @@ -10,7 +10,6 @@ import random import string -from nose.plugins.attrib import attr from unittest import skip from chart_studio import plotly as py @@ -33,7 +32,6 @@ def random_filename(self): unique_filename = "Valid Grid with Meta " + "".join(random_chars) return unique_filename - @attr("slow") def test_upload_meta(self): unique_filename = self.random_filename() grid_url = py.grid_ops.upload(self._grid, unique_filename, auto_open=False) @@ -41,7 +39,6 @@ def test_upload_meta(self): # Add some Metadata to that grid py.meta_ops.upload(self._meta, grid_url=grid_url) - @attr("slow") def test_upload_meta_with_grid(self): c1 = Column([1, 2, 3, 4], "first column") Grid([c1]) diff --git a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_plotly/test_plot.py b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_plotly/test_plot.py index 3982bde7d8..7351f1ee2a 100644 --- a/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_plotly/test_plot.py +++ b/packages/python/chart-studio/chart_studio/tests/test_plot_ly/test_plotly/test_plot.py @@ -13,7 +13,6 @@ import json as _json import warnings -from nose.plugins.attrib import attr import chart_studio.tools as tls import plotly.tools @@ -37,7 +36,6 @@ def setUp(self): py.sign_in("PlotlyImageTest", "786r5mecv0") self.simple_figure = {"data": [{"x": [1, 2, 3], "y": [2, 1, 2]}]} - @attr("slow") def test_plot_valid(self): fig = { "data": [{"x": (1, 2, 3), "y": (2, 1, 2)}], @@ -155,7 +153,6 @@ def test_plot_option_logic_only_sharing_given(self): } self.assertEqual(plot_option_logic, expected_plot_option_logic) - @attr("slow") def test_plot_url_given_sharing_key(self): # Give share_key is requested, the retun url should contain @@ -175,7 +172,6 @@ def test_plot_url_given_sharing_key(self): self.assertTrue("share_key=" in plot_url) - @attr("slow") def test_plot_url_response_given_sharing_key(self): # Given share_key is requested, get request of the url should @@ -196,7 +192,6 @@ def test_plot_url_response_given_sharing_key(self): self.assertEqual(response.status_code, 200) - @attr("slow") def test_private_plot_response_with_and_without_share_key(self): # The json file of the private plot should be 404 and once diff --git a/packages/python/chart-studio/tox.ini b/packages/python/chart-studio/tox.ini index 4a43598e52..faddb36305 100644 --- a/packages/python/chart-studio/tox.ini +++ b/packages/python/chart-studio/tox.ini @@ -24,15 +24,14 @@ ; PASSING ADDITONAL ARGUMENTS TO TEST COMMANDS ; The {posargs} is tox-specific and passes in any command line args after `--`. ; For example, given the testing command in *this* file: -; nosetests {posargs} -x plotly/tests/test_core +; pytest {posargs} -x plotly/tests/test_core ; ; The following command: -; tox -- -a '!slow' +; tox -- -k 'not nodev' ; ; Tells tox to call: -; nosetests -a '!slow' -x plotly/tests/test_core +; pytest -k 'not nodev' -x plotly/tests/test_core ; -; Which is a nice way to skip slow tests for faster testing cycles. [tox] ; The py{A,B,C}-{X,Y} generates a matrix of envs: @@ -72,16 +71,16 @@ deps= basepython={env:PLOTLY_TOX_PYTHON_27:} commands= python --version - nosetests {posargs} -x chart_studio/tests/ + pytest {posargs} -x chart_studio/tests/ [testenv:py35-plot_ly] basepython={env:PLOTLY_TOX_PYTHON_35:} commands= python --version - nosetests {posargs} -x chart_studio/tests/ + pytest {posargs} -x chart_studio/tests/ [testenv:py37-plot_ly] basepython={env:PLOTLY_TOX_PYTHON_37:} commands= python --version - nosetests {posargs} -x chart_studio/tests/ + pytest {posargs} -x chart_studio/tests/ diff --git a/packages/python/plotly/optional-requirements.txt b/packages/python/plotly/optional-requirements.txt index d0bb959e0d..9886dcd187 100644 --- a/packages/python/plotly/optional-requirements.txt +++ b/packages/python/plotly/optional-requirements.txt @@ -14,7 +14,6 @@ numpy ## testing dependencies ## coverage==4.3.1 mock==2.0.0 -nose==1.3.3 pytest==3.5.1 backports.tempfile==1.0 xarray diff --git a/packages/python/plotly/plotly/_widget_version.py b/packages/python/plotly/plotly/_widget_version.py index d6c83d0794..ee9406e56f 100644 --- a/packages/python/plotly/plotly/_widget_version.py +++ b/packages/python/plotly/plotly/_widget_version.py @@ -2,4 +2,4 @@ # for automated dev builds # # It is edited by hand prior to official releases -__frontend_version__ = "1.5.2" +__frontend_version__ = "1.5.3" diff --git a/packages/python/plotly/plotly/matplotlylib/mplexporter/tests/test_basic.py b/packages/python/plotly/plotly/matplotlylib/mplexporter/tests/test_basic.py index 1c4dfb3e92..b86759fa18 100644 --- a/packages/python/plotly/plotly/matplotlylib/mplexporter/tests/test_basic.py +++ b/packages/python/plotly/plotly/matplotlylib/mplexporter/tests/test_basic.py @@ -1,7 +1,7 @@ import matplotlib import numpy as np from distutils.version import LooseVersion -from nose.plugins.skip import SkipTest +import pytest from numpy.testing import assert_warns from ..exporter import Exporter @@ -168,7 +168,7 @@ def test_image(): # Test fails for matplotlib 1.5+ because the size of the image # generated by matplotlib has changed. if LooseVersion(matplotlib.__version__) >= LooseVersion('1.5.0'): - raise SkipTest("Test fails for matplotlib version > 1.5.0"); + pytest.skip("Test fails for matplotlib version > 1.5.0") np.random.seed(0) # image size depends on the seed fig, ax = plt.subplots(figsize=(2, 2)) ax.imshow(np.random.random((10, 10)), diff --git a/packages/python/plotly/plotly/tests/test_core/test_colors/test_colors.py b/packages/python/plotly/plotly/tests/test_core/test_colors/test_colors.py index 053b595e50..e382e9bfd7 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_colors/test_colors.py +++ b/packages/python/plotly/plotly/tests/test_core/test_colors/test_colors.py @@ -1,6 +1,5 @@ from unittest import TestCase -from nose.tools import raises import plotly.tools as tls from plotly.exceptions import PlotlyError import plotly.colors as colors diff --git a/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_move_delete_traces.py b/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_move_delete_traces.py index a644cf6594..9a8e332549 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_move_delete_traces.py +++ b/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_move_delete_traces.py @@ -1,6 +1,6 @@ import sys from unittest import TestCase -from nose.tools import raises +import pytest import plotly.graph_objs as go @@ -80,12 +80,12 @@ def test_move_and_delete_traces(self): self.figure._send_deleteTraces_msg.assert_called_once_with([1]) self.figure._send_moveTraces_msg.assert_called_once_with([0, 1], [1, 0]) - @raises(ValueError) def test_validate_assigned_traces_are_subset(self): traces = self.figure.data - self.figure.data = [traces[2], go.Scatter(y=[3, 2, 1]), traces[1]] + with pytest.raises(ValueError): + self.figure.data = [traces[2], go.Scatter(y=[3, 2, 1]), traces[1]] - @raises(ValueError) def test_validate_assigned_traces_are_not_duplicates(self): traces = self.figure.data - self.figure.data = [traces[2], traces[1], traces[1]] + with pytest.raises(ValueError): + self.figure.data = [traces[2], traces[1], traces[1]] diff --git a/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_on_change.py b/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_on_change.py index 5f2aeb610f..8e2ce3426d 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_on_change.py +++ b/packages/python/plotly/plotly/tests/test_core/test_figure_messages/test_on_change.py @@ -1,6 +1,6 @@ import sys from unittest import TestCase -from nose.tools import raises +import pytest import plotly.graph_objs as go @@ -24,26 +24,26 @@ def setUp(self): # on_change validation # -------------------- - @raises(ValueError) def test_raise_if_no_figure(self): scatt = go.Scatter() fn = MagicMock() - scatt.on_change(fn, "x") + with pytest.raises(ValueError): + scatt.on_change(fn, "x") - @raises(ValueError) def test_raise_on_frame_hierarchy(self): fn = MagicMock() - self.figure.frames[0].layout.xaxis.on_change(fn, "range") + with pytest.raises(ValueError): + self.figure.frames[0].layout.xaxis.on_change(fn, "range") - @raises(ValueError) def test_validate_property_path_nested(self): fn = MagicMock() - self.figure.layout.xaxis.on_change(fn, "bogus") + with pytest.raises(ValueError): + self.figure.layout.xaxis.on_change(fn, "bogus") - @raises(ValueError) def test_validate_property_path_nested(self): fn = MagicMock() - self.figure.layout.on_change(fn, "xaxis.titlefont.bogus") + with pytest.raises(ValueError): + self.figure.layout.on_change(fn, "xaxis.titlefont.bogus") # Python triggered changes # ------------------------ diff --git a/packages/python/plotly/plotly/tests/test_core/test_figure_widget_backend/test_validate_no_frames.py b/packages/python/plotly/plotly/tests/test_core/test_figure_widget_backend/test_validate_no_frames.py index d7331872e8..81f0749695 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_figure_widget_backend/test_validate_no_frames.py +++ b/packages/python/plotly/plotly/tests/test_core/test_figure_widget_backend/test_validate_no_frames.py @@ -1,29 +1,29 @@ from unittest import TestCase import plotly.graph_objs as go -from nose.tools import raises +import pytest class TestNoFrames(TestCase): if "FigureWidget" in go.__dict__.keys(): - @raises(ValueError) def test_no_frames_in_constructor_kwarg(self): - go.FigureWidget(frames=[{}]) + with pytest.raises(ValueError): + go.FigureWidget(frames=[{}]) def test_emtpy_frames_ok_as_constructor_kwarg(self): go.FigureWidget(frames=[]) - @raises(ValueError) def test_no_frames_in_constructor_dict(self): - go.FigureWidget({"frames": [{}]}) + with pytest.raises(ValueError): + go.FigureWidget({"frames": [{}]}) def test_emtpy_frames_ok_as_constructor_dict_key(self): go.FigureWidget({"frames": []}) - @raises(ValueError) def test_no_frames_assignment(self): fig = go.FigureWidget() - fig.frames = [{}] + with pytest.raises(ValueError): + fig.frames = [{}] def test_emtpy_frames_assignment_ok(self): fig = go.FigureWidget() diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_annotations.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_annotations.py index c551bc5be1..65aff11e98 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_annotations.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_annotations.py @@ -8,8 +8,6 @@ from __future__ import absolute_import from unittest import skip -from nose.tools import raises - from plotly.exceptions import ( PlotlyError, PlotlyDictKeyError, diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_append_trace.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_append_trace.py index 9f52249222..f01770ceb8 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_append_trace.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_append_trace.py @@ -1,6 +1,5 @@ from __future__ import absolute_import - -from nose.tools import raises +import pytest from plotly.graph_objs import ( Data, @@ -19,31 +18,31 @@ import copy -@raises(Exception) def test_print_grid_before_make_subplots(): fig = Figure() - fig.print_grid() + with pytest.raises(Exception): + fig.print_grid() -@raises(Exception) def test_append_trace_before_make_subplots(): trace = Scatter(x=[1, 2, 3], y=[2, 3, 4]) fig = Figure() - fig.append_trace(trace, 2, 2) + with pytest.raises(Exception): + fig.append_trace(trace, 2, 2) -@raises(Exception) def test_append_trace_row_out_of_range(): trace = Scatter(x=[1, 2, 3], y=[2, 3, 4]) fig = tls.make_subplots(rows=2, cols=3) - fig.append_trace(trace, 10, 2) + with pytest.raises(Exception): + fig.append_trace(trace, 10, 2) -@raises(Exception) def test_append_trace_col_out_of_range(): trace = Scatter(x=[1, 2, 3], y=[2, 3, 4]) fig = tls.make_subplots(rows=2, cols=3) - fig.append_trace(trace, 2, 0) + with pytest.raises(Exception): + fig.append_trace(trace, 2, 0) def test_append_scatter(): diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_constructor.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_constructor.py index 870b11b3de..09fa78857b 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_constructor.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_constructor.py @@ -1,6 +1,6 @@ from unittest import TestCase import plotly.graph_objs as go -from nose.tools import raises +import pytest class TestGraphObjConstructor(TestCase): @@ -28,18 +28,18 @@ def test_kwarg_takes_precedence(self): m.to_plotly_json(), {"color": "blue", "size": 12, "opacity": 0.6} ) - @raises(ValueError) def test_invalid_kwarg(self): - go.scatter.Marker(bogus=[1, 2, 3]) + with pytest.raises(ValueError): + go.scatter.Marker(bogus=[1, 2, 3]) - @raises(ValueError) def test_invalid_arg(self): - go.scatter.Marker([1, 2, 3]) + with pytest.raises(ValueError): + go.scatter.Marker([1, 2, 3]) - @raises(ValueError) def test_valid_arg_with_invalid_key_name(self): - go.scatter.Marker({"bogus": 12}) + with pytest.raises(ValueError): + go.scatter.Marker({"bogus": 12}) - @raises(ValueError) def test_valid_arg_with_invalid_key_value(self): - go.scatter.Marker({"color": "bogus"}) + with pytest.raises(ValueError): + go.scatter.Marker({"color": "bogus"}) diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_data.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_data.py index faec80efcd..136a043a46 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_data.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_data.py @@ -8,7 +8,6 @@ from __future__ import absolute_import from unittest import skip -from nose.tools import raises from plotly.exceptions import ( PlotlyError, @@ -30,7 +29,6 @@ def test_trivial(): assert Data() == list() -# @raises(PlotlyError) def test_weird_instantiation(): # Python allows this... assert Data({}) == [] @@ -43,26 +41,21 @@ def test_dict_instantiation(): Data([{"type": "scatter"}]) -# @raises(PlotlyDictKeyError) def test_dict_instantiation_key_error(): assert Data([{"not-a-key": "anything"}]) == [{"not-a-key": "anything"}] -# @raises(PlotlyDictValueError) def test_dict_instantiation_key_error_2(): assert Data([{"marker": "not-a-dict"}]) == [{"marker": "not-a-dict"}] -# @raises(PlotlyDataTypeError) def test_dict_instantiation_type_error(): assert Data([{"type": "invalid_type"}]) == [{"type": "invalid_type"}] -# @raises(PlotlyListEntryError) def test_dict_instantiation_graph_obj_error_0(): assert Data([Data()]) == [[]] -# raises(PlotlyListEntryError) def test_dict_instantiation_graph_obj_error_2(): assert Data([Annotations()]) == [[]] diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_error_bars.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_error_bars.py index 7526135d15..d12abbc24c 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_error_bars.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_error_bars.py @@ -7,7 +7,6 @@ """ from __future__ import absolute_import -from nose.tools import raises from plotly.graph_objs import ErrorX, ErrorY from plotly.exceptions import PlotlyDictKeyError diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_figure_properties.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_figure_properties.py index 26a256de9f..99ee26e0ba 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_figure_properties.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_figure_properties.py @@ -1,6 +1,7 @@ from unittest import TestCase +import pytest + import plotly.graph_objs as go -from nose.tools import raises import plotly.io as pio @@ -81,21 +82,21 @@ def test_property_assignment_dots(self): self.figure["frames[0].layout.yaxis.title.text"] = "f2" self.assertEqual(self.figure["frames.0.layout.yaxis.title.text"], "f2") - @raises(AttributeError) def test_access_invalid_attr(self): - self.figure.bogus + with pytest.raises(AttributeError): + self.figure.bogus - @raises(KeyError) def test_access_invalid_item(self): - self.figure["bogus"] + with pytest.raises(KeyError): + self.figure["bogus"] - @raises(AttributeError) def test_assign_invalid_attr(self): - self.figure.bogus = "val" + with pytest.raises(AttributeError): + self.figure.bogus = "val" - @raises(KeyError) def test_access_invalid_item(self): - self.figure["bogus"] = "val" + with pytest.raises(KeyError): + self.figure["bogus"] = "val" # Update def test_update_layout(self): @@ -202,9 +203,9 @@ def test_update_frames(self): ) self.assertEqual(self.figure.frames[0].layout.yaxis.title.text, "f4") - @raises(ValueError) def test_update_invalid_attr(self): - self.figure.layout.update({"xaxis": {"bogus": 32}}) + with pytest.raises(ValueError): + self.figure.layout.update({"xaxis": {"bogus": 32}}) # plotly_restyle def test_plotly_restyle(self): @@ -218,13 +219,13 @@ def test_plotly_restyle(self): self.assertEqual(self.figure.data[0].marker.color, "blue") - @raises(ValueError) def test_restyle_validate_property(self): - self.figure.plotly_restyle({"bogus": 3}, trace_indexes=[0]) + with pytest.raises(ValueError): + self.figure.plotly_restyle({"bogus": 3}, trace_indexes=[0]) - @raises(ValueError) def test_restyle_validate_property_nested(self): - self.figure.plotly_restyle({"marker.bogus": 3}, trace_indexes=[0]) + with pytest.raises(ValueError): + self.figure.plotly_restyle({"marker.bogus": 3}, trace_indexes=[0]) # plotly_relayout def test_plotly_relayout(self): @@ -235,17 +236,17 @@ def test_plotly_relayout(self): self.figure.plotly_relayout(relayout_data={"xaxis.range": [10, 20]}) self.assertEqual(self.figure.layout.xaxis.range, (10, 20)) - @raises(ValueError) def test_relayout_validate_property(self): - self.figure.plotly_relayout({"bogus": [1, 3]}) + with pytest.raises(ValueError): + self.figure.plotly_relayout({"bogus": [1, 3]}) - @raises(ValueError) def test_relayout_validate_property_nested(self): - self.figure.plotly_relayout({"xaxis.bogus": [1, 3]}) + with pytest.raises(ValueError): + self.figure.plotly_relayout({"xaxis.bogus": [1, 3]}) - @raises(ValueError) def test_relayout_validate_unintialized_subplot(self): - self.figure.plotly_relayout({"xaxis2.range": [1, 3]}) + with pytest.raises(ValueError): + self.figure.plotly_relayout({"xaxis2.range": [1, 3]}) # plotly_update def test_plotly_update_layout(self): @@ -267,10 +268,10 @@ def test_plotly_update_data(self): self.assertEqual(self.figure.data[0].marker.color, "blue") - @raises(ValueError) def test_plotly_update_validate_property_trace(self): - self.figure.plotly_update(restyle_data={"bogus": 3}, trace_indexes=[0]) + with pytest.raises(ValueError): + self.figure.plotly_update(restyle_data={"bogus": 3}, trace_indexes=[0]) - @raises(ValueError) def test_plotly_update_validate_property_layout(self): - self.figure.plotly_update(relayout_data={"xaxis.bogus": [1, 3]}) + with pytest.raises(ValueError): + self.figure.plotly_update(relayout_data={"xaxis.bogus": [1, 3]}) diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_frames.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_frames.py index 37a33b2026..c7dc96d8e8 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_frames.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_frames.py @@ -4,7 +4,7 @@ from plotly.graph_objs import Bar, Frames, Frame, Layout -from nose.plugins.attrib import attr +import pytest import re @@ -43,7 +43,7 @@ def test_non_string_frame(self): # with self.assertRaises(exceptions.PlotlyListEntryError): # frames.append(0) - @attr("nodev") + @pytest.mark.nodev def test_deeply_nested_layout_attributes(self): frames = Frame frames.layout = [Layout()] diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_layout_subplots.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_layout_subplots.py index 1401512ada..037d238498 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_layout_subplots.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_layout_subplots.py @@ -1,6 +1,7 @@ from unittest import TestCase +import pytest + import plotly.graph_objs as go -from nose.tools import raises import plotly.io as pio @@ -33,13 +34,13 @@ def test_initial_access_subplots(self): self.assertIs(self.layout.mapbox, self.layout.mapbox1) self.assertIs(self.layout.polar, self.layout.polar1) - @raises(AttributeError) def test_initial_access_subplot2(self): - self.layout.xaxis2 + with pytest.raises(AttributeError): + self.layout.xaxis2 - @raises(KeyError) def test_initial_access_subplot2(self): - self.layout["xaxis2"] + with pytest.raises(KeyError): + self.layout["xaxis2"] def test_assign_subplots(self): self.assertIsNone(self.layout.xaxis.title.text) diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_properties_validated.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_properties_validated.py index e31d1dad09..c3edcfb111 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_properties_validated.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_properties_validated.py @@ -1,6 +1,6 @@ from unittest import TestCase import plotly.graph_objs as go -from nose.tools import raises +import pytest class TestPropertyValidation(TestCase): @@ -9,43 +9,43 @@ def setUp(self): self.scatter = go.Scatter() self.scatter.name = "Scatter 1" - @raises(ValueError) def test_validators_work_attr(self): """ Note: all of the individual validators are tested in `_plotly_utils/tests/validators`. Here we're just making sure that datatypes make use of validators """ - self.scatter.name = [1, 2, 3] + with pytest.raises(ValueError): + self.scatter.name = [1, 2, 3] - @raises(ValueError) def test_validators_work_item(self): """ Note: all of the individual validators are tested in `_plotly_utils/tests/validators`. Here we're just making sure that datatypes make use of validators """ - self.scatter["name"] = [1, 2, 3] + with pytest.raises(ValueError): + self.scatter["name"] = [1, 2, 3] - @raises(ValueError) def test_invalid_attr_assignment(self): - self.scatter.bogus = 87 + with pytest.raises(ValueError): + self.scatter.bogus = 87 - @raises(ValueError) def test_invalid_item_assignment(self): - self.scatter["bogus"] = 87 + with pytest.raises(ValueError): + self.scatter["bogus"] = 87 - @raises(ValueError) def test_invalid_dot_assignment(self): - self.scatter["marker.bogus"] = 87 + with pytest.raises(ValueError): + self.scatter["marker.bogus"] = 87 - @raises(ValueError) def test_invalid_tuple_assignment(self): - self.scatter[("marker", "bogus")] = 87 + with pytest.raises(ValueError): + self.scatter[("marker", "bogus")] = 87 - @raises(ValueError) def test_invalid_constructor_kwarg(self): - go.Scatter(bogus=87) + with pytest.raises(ValueError): + go.Scatter(bogus=87) class TestPropertyPresentation(TestCase): diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_scatter.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_scatter.py index d3af52db2a..78d3aa1d77 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_scatter.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_scatter.py @@ -7,7 +7,6 @@ """ from __future__ import absolute_import -from nose.tools import raises from plotly.graph_objs import Scatter from plotly.exceptions import PlotlyError diff --git a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_template.py b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_template.py index 47bbf12b06..8010e962a9 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_template.py +++ b/packages/python/plotly/plotly/tests/test_core/test_graph_objs/test_template.py @@ -2,7 +2,7 @@ import copy from unittest import TestCase -from nose.tools import raises +import pytest import plotly.io as pio import plotly.graph_objs as go @@ -105,27 +105,31 @@ def test_defaults_in_property_assignment(self): }, ) - @raises(ValueError) def test_invalid_defaults_property_name_constructor(self): - go.Figure(layout={"template": {"layout": {"imagedefaults": {"bogus": 500}}}}) + with pytest.raises(ValueError): + go.Figure( + layout={"template": {"layout": {"imagedefaults": {"bogus": 500}}}} + ) - @raises(ValueError) def test_invalid_defaults_property_value_constructor(self): - go.Figure( - layout={ - "template": {"layout": {"imagedefaults": {"sizex": "str not number"}}} - } - ) + with pytest.raises(ValueError): + go.Figure( + layout={ + "template": { + "layout": {"imagedefaults": {"sizex": "str not number"}} + } + } + ) - @raises(ValueError) def test_invalid_defaults_property_name_constructor(self): - go.Figure(layout={"template": {"layout": {"xaxis": {"bogus": 500}}}}) + with pytest.raises(ValueError): + go.Figure(layout={"template": {"layout": {"xaxis": {"bogus": 500}}}}) - @raises(ValueError) def test_invalid_defaults_property_value_constructor(self): - go.Figure( - layout={"template": {"layout": {"xaxis": {"range": "str not tuple"}}}} - ) + with pytest.raises(ValueError): + go.Figure( + layout={"template": {"layout": {"xaxis": {"range": "str not tuple"}}}} + ) # plotly.io.template tests # ------------------------ diff --git a/packages/python/plotly/plotly/tests/test_core/test_offline/test_offline.py b/packages/python/plotly/plotly/tests/test_core/test_offline/test_offline.py index b922d4f5ec..315a81b941 100644 --- a/packages/python/plotly/plotly/tests/test_core/test_offline/test_offline.py +++ b/packages/python/plotly/plotly/tests/test_core/test_offline/test_offline.py @@ -6,8 +6,8 @@ import os from unittest import TestCase +import pytest -from nose.plugins.attrib import attr import json as _json import plotly @@ -314,7 +314,7 @@ def get_html(): self.assertIn('"bogus": 42', html) - @attr("nodev") + @pytest.mark.nodev def test_plotlyjs_version(self): path = os.path.join(packages_root, "javascript", "plotlywidget", "package.json") with open(path, "rt") as f: diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_annotations.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_annotations.py index 6d0b337cd7..18d8fb7c4b 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_annotations.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_annotations.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports @@ -14,7 +14,7 @@ from plotly.tests.test_optional.test_matplotlylib.data.annotations import * -@attr("matplotlib") +@pytest.mark.matplotlib def test_annotations(): fig, ax = plt.subplots() ax.plot([1, 2, 3], "b-") diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_axis_scales.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_axis_scales.py index 9063ce7319..e7f0753da3 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_axis_scales.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_axis_scales.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports from plotly.tests.utils import compare_dict, strip_dict_params @@ -13,7 +13,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib def test_even_linear_scale(): fig, ax = plt.subplots() x = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10] diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_bars.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_bars.py index 6a6df89615..40d891b941 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_bars.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_bars.py @@ -1,6 +1,5 @@ from __future__ import absolute_import - -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports from plotly.tests.utils import compare_dict, strip_dict_params @@ -13,7 +12,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib def test_vertical_bar(): fig, ax = plt.subplots() ax.bar(left=D["left"], height=D["height"]) @@ -33,7 +32,7 @@ def test_vertical_bar(): assert equivalent, msg -@attr("matplotlib") +@pytest.mark.matplotlib def test_horizontal_bar(): fig, ax = plt.subplots() ax.barh(bottom=D["bottom"], width=D["width"]) @@ -53,7 +52,7 @@ def test_horizontal_bar(): assert equivalent, msg -@attr("matplotlib") +@pytest.mark.matplotlib def test_h_and_v_bars(): fig, ax = plt.subplots() ax.bar( diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_data.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_data.py index 050432c898..fc208573b5 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_data.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_data.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports from plotly.tests.test_optional.optional_utils import run_fig @@ -12,7 +12,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib def test_line_data(): fig, ax = plt.subplots() ax.plot(D["x1"], D["y1"]) @@ -31,7 +31,7 @@ def test_line_data(): ) -@attr("matplotlib") +@pytest.mark.matplotlib def test_lines_data(): fig, ax = plt.subplots() ax.plot(D["x1"], D["y1"]) @@ -63,7 +63,7 @@ def test_lines_data(): ) -@attr("matplotlib") +@pytest.mark.matplotlib def test_bar_data(): fig, ax = plt.subplots() ax.bar(D["x1"], D["y1"]) @@ -74,7 +74,7 @@ def test_bar_data(): ) -@attr("matplotlib") +@pytest.mark.matplotlib def test_bars_data(): fig, ax = plt.subplots() ax.bar(D["x1"], D["y1"], color="r") diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_date_times.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_date_times.py index ac4ee079e3..68546749eb 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_date_times.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_date_times.py @@ -3,9 +3,9 @@ import datetime import random from unittest import TestCase +import pytest import pandas as pd -from nose.plugins.attrib import attr import plotly.tools as tls from plotly import optional_imports @@ -17,7 +17,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib class TestDateTimes(TestCase): def test_normal_mpl_dates(self): datetime_format = "%Y-%m-%d %H:%M:%S" diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_lines.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_lines.py index 642936aed1..bb69c18ecc 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_lines.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_lines.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports from plotly.tests.utils import compare_dict, strip_dict_params @@ -13,7 +13,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib def test_simple_line(): fig, ax = plt.subplots() ax.plot(D["x1"], D["y1"], label="simple") @@ -29,7 +29,7 @@ def test_simple_line(): assert equivalent, msg -@attr("matplotlib") +@pytest.mark.matplotlib def test_complicated_line(): fig, ax = plt.subplots() ax.plot(D["x1"], D["y1"], "ro", markersize=10, alpha=0.5, label="one") diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_scatter.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_scatter.py index 839880dc59..96984130d8 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_scatter.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_scatter.py @@ -1,6 +1,5 @@ from __future__ import absolute_import - -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports from plotly.tests.utils import compare_dict, strip_dict_params @@ -13,7 +12,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib def test_simple_scatter(): fig, ax = plt.subplots() ax.scatter(D["x1"], D["y1"]) @@ -33,7 +32,7 @@ def test_simple_scatter(): assert equivalent, msg -@attr("matplotlib") +@pytest.mark.matplotlib def test_double_scatter(): fig, ax = plt.subplots() ax.scatter(D["x1"], D["y1"], color="red", s=121, marker="^", alpha=0.5) diff --git a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_subplots.py b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_subplots.py index 4553eadeb4..6d4e0959dd 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_subplots.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_matplotlylib/test_subplots.py @@ -1,6 +1,6 @@ from __future__ import absolute_import -from nose.plugins.attrib import attr +import pytest from plotly import optional_imports from plotly.tests.utils import compare_dict, strip_dict_params @@ -14,7 +14,7 @@ import matplotlib.pyplot as plt -@attr("matplotlib") +@pytest.mark.matplotlib def test_blank_subplots(): fig = plt.figure() gs = GridSpec(4, 6) diff --git a/packages/python/plotly/plotly/tests/test_optional/test_offline/test_offline.py b/packages/python/plotly/plotly/tests/test_optional/test_offline/test_offline.py index f16575d7c2..d36934d1ea 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_offline/test_offline.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_offline/test_offline.py @@ -4,11 +4,10 @@ """ from __future__ import absolute_import import re -from nose.tools import raises -from nose.plugins.attrib import attr import json as _json from unittest import TestCase +import pytest import plotly from plotly import optional_imports @@ -39,7 +38,7 @@ def test_iplot_works_after_you_call_init_notebook_mode(self): if matplotlylib: - @attr("matplotlib") + @pytest.mark.matplotlib def test_iplot_mpl_works(self): # Generate matplotlib plot for tests fig = plt.figure() @@ -64,7 +63,7 @@ def _read_html(self, file_url): if matplotlylib: - @attr("matplotlib") + @pytest.mark.matplotlib def test_default_mpl_plot_generates_expected_html(self): # Generate matplotlib plot for tests fig = plt.figure() diff --git a/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py b/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py index d26e7ac6ce..24d3702491 100644 --- a/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py +++ b/packages/python/plotly/plotly/tests/test_optional/test_utils/test_utils.py @@ -9,11 +9,11 @@ import decimal from datetime import datetime as dt from unittest import TestCase +import pytest import numpy as np import pandas as pd import pytz -from nose.plugins.attrib import attr from pandas.util.testing import assert_series_equal import json as _json import os @@ -295,7 +295,7 @@ def test_pil_image_encoding(self): if matplotlylib: - @attr("matplotlib") + @pytest.mark.matplotlib def test_masked_constants_example(): # example from: https://gist.github.com/tschaume/d123d56bf586276adb98 data = { diff --git a/packages/python/plotly/plotlywidget/static/index.js b/packages/python/plotly/plotlywidget/static/index.js index bf3598331e..edab9e72d2 100644 --- a/packages/python/plotly/plotlywidget/static/index.js +++ b/packages/python/plotly/plotlywidget/static/index.js @@ -94,7 +94,7 @@ module.exports = g; /* 1 */ /***/ (function(module, exports) { -module.exports = {"name":"plotlywidget","version":"1.5.2","description":"The plotly JupyterLab extension","author":"The plotly.py team","license":"MIT","main":"src/index.js","repository":{"type":"git","url":"https://github.com/plotly/plotly.py"},"keywords":["jupyter","widgets","ipython","ipywidgets","plotly"],"files":["src/**/*.js","dist/*.js","style/*.*"],"scripts":{"build":"webpack","clean":"rimraf dist/ && rimraf ../../python/plotly/plotlywidget/static'","test":"echo \"Error: no test specified\" && exit 1"},"devDependencies":{"webpack":"^3.10.0","rimraf":"^2.6.1","ify-loader":"^1.1.0","typescript":"~3.1.1"},"dependencies":{"plotly.js":"^1.52.2","@jupyter-widgets/base":"^2.0.0","lodash":"^4.17.4"},"jupyterlab":{"extension":"src/jupyterlab-plugin.js"}} +module.exports = {"name":"plotlywidget","version":"1.5.3","description":"The plotly JupyterLab extension","author":"The plotly.py team","license":"MIT","main":"src/index.js","repository":{"type":"git","url":"https://github.com/plotly/plotly.py"},"keywords":["jupyter","widgets","ipython","ipywidgets","plotly"],"files":["src/**/*.js","dist/*.js","style/*.*"],"scripts":{"build":"webpack","clean":"rimraf dist/ && rimraf ../../python/plotly/plotlywidget/static'","test":"echo \"Error: no test specified\" && exit 1"},"devDependencies":{"webpack":"^3.10.0","rimraf":"^2.6.1","ify-loader":"^1.1.0","typescript":"~3.1.1"},"dependencies":{"plotly.js":"^1.52.2","@jupyter-widgets/base":"^2.0.0","lodash":"^4.17.4"},"jupyterlab":{"extension":"src/jupyterlab-plugin.js"}} /***/ }), /* 2 */ diff --git a/packages/python/plotly/pytest.ini b/packages/python/plotly/pytest.ini new file mode 100644 index 0000000000..3d05496c99 --- /dev/null +++ b/packages/python/plotly/pytest.ini @@ -0,0 +1,5 @@ +# content of pytest.ini +[pytest] +markers = + nodev: mark a test as nodev + matplotlib: mark a test as matplotlib diff --git a/packages/python/plotly/tox.ini b/packages/python/plotly/tox.ini index df41b7e1df..b1f1cca2f7 100644 --- a/packages/python/plotly/tox.ini +++ b/packages/python/plotly/tox.ini @@ -24,15 +24,14 @@ ; PASSING ADDITONAL ARGUMENTS TO TEST COMMANDS ; The {posargs} is tox-specific and passes in any command line args after `--`. ; For example, given the testing command in *this* file: -; nosetests {posargs} -x plotly/tests/test_core +; pytest {posargs} -x plotly/tests/test_core ; ; The following command: -; tox -- -a '!slow' +; tox -- -k 'not nodev' ; ; Tells tox to call: -; nosetests -a '!slow' -x plotly/tests/test_core +; pytest -k 'not nodev' -x plotly/tests/test_core ; -; Which is a nice way to skip slow tests for faster testing cycles. [tox] ; The py{A,B,C}-{X,Y} generates a matrix of envs: @@ -53,7 +52,6 @@ deps= coverage==4.3.1 decorator==4.0.9 mock==2.0.0 - nose==1.3.7 requests==2.12.4 six==1.10.0 pytz==2016.10 @@ -81,25 +79,25 @@ deps= basepython={env:PLOTLY_TOX_PYTHON_27:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_core [testenv:py35-core] basepython={env:PLOTLY_TOX_PYTHON_35:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_core [testenv:py36-core] basepython={env:PLOTLY_TOX_PYTHON_36:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_core [testenv:py37-core] basepython={env:PLOTLY_TOX_PYTHON_37:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_core ; OPTIONAL ENVIRONMENTS ;[testenv:py27-optional] @@ -116,8 +114,8 @@ commands= basepython={env:PLOTLY_TOX_PYTHON_27:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core - nosetests {posargs} -x plotly/tests/test_optional + pytest {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_optional pytest _plotly_utils/tests/ pytest plotly/tests/test_io @@ -125,8 +123,8 @@ commands= basepython={env:PLOTLY_TOX_PYTHON_35:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core - nosetests {posargs} -x plotly/tests/test_optional + pytest {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_optional pytest _plotly_utils/tests/ pytest plotly/tests/test_io @@ -134,8 +132,8 @@ commands= basepython={env:PLOTLY_TOX_PYTHON_36:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core - nosetests {posargs} -x plotly/tests/test_optional + pytest {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_optional pytest _plotly_utils/tests/ pytest plotly/tests/test_io @@ -143,7 +141,7 @@ commands= basepython={env:PLOTLY_TOX_PYTHON_37:} commands= python --version - nosetests {posargs} -x plotly/tests/test_core - nosetests {posargs} -x plotly/tests/test_optional + pytest {posargs} -x plotly/tests/test_core + pytest {posargs} -x plotly/tests/test_optional pytest _plotly_utils/tests/ pytest plotly/tests/test_io