I'm working on a documentation of an Python wrapper around a PyObjC application with Sphinx.
Sphinx adds a confusing and unwanted library description of the library code to this class's property description that happens to be code (please see screenshot, second last line).
How to get rid of it? I looked into conf.py, but couldn't find anything.
Also, I learned, autodoc adds more docstring stuff, but I never asked for it and and can't find whether this is what's even happening and how to turn it off.
The corresponding sphinx code is simply this:
Properties
.. autosummary::
name
code
automatic
Related
I'm using Sphinx to document a python project, and I'm trying to create a reusable tip to be used in several locations.
Typically, I'll use the following syntax in a python file:
"""
.. tip::
I want this tip to be used in several locations. Why?
- Save time
- Work less
"""
Now this works whether I put it at the beginning of the file, right under class definition or right under function definition.
I found Sphinx's manual for :ref:, which suggests to use a label:
.. _my_reusable_tip:
.. tip::
...
And then call this tip with :ref:`my_reusable_tip` anywhere I want.
The manual states that 'it works across files, when section headings are changed, and for all builders that support cross-references'
The thing is, it doesn't matter in which .py file in the project I write the label and tip definition, the :ref:`my_reusable_tip` just displays 'my_reusable_tip', and not the tip itself.
What I'm using to build the documentation is
sphinx-apidoc -f -F -o
make html
I'm pretty sure my logic is flawed in some way, but I can't figure out why.
I know that Sphinx searches the project for reStructuredText and renders it if it can, but I think I'm missing something here.
I tried to add this label in a seperate .py file enclosed in """, and in a separate .txt file without enclosed """.
I tried creating an .rst file with the label definition and rebuild the html documentation.
What am I missing here?
Python 3.4.3 BTW.
In sphinx, a :ref: is simply a more robust way of linking (or referencing) another part of the document. Thus, your use of :ref: will simply provide a hyperlink to the label.
It is not a way of substituting or expanding a block.
Inline substitutions are available using using |...|, however an inline substitution cannot be used to substitute a block as you seem to require.
RestructuredText is not a template language, and thus doesn't provide macro like facilities. In the event you need it, an alternative solution is to use a template library such as mako or jinja to deal with this kind of issue.
Just using reStructuredText directive
.. include:: ./my_reusable_tip.txt
in your rst files?
I'm documenting my Python classes using Sphinx, and sometimes I want to give my parameters quite long descriptions to explain something in details. Unfortunately, Sphinx generates ugly output for me which wastes a lot of space and breaks the whole page appearance:
It can be seen that Sphinx creates a table, then puts "Parameters" header to the left cell, and the actual list of parameters to the right cell. But there should be way to avoid creating this table completely. After playing with the page DOM tree I finally can show that I want to achieve:
Is there a built-in way to do this or I'd have to create a PR to Sphinx theme or Sphinx itself?
After posting an issue to Sphinx bug-tracker and having no response, I've decided to roll-out my own solution (better say, hack). To achieve the look I want, I have written a simple Sphinx extension which post-processes generated HTML code. It can be found on PyPI:
https://pypi.python.org/pypi/sphinxcontrib.divparams
https://pythonhosted.org/sphinxcontrib.divparams/
This doesn't seem to be the best way to solve the issue, but the behaviour I wanted to change is deeply hard-coded in docutils, not Sphinx.
I am trying to make a cookbook out of some Python snippets using Sphinx. Each snippet is a self-contained Python script and has a tutorial-type doctsring.
I want to have a source link in the generated documentation to display the script contents. But viewcode does not seem to create this link for the module, but only for a function or a class with a docstring. Is there a way to coax sphinx.ext.viewcode to display the script code without having any class/function in it?
I hope you haven't sat for two years waiting for an answer, but try using the literal include tag. You can play around with what gets displayed.
See the sphinx docs for more details.
As an exercise for learning, I am trying to write a plugin for MusicBrainz that matches the albumartistsort to albumartist and artistsort to artist, as opposed to the (apparently) default of Last Name, First Name format it is currently using.
I am just learning about Python and therefore I am trying to use another plugin as a guide, but some important changes need to be done and that's where I probably screwed up.
When I try installing the plug in, it doesn't appear in the plugin list although it is copied to the plugin folder; and the .pyo file is not generated. I am guessing this is due to a compilation error, but I haven't been able to include whatever I need so I can use the picard module (don't know where to find it nor import it) so I can test in my python interpreter.
This is the code I have:
PLUGIN_NAME = "Sort Artist and Album Artist"
PLUGIN_AUTHOR = "Kevin Hernandez"
PLUGIN_DESCRIPTION = "Sorts artist/album artist by name as in Artist/Album Artist field instead of Last, First"
PLUGIN_VERSION = "0.1"
PLUGIN_API_VERSIONS = ["0.9.0", "0.10", "0.15", "0.16"]
from picard.metadata import register_album_metadata_processor
import re
def copy_albumartist_to_albumartistsort(tagger, metadata, release):
match = re.search($not($eq(metadata["albumartistsort"],metadata["albumartist"])))
if match:
metadata["albumartistsort"] = metadata["albumartist"]
def copy_artist_to_artistsort(tagger, metadata, release):
match = re.search($not($eq(metadata["artistsort"],metadata["artist"])))
if match:
metadata["artistsort"] = metadata["artist"]
register_album_metadata_processor(copy_albumartist_to_albumartistsort)
register_album_metadata_processor(copy_artist_to_artistsort)
and I also tried defining the functions as:
def copy_albumartist_to_albumartistsort(tagger, metadata, release):
metadata["albumartistsort"] = metadata["albumartist"]
def copy_artist_to_artistsort(tagger, metadata, release):
metadata["artistsort"] = metadata["artist"]
I must point out that I don't fully understand when these are called. I believe the plugin documentation here, here and here is not enough to follow the plugins they have there (e.g. the search and match methods they use in different plugins with re are not explained in the documentation links I am referring to.
If there's a more thorough documentation for it, you can pinpoint what I am doing wrong in my code, or know how to include the picard module in an interpreter (where to find it AND how to include it), then your comments are very much appreciated and valid answers to this question.
I think your biggest problem is that you're mixing up the plugin API with the tagger scripting language.
Tagger scripts are written in a simple custom language; plugins are written in Python. You can't mix and match syntax between the two languages. In particular:
match = re.search($not($eq(metadata["albumartistsort"],metadata["albumartist"])))
That $not, $eq, etc. doesn't mean anything in Python. If you want to check whether things are equal, you use the == operator. If you want to use re.search, you use regular expression syntax. And so on.
Also, your code has to be valid Python, with valid indentation. Your code, at least as posted here.
But let's go through your questions one by one:
I am trying to write a plugin for MusicBrainz that matches the albumartistsort to albumartist and artistsort to artist, as opposed to the (apparently) default of Last Name, First Name format it is currently using.
There are very few automatic defaults in MusicBrainz. Each artist has a name and a sort name, in the database, entered by a human user and verified by other users. You can see this from the web interface. For example, go to David Bowie, and in the "Artist Information" panel on the right side, you'll see "Sort name: Bowie, David". If you're not used to using MusicBrainz's web interface, you should explore it before trying to expand Picard.
When I try installing the plug in, it doesn't appear in the plugin list although it is copied to the plugin folder; and the .pyo file is not generated. I am guessing this is due to a compilation error
Yep. If you run Picard from the command-line with the -d flag, it will show you the errors instead of just silently disabling your plugin, so you don't have to guess. This is documented under Troubleshooting. (If you're on a Mac, the path will be something like /Applications/MusicBrainz Picard.app/Contents/MacOS/MusicBrainz Picard; I think the docs don't explain that because it's standard OS X app bundle stuff.)
but I haven't been able to include whatever I need so I can use the picard module (don't know where to find it nor import it) so I can test in my python interpreter.
You really can't test it in your interpreter. Picard bundles its own custom-built Python interpreter, rather than using your system Python. In that custom interpreter, the picard package is on the sys.path, but in your system Python interpreter, it's not. And trying to import that package and use things out of it while not actually running the Picard GUI wouldn't be a good idea anyway.
If you really want to explore what's in the picard package, download the source and run a local build of the code. But you really shouldn't need to do that. You shouldn't need any functions beyond those documented in the API, and if you want to debug things, you want to debug them in the right context, which generally means adding print functions and/or using the logging module in your code.
I must point out that I don't fully understand when these are called.
At some point after each album is downloaded from the MusicBrainz server, all registered album processor functions get called with the album, and all registered track processor function get called with each track on the album.
Notice that an album processor isn't going to be able to change track-level fields like the track artist sort; you will need a track processor for that.
e.g. the search and match methods they use in different plugins with re are not explained in the documentation links I am referring to.
That's because they're part of the Python standard library, which is documented as part of the standard Python docs—in this case, see re.
You're expected to know the basics of Python before being able to write a Picard plugin.
Meanwhile, I'm not sure what you were trying to write here, but it looks like a really convoluted attempt to say "if these two fields aren't equal, make them equal". Which does the same thing as "unconditionally make them equal". So, why even bother with the regexp and the if condition?
So, your functions could be simplified to:
def copy_albumartist_to_albumartistsort(tagger, metadata, release):
metadata["albumartistsort"] = metadata["albumartist"]
def copy_artist_to_artistsort(tagger, metadata, release, track):
metadata["artistsort"] = metadata["artist"]
register_album_metadata_processor(copy_albumartist_to_albumartistsort)
register_track_metadata_processor(copy_artist_to_artistsort)
However, you really don't need a plugin here at all. You should be able to write this whole thing as a trivial tagger script:
$set(artistsort,%artist%)
$set(albumartistsort,%albumartist%)
When building html documentation, how do you force sphinx to report, or create an error, on links that don't exist?
Specifically, I have properties and methods within my Python project that have been removed or renamed, and it is hard to find all the dead links with the sphinx generated html output.
I feel like I'm staring at the answer here:
http://sphinx-doc.org/glossary.html, as descriped in the opening paragraph.
I'm obviously not understanding something.
Set the nitpicky configuration variable to True (you can also use the -n option when running sphinx-build).
In nitpicky mode, a cross-reference to a function (such as :func:`myfunc`), class, or other object that cannot be found will generate a warning message.
I think CheckExternalLinksBuilder is what you're looking for.
It's basically used by calling 'sphinx-build' with -b linkcheck option. Please see sphinx-build for more info. Also, take a look at the list of sphinx-extensions here and here.