Title: plot_directive is confused by include directives, part 2 (context option) · Issue #20523 · matplotlib/matplotlib · GitHub
Open Graph Title: plot_directive is confused by include directives, part 2 (context option) · Issue #20523 · matplotlib/matplotlib
X Title: plot_directive is confused by include directives, part 2 (context option) · Issue #20523 · matplotlib/matplotlib
Description: Bug summary Whenever a file b.rst is included in a.rst via the RST include directive, Sphinx rebuilds the a.html page; but in plot_directive, a.rst is not considered 'out of date' (as judged by the out_of_date() function), because the mo...
Open Graph Description: Bug summary Whenever a file b.rst is included in a.rst via the RST include directive, Sphinx rebuilds the a.html page; but in plot_directive, a.rst is not considered 'out of date' (as judged by the...
X Description: Bug summary Whenever a file b.rst is included in a.rst via the RST include directive, Sphinx rebuilds the a.html page; but in plot_directive, a.rst is not considered 'out of date' (as judge...
Opengraph URL: https://github.com/matplotlib/matplotlib/issues/20523
X: @github
Domain: github.com
{"@context":"https://schema.org","@type":"DiscussionForumPosting","headline":"plot_directive is confused by include directives, part 2 (context option)","articleBody":"### Bug summary\r\n\r\nWhenever a file `b.rst` is included in `a.rst` via the RST `include` directive, Sphinx rebuilds the `a.html` page; but in plot_directive, `a.rst` is not considered 'out of date' (as judged by the `out_of_date()` function), because the modification time of `a.rst` was not changed.\r\n\r\nThis discrepancy is part of the reason why #17860 exists; and while working on it (at PR #20374) I discovered also that figures with the `:context:` option set will get confused. A specific example is shown below. It's quite hard to encounter in real life but it is directly relevant to matplotlib's tests as there is a very similar construct in plots 6-9 of matplotlib's `test_sphinxext.py`.\r\n\r\n### Code for reproduction\r\n\r\n**conf.py**\r\n```python\r\nextensions = ['matplotlib.sphinxext.plot_directive']\r\nexclude_patterns = ['_build']\r\n```\r\n\r\n**index.rst**\r\n```rst\r\nIndex\r\n=====\r\n\r\n.. toctree::\r\n \r\n a\r\n b\r\n```\r\n\r\n**a.rst**\r\n```rst\r\nFile A\r\n======\r\n\r\nIt's important that the first plot produces an image, and also sets a variable\r\nvia ``:context:``.\r\n\r\n\r\n.. plot::\r\n :context:\r\n\r\n plt.plot(range(2))\r\n a = 1 \r\n\r\nThe second plot must not use ``:context:``. It doesn't necessarily have to\r\nproduce an image. The important thing is that it must close the figure from the\r\nprevious plot, so that the third plot doesn't actually produce an image (if\r\nfigures aren't closed, then the third plot will reuse the same image from the\r\nfirst plot).\r\n\r\n.. plot::\r\n\r\n plt.plot(range(3))\r\n\r\nThe third plot must try to use a variable previously saved in `:context:`` and\r\nmust not produce an image.\r\n\r\n\r\n.. plot::\r\n :context:\r\n\r\n assert a == 1\r\n\r\nLastly we include another file.\r\n\r\n.. include:: b.rst\r\n```\r\n\r\n**b.rst**\r\n```rst\r\nFile B\r\n======\r\n\r\nThis can be anything.\r\n```\r\n\r\n\r\n### Steps to reproduce\r\n\r\n1. Put the four files above in a directory and `cd` into it.\r\n2. Build the docs the first time using `sphinx-build -b html . ./_build/html`.\r\n3. Modify `b.rst` in any way.\r\n4. Build the docs again.\r\n\r\n### Actual outcome\r\n\r\nThe third plot in `a.rst` throws an error.\r\n\r\n```\r\n/Users/yongrenjie/test/rst/a.rst:21: WARNING: Exception occurred in plotting a-3\r\n from /Users/yongrenjie/test/rst/a.rst:\r\nTraceback (most recent call last):\r\n File \"/Users/yongrenjie/progs/matplotlib/lib/matplotlib/sphinxext/plot_directive.py\", line 497, in _run_code\r\n exec(code, ns)\r\n File \"\u003cstring\u003e\", line 1, in \u003cmodule\u003e\r\nNameError: name 'a' is not defined\r\n```\r\n\r\nThe reason for this, as suggested above, is because of the `out_of_date()` function. When `sphinx-build` is invoked again, Sphinx decides that both `a.rst` and `b.rst` must be recompiled. Now:\r\n\r\n - Plot 1 is not considered out of date, because the image file already exists and `a.rst` was not modified. So the code is never run and `a` is never saved to the context.\r\n - Plot 2 is there to ensure that figures are closed prior to Plot 3, so that Plot 3 never generates an image file.\r\n - Plot 3 is considered out of date, because there is no image file that corresponds to it. Thus it is run again, and doesn't see `a` in the context, hence the warning.\r\n\r\n### Expected outcome\r\n\r\nThere shouldn't be any errors.\r\n\r\nOne easy way to accomplish this is to make sure that Sphinx re-runs all code snippets which are context-dependent, whenever a file is recompiled. That is, if a plot directive has :context: on, then the code should always be considered out of date regardless of the file modification times.\r\n\r\nThis will lead to some excessive regeneration of plots whenever included files are modified. For example, in the above code, whenever `b.rst` is modified, Plots 1 and 3 will always be re-created, even if `a.rst` is untouched. But IMO this is more sensible behaviour than the current bug. It would also be in line with what happens if *any* part of `a.rst` is modified, including the text outside the plot directives: all the plots in `a.rst` would be re-created.\r\n\r\nThis doesn't change the case where neither `a.rst` nor `b.rst` are modified, because in that case Sphinx will never attempt to recompile either file and plot_directive will never be called.","author":{"url":"https://github.com/yongrenjie","@type":"Person","name":"yongrenjie"},"datePublished":"2021-06-26T19:48:28.000Z","interactionStatistic":{"@type":"InteractionCounter","interactionType":"https://schema.org/CommentAction","userInteractionCount":1},"url":"https://github.com/20523/matplotlib/issues/20523"}
| route-pattern | /_view_fragments/issues/show/:user_id/:repository/:id/issue_layout(.:format) |
| route-controller | voltron_issues_fragments |
| route-action | issue_layout |
| fetch-nonce | v2:640156dd-be73-cd4e-14c4-e3f28a7c0542 |
| current-catalog-service-hash | 81bb79d38c15960b92d99bca9288a9108c7a47b18f2423d0f6438c5b7bcd2114 |
| request-id | ED62:24214A:1C3B446:26763D5:6A5400AB |
| html-safe-nonce | e2f9334e20f02d952fb537e07f28b39965197c28761c32d0af3e53c61a232f26 |
| visitor-payload | eyJyZWZlcnJlciI6IiIsInJlcXVlc3RfaWQiOiJFRDYyOjI0MjE0QToxQzNCNDQ2OjI2NzYzRDU6NkE1NDAwQUIiLCJ2aXNpdG9yX2lkIjoiNDE1MjY0NDIxOTE3MjAyODU4NyIsInJlZ2lvbl9lZGdlIjoiaWFkIiwicmVnaW9uX3JlbmRlciI6ImlhZCJ9 |
| visitor-hmac | 5e8abae87e04b75b9119e1c7f6c04f2c880e11bf471584f2f204dff45c929fc2 |
| hovercard-subject-tag | issue:930782905 |
| github-keyboard-shortcuts | repository,issues,copilot |
| google-site-verification | Apib7-x98H0j5cPqHWwSMm6dNU4GmODRoqxLiDzdx9I |
| octolytics-url | https://collector.github.com/github/collect |
| analytics-location | / |
| fb:app_id | 1401488693436528 |
| apple-itunes-app | app-id=1477376905, app-argument=https://github.com/_view_fragments/issues/show/matplotlib/matplotlib/20523/issue_layout |
| twitter:image | https://opengraph.githubassets.com/7a30448fbb85522fa3d2a6b20995455edb500ea165fc28d09848f948bec543e4/matplotlib/matplotlib/issues/20523 |
| twitter:card | summary_large_image |
| og:image | https://opengraph.githubassets.com/7a30448fbb85522fa3d2a6b20995455edb500ea165fc28d09848f948bec543e4/matplotlib/matplotlib/issues/20523 |
| og:image:alt | Bug summary Whenever a file b.rst is included in a.rst via the RST include directive, Sphinx rebuilds the a.html page; but in plot_directive, a.rst is not considered 'out of date' (as judged by the... |
| og:image:width | 1200 |
| og:image:height | 600 |
| og:site_name | GitHub |
| og:type | object |
| og:author:username | yongrenjie |
| hostname | github.com |
| expected-hostname | github.com |
| None | b9a586c06a05a7a86fc7e3f4dbd03e42f6869085879aa184aa6369456dbd50fb |
| turbo-cache-control | no-preview |
| go-import | github.com/matplotlib/matplotlib git https://github.com/matplotlib/matplotlib.git |
| octolytics-dimension-user_id | 215947 |
| octolytics-dimension-user_login | matplotlib |
| octolytics-dimension-repository_id | 1385122 |
| octolytics-dimension-repository_nwo | matplotlib/matplotlib |
| octolytics-dimension-repository_public | true |
| octolytics-dimension-repository_is_fork | false |
| octolytics-dimension-repository_network_root_id | 1385122 |
| octolytics-dimension-repository_network_root_nwo | matplotlib/matplotlib |
| turbo-body-classes | logged-out env-production page-responsive |
| disable-turbo | false |
| browser-stats-url | https://api.github.com/_private/browser/stats |
| browser-errors-url | https://api.github.com/_private/browser/errors |
| release | 07a982c1d40157c619b364352b704c3ce66bb332 |
| ui-target | full |
| theme-color | #1e2327 |
| color-scheme | light dark |
Links:
Viewport: width=device-width