Sphinx `todo` ignoring `todo`s in Python docstrings - python-sphinx

I'm using Sphinx's todo extension but the todo shown in my code below is being ignored - any ideas why? It does "see" todos placed into the index.rst file so the todo processing is enabled. Thanks for all suggestions because I'm out of ideas!
"""This is a test class definition."""
from typing import TypeVar
TypeTestMe = TypeVar("TypeTestMe", bound="TestMe")
class TestMe(object):
"""Simple object to test sphinx"""
def __init__(self: TypeTestMe, name: str) -> None:
"""
Constructor for the object.
The first line is brief explanation, which may be completed with
a longer one. For instance to discuss about its methods. The only
method here is :func:`function1`'s. The main idea is to document
the class and methods's arguments with
- **parameters**, **types**, **return** and **return types**::
:param str: The name of the owner of this object
:type arg1: string
:return: None
.. todo::
Todo in source code.
"""

OK, a whole raft of errors it turns out!
The todo comments are only picked up from docstrings so don't bother putting them into random comments in-line in your code
todo is built on top of autodoc so if autodoc is not documenting your code module, you won't get any todos either; fix-up your autodoc config if this is the error
The syntax for a todo block is indent sensitive so...
.. todo:: This comment will appear
.. todo::
This comment is ignored because of bad indentation and you get a warning
.. todo::
This is the correct indentation and this todo will appear.
Finally remember to check that your todo config is also correct.

Related

Can I tell pylint about a specific param a decorator requires and have it not apply unused-argument?

I use pyinvoke which has a task decorator that works like this:
#task
def mycommand(
# MUST include context param even if its not used
ctx: Context
):
# Do stuff, but don't use ctx
Even if I don't use ctx I must include it for pyinvoke to work correctly. Pylint throws Unused argument 'ctx' Pylint(W0613:unused-argument).
From what I have read in GitHub issues it seems like it would be unreasonable to expect pylint to dig into decorators and figure them all out automatically.
I also don't want to turn off this pylint rule for the entire function.
Is there a way I can tell pylint that if the #task decorator is used do not apply the W0613 rule to the first argument of the function?
When there is code that is too dynamic and impossible to parse for pylint it's possible to create a "brain" i.e. a simpler version that will explain what the code does to astroid (the internal code representation of pylint). Generally this is what a pylint plugin does (for example pylint-django will do it for view function that need request, which is similar to your issue with ctx). Here's an example of brain for signal directly in astroid and the documentation. It's possible that a pylint plugin already exists so you don't have to do this yourself.

Sphinx add hyperlink to referenced modules [duplicate]

I have installed Sphinx in order to document some Python modules and class I'm working on. While the markup language looks very nice, I haven't managed to auto-document a Python code.
Basically, I have the following Python module:
SegLib.py
And A class called Seg in it. I would like to display the docstrings of the class and module within the generated Sphinx document, and add further formatted text to it.
My index.rst looks like this:
Contents:
.. toctree::
:maxdepth: 2
chapter1.rst
and chapter1.rst:
This is a header
================
Some text, *italic text*, **bold text**
* bulleted list. There needs to be a space right after the "*"
* item 2
.. note::
This is a note.
See :class:`Seg`
But Seg is just printed in bold, and not linked to an auto-generated documentation of the class.
Trying the following didn't help, either:
See :class:`Seg`
Module :mod:'SegLib'
Module :mod:'SegLib.py'
Edit: changed SegLib to segments (thanks, iElectric!), and changed chapter1.rst to:
The :mod:`segments` Module
--------------------------
.. automodule:: segments.segments
.. autoclass:: segments.segments.Seg
Still, can't get Sphinx to directly document functions within a class, or better - to automatically add all the functions within a class to the document. Tried:
.. autofunction:: segments.segments.Seg.sid
and got:
autodoc can't import/find function 'segments.segments.Seg.sid', it reported error: "No module named Seg"
Any ideas how to auto-document the functions and classes with a short command?
Add to the beginning of the file:
.. module:: SegLib
Try using :autoclass: directive for class doc.
BTW: module names should be lower_case.
EDIT: I learned a lot from reading other source files.

Ignore Sphinx autodoc warnings for rtype values

Right now autodoc seems to throw warnings for any rtype value that is not just an object type (a class instance, int, list, dictionary, etc). So a return value such as "list of tuples" will throw a warning. Is there any way to ignore these warnings (either individually or on the whole)? I don't want to ignore the whole file, just those specific warnings.
An example of this warning might be something like:
/path/to/code.py:docstring of path.to.code.method:: WARNING: py:class reference target not found: list of tuples
And in some cases, I'm seeing errors for objects that I know are legit classes imported in the code like:
/path/to/code.py:docstring of path.to.code.method:: WARNING: py:class reference target not found: Response
In that example, "Response" is part of rest_framework.response, so it's a pretty commonly used class object.
These warnings happen anytime I do a fresh make docs. It's not clear to be that it can be reproduced in another environment.
The solution here was that the classes in question were not in a toctree, so were not part of the docs. Basically, autodocs wants to be able to link to classes mentioned in type variables. If it can't do that, it will throw an error saying "I have no idea what "Response" is (or whatever the class happens to be that you return). Not an error, because it assumed you're right, but a warning that it can't find it. So the solution here was to create an index.rst that included the class, then a Response.rst (for example) including the relative path to the class. Below is an example of this process. It assumes that Response is in a rest.py.
error: /path/to/code.py:docstring of the.code.rest.GetAccount.get:: WARNING: py:class reference target not found: Response
In my case, this needed the following:
add a line item for response to modules/code/rest.rst
add response.rst in the same directory
include the line `.. automodule:: code.rest.Response
Then delete and rebuild docs and it should be good to go.

Rails logger formatting - insert method name calling logger method

I want to insert name of the method calling the logger methods into my log files. Not the whole stack trace, but the class, method and/or line number would be great.
In any method, one can use caller to get an array of strings, each of which contains the file, line number and method name. I've come up with a pretty awful kludge using regexes and Enumerable#find to try to return the first non-logger stack frame. I guess it works, but if the locations of the logging Ruby files change in a different version or Rails, or I name my files something to do with logs, it will break. Same with if I take a given index from the top of the stack (I did this at first, then refactored one thing and naturally it gave me the wrong frame).
Note that I'm not looking to just log the controller or action, as those can be retrieved easily. Mostly this is for stuff in the lib/ directory.
Isn't there an easy way to do this? I don't want to have to pass in __method__ every time I make a logging statement.
I've looked all over at different solutions for capturing the exact place (file, line number, method name) where I invoke any given logger instance method from within my rails app. To do this, you need to override Logger's format_message method, and a good place to do this is in your rails project's config/environment.rb file.
This is what I've come up with, which is good enough for me ;o)
class Logger
def format_message(severity, timestamp, progname, msg)
line = ''
Kernel.caller.each{|entry|
if (entry.include? Rails.root.to_s)
line = " #{entry.gsub(Rails.root.to_s,'').gsub(/\/(.+)\:in `(.+)'/, "\\1 -> \\2")}"
break
end
}
"[#{timestamp.strftime("%Y%m%d.%H:%M:%S")}] #{severity}#{line}: #{msg}\n"
end
end
Kernel.caller holds an enumerable array of the entire backtrace. If you look at it in its entirety, you'll see most calls are internal inside of a gem somewhere well outside your project. I've found that by looping through the Kernel.caller until I find the first place that includes my Rails.root, I can get the line with the information I want to parse.
Example:
If I call Rails.logger.debug("Streamer class started!") from the start method of my Streamer class, the raw entry would look like this:
/Users/chikoon/www/my_rails_app/lib/streamer.rb:7:in `start'
so by the time it makes it through my formatter, I've got the timestamp, severity mode, the file path, line number, method name, and message:
[20140919.19:23:44] DEBUG lib/streamer.rb:7 -> start: Streamer class started!
I hope that helps get your wheels turning.
How about setting up log_tags to call the __method__?
Blog::Application.configure do
config.log_tags = [lambda { |req| __method__ }]
end

Qt QLineEdit custom validation in ruby

I am trying to implement QLineEdit's text which is all capital letters no matter what user types in. I have found several solutions, none of them working in Ruby. In brief I have QLineEdit object searchEdit and this code:
class UpcaseValidator < Qt::Validator
def validate(input,pos)
input.upcase!
Qt::Validator::Acceptable
end
end
...
def initialize(parent = nil)
uppercaseValidator = UpcaseValidator.new;
searchEdit.setValidator(uppercaseValidator)
...
The validate method gets triggered correctly whenever user types in the input field, but it is not getting uppercased. Seems to me that changing input variable within validate does not get propagated back to the searchEdit object.
Thanks for any help, even pointing me out to some good docs about Qt Ruby bindings.
QValidator has a method called 'fixup()', which will probably do what you want :)

Resources