-
-
Notifications
You must be signed in to change notification settings - Fork 2.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add static configuration (Sphinx.toml
)
#9040
Comments
Just wanted to chime in here and say this would be a great addition. I think it would improve the onboarding experience, and allow simple configurations to be machine-parsable. The dynamic nature of the Python configs definitely leads to a lot of customizations that are harder to support in varied development environments, which is a very common mistake for first-time Read the Docs users. I'm in favor on adding it, and I also wanted to note that between the Executable Books & RTD teams, we'd probably be willing to implement and document this work, so we're mostly looking for a 👍 or 👎 from the team before starting a PR. |
A couple of thoughts from me:
More unsolicited thoughtsIMO the choice for the file format comes down to “how much do you like nesting”. If you wanna have JSON-like arbitrary nesting, then YAML is likely a better fit. I’m likely biased, but I do think conf.py’s generally flat structure translates very nicely toward TOML’s design. Most existing conf.py files are probably also almost-valid TOML files already! Neither choice is wrong, both have gotchas, and I’d like it if we went with TOML here (it also helps the case for if/when I push to get a parser for that into the standard library). |
Indeed the main thing is to get a 👍 from the sphinx team, and I am definitely +1 😄 In terms of YAML vs TOML; I would note that both jupyter-book (_config.yml and _toc.yml) and RTD (.readthedocs.yml) currently use YAML for their configuration files, and so at least for those use case, I feel TOML would be an additional overhead in understanding for the user |
I don't have a fully formed opinion yet, but some thoughts:
|
Maybe a terrible idea, but what if Maybe the null case could even be the default, given that the |
I guess the classic example of a co-existance of such files is the setuptools |
What setuptools does is basically pretend there's a minimal setup.py file, if it doesn't exist. Notably, it's possible for tooling to detect whether setup.py exists and if it doesn't, it means that everything is declared statically. For Sphinx, the minimal conf.py file would be empty, I guess? |
TOML allows top level keys though with no section defined. The following is valid toml: project = "sphinx"
version = "0.0.1" Sections are only required if there's dictionaries in Why I'm not a huge YAML fan is that YAML types are difficult to parse for humans and machines alike. Consider something like - yes # bool
- "no" # string
- false # bool
- .6432 # float
- "0.1" # string
- null # null
- none # string
- ~ # null
- 0xabba # int |
Well, TOML is literally designed to be a configuration file format. https://toml.io uses the tag line: "A config file format for humans". Think of it as unambiguous INI files. The clarity and unambitious nature of the format is why pyproject.toml is TOML based, same for Cargo.toml and more. :) To address the specific question raised: All key-value pairs in a table Anyway, the reason I kept my thoughts on file format choices in hidden-unless-you're-curious is because I didn't want push this issue toward that way. I should've just omitted that whole thing. Let's first wait for opinions on the general idea of static metadata in Sphinx, before discussing the exact file format further. :) |
Yeh, at the end of the day, JSON/YAML/TOML all basically map to each other 1-to-1, so it won't really affect the underlying code/logic to be written |
+0 for supporting static config file. I don't think python script is not good for the config file. But it's reasonable to support a commonly used file format for sphinx. And I don't have opinion for YAML vs TOML. Because I've never written a .toml file. |
@tk0miya thanks for your thoughts! Could you clarify why you don't want a combination of YAML and Python? I think the combination of I think we should just scope this conversation to YAML since it is super common for config, and readthedocs uses it, and leave TOML to a later conversation |
It also feels like it would be very difficult to migrate everyone from py to yaml? |
What would be the benefit of doing that anyway? I can to some degree see the point that each author may want to shift as much as possible to something more easily parsable, but maybe I don't fully get the problem with the current setup:
Can you elaborate on the reasoning behind this? |
Here's a few thoughts: benefits of YAML
downsides of YAML
benefits of Python
downsides of Python
So to me this sounds like a reasonable base for : Support YAML for simple configuration use-cases, which are probably most use-cases. For anything advanced, let people provide a As an aside, one of the most common things people like about Jupyter Book (which is built on Sphinx), is that it supports YAML configuration. One reason I opened this issue is because so many people have told me they prefer YAML, that I think it is worth considering for core Sphinx, as I think it would be a benefit to many. |
@choldgraf, right, basically I agree with all those points. Where the disagreement/confusion comes from is how this will work, and the comment from @chrisjsewell:
Maybe I misunderstand, but that seems to imply that only one of |
Oh no, I'm arguing for exactly the opposite lol |
@jakobandersen ah in that case I totally agree with you, I think @chrisjsewell was suggesting they need to co-exist as well. I'll try to clarify this in the title + top-comment as well |
Ah, all good then :-) |
|
Hmm... I would've imagined setting a value in conf.yml and conf.py would result in an error OR cause the Python value to be used. |
Awesome! So, everyone is on board for (or ambivalent to) allowing static metadata! 🎉 I think there's a few things to decide on AFAICT:
Remembering the law of triviality, I'm gonna focus on semantics first. :) Semantics At least 2 folks have stated a -1 for allowing both the static metadata file, and Python file to exist at the same time, because it would get confusing when folks define keys in both. I agree! Specifying values in both is weird and confusing. I disagree that we shouldn't allow the files to complement each other when they both exist, without overlaps though. Allowing both to co-exist, and erroring out if the same value is defined in both (which isn't that much code complexity), allows for a significantly better experience with the static metadata: I write a nice Sphinx site, with only static metadata. After some time, I realize I do need some amount of dynamic behaviour (idk, need to add to sys.path for autodoc to work). If we don't allow both files to co-exist, this means that now I'll have to translate the YAML configuration into Python values, and start all over again. Compare that to just being able to add that File name
Let's use That way, it's much clearer what tool is being used. Searching for the filename on search engines will actually yield useful results; which likely won't happen for File format Full disclosure: I am the primary maintainer of TOML now. And, unsurpisingly, I'd like to advocate for adopting TOML over YAML here. Excuse me for being lazy, and quoting some pieces of writing: In the toml-lang/toml README -- this is the only quote where I've contributed wording.
Comparison of configuration file languages, done during the PEP 518 discussion
PEP 518's discussion of "why not YAML"
Example demonstrating how YAML can be ambigous in weird ways, from earlier in this thread
One fun example of this is the Norway-YAML law. Finally, thanks to pyproject.toml, a lot of Python tooling is going to be configured through TOML going forward. It'd be nice for Sphinx to hop on board as well! :) |
Maybe I misunderstood, but I got the impression that @tk0miya wanted to completely remove the python file, rather than just restrict its use? |
One dynamic thing I actually do a lot in projects is add a builder-inited event, to run sphinx-apidoc and automate the build of the api documentation pages (which I gitignore from the repo). But maybe I am missing a better way to do this? |
Well, if you're missing something, then it's you and I both. :) One of the nice things about conf.py is that it also basically serves as an extension, once you add the setup function. |
If Sphinx does allow for configuration from static metadata, I would suggest using Python literals as the file format; see an example (sphinx_static_config.zip) of import ast
def setup(app):
with open("sphinx-conf.pylit", encoding="utf-8") as f:
cfg = ast.literal_eval("{\n" + f.read() + "\n}")
for key, value in cfg.items():
app.config[key] = value |
So what's the status on this? What's blocking it? |
What's blocking it is reaching consensus about a way forward. To repeat what was summarized in the last comment a few pixels above, some Sphinx maintainers think having 2 methods is a bad idea and adds complexity, so there should be a hard transition. Some others think having 2 methods could pave a way to a smoother transition. These two visions cannot coexist, and until consensus is reached, the status quo will be maintained. |
I mean it's been 2 years and a few major releases in between. There is a simple solution to proritize the yaml and if a Much of the functionalities that needed to be dynamic seem to be handled by the plugins side. Otherwise, that can be handled by jinja templating it (maybe with values from pyproject.toml or importlib.metadata) or adding a few extra plugings, e.g. for the dynamic version. |
Well that and yaml vs toml. Probably at this point, with toml in core python, it might make more sense |
I mean, I don't think there's a "simple" solution (otherwise we probably wouldn't be having this conversation). If you ask me, I do agree with @tk0miya and others that we should obliterate dynamic config completely, make it static (in whatever format we decide, please don't bring YAML vs TOML debates again), and any dynamic config should be handled by plugins/extensions/hooks/entry_points/whatever. The whole Python ecosystem is solidly moving in that direction. |
"Simple" I mean it is straightforward to implement on top of #9170. I don't think either camp would be objecting to this, and it is just 5-ish extra lines of code. But also the ecosystem and people's experience change, so it is worth testing the waters again every now-and-then. About the yaml-toml. Most tools use a |
FYI, for anyone who's looking to at least have DRY for sphinx as a temporary solution, take a look at sphinx-toolbox/sphinx-pyproject by @domdfcoding so you can just make the |
Sphinx.toml
)
Static configuration is a good idea. I think we can move incrementally, a first version to be committed would be if A |
I was pretty enthusiastic for TOML, especially for pyproject.toml integration (e.g., the version could by default be read from the standard packaging metadata) and started writing a patch... but I hit a snag: TOML doesn't support an equivalent of None. There are some configuration variables that use None in their format. If Sphinx had started with TOML config from day 1, all existing confvars would be designed with this in mind (e.g., not So, with disappointment, I have to say that this pretty much kills TOML in favor of YAML. |
I don't think this is a priority, a lot of users are going to want I think it'd be better for contributors to be focused on existing bugs that likely affect the majority of current Sphinx users than wasting energy on new features like |
Considering the drawbacks of using static configuration and the lack of null values in TOML, would you consider an option to define a helper for static typing? Something like:
from sphinx.somewhere import SphinxConf
conf = SphinxConf(
project=...,
...
) As an optional alternative of course. |
Background
One of the challenges in getting started with Sphinx is the
conf.py
file, for a few reasons:Over the years, many other configuration formats have arisen, probably the two most well-known are YAML and TOML. For example. Jupyter Book provides a layer of YAML configuration on top of Sphinx. Users have responded that this is a really friendly pattern for beginners and experts alike. I wonder if Sphinx would be interested in allowing for YAML or TOML configuration as well.
Describe the solution you'd like
In addition to the current config option of
conf.py
, add another option:Allow config with YAML. I think it would be useful if Sphinx allowed for:
conf.yml
. This would be read-in with PyYAML.This file would be read in and converted to Python variables directly, as if it was written in Python (
conf.py
). So for example:would map onto
Allow
conf.py
to be provided simultaneously. Some Sphinx builds will still need to run custom Python code (e.g., to set up some extensions etc). In this case, authors may wish to keep their "simple config" in the YAML file, and the complex config in pure Python.If
conf.py
is supplied as well asconf.yml
, then the environment defined inconf.py
will over-rule anything inconf.yml
.So the order of operations would be:
conf.yaml
conf.py
if it exists, overwriting variables created in 1Describe alternatives you've considered
I've tried creating a lightweight extension that allows this but didn't have success because of the way that extensions are activated.
I have also considered other documentation engines like
mkdocs
, which use YAML, but I'd for this to be in the Sphinx ecosystem!cc some others who have discussed this in the
executablebooks/
repo: @pradyunsg @ericholscher @chrisjsewellEDIT: I've updated the above description to remove mention of TOML, as I don't want that to derail conversation here!
The text was updated successfully, but these errors were encountered: