Documenting both class and constructor in Sphinx

How to make Sphinx document your Python class and constructor properly.


sphinxI lost an hour of my life today trying to figure out why Sphinx would not document a class inside a module specified by :automodule:.

I learnt two things today.

Firstly, Sphinx will not document a class automatically as part of :automodule: if the class itself doesn’t have a docstring. You can force the class to be displayed by having an additional :autoclass:directive though.

If the class does have a doc string, it will be displayed including the documentation of its regular (ones without a leading _ in the name) methods. It will still not show the constructor though.

To display the constructor, I first thought I would add the :special-members: option to the :automodule: directive. But that didn’t work very well, as it showed various unnecessary private functions as well, e.g. _weakref.

I finally discovered that the best way to get the constructor documentation displayed was using the autoclass_content config in the sphinx config file.

autoclass_content = 'both'

As per the documentation,

This value selects what content will be inserted into the main body of an autoclass directive. The possible values are:

  • “class”: Only the class’ docstring is inserted. This is the default. You can still document __init__ as a separate method using automethod or the members option to autoclass.
  • “both”: Both the class’ and the __init__ method’s docstring are concatenated and inserted.
  • “init”: Only the __init__ method’s docstring is inserted.

Using Python to update a required field while performing a transition in Jira

“Gojira!” by donsolo

This might be a very esoteric topic for most people, but since I could
not find information about this anywhere, I decided to document this
in a post.

Here is the problem. I use Jira at work, and today, I needed
to close a bunch of tickets based on a search result. Now, searching
or doing batch operations is simple enough from the browser, but a
small detail made the exercise impossible via the web UI.

Our Jira project requires a field to be filled while closing the
ticket – the time spent in the ticket. This breaks Jira in all sorts
of ways – the batch operation doesn’t work, some of the email-to-jira
interface at work breaks as well.

So I looked at doing this via the Jira Python library. But
it didn’t work as expected.

>>> from jira import JIRA
>>> jira = JIRA("https://JIRA_URL", basic_auth=('USER_NAME', 'Password'))
>>> issue = jira.issue("ISSUE-123")
>>> [(t['id'], t['name']) for t in jira.transitions(issue)]  # What are the workflows available?
[(u'4', u'Start Progress'), (u'5', u'Resolve Issue'), (u'2', u'Close Issue'), (u'711', u'Planning'), (u'751', u'Blocked'), (u'801', u'To Monitor')
>>> jira.transition_issue(issue, '2')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
jira.exceptions.JIRAError: JiraError HTTP 400
    text: Time Spent is required
    url: ...
    response headers = {...}
    response text = {"errorMessages":["Time Spent is required"],"errors":{}}

The documentation on transitions mentioned that
we could add fields in the call to jira.transitions(). That didn’t
work as well.

>>> jira.transition_issue(issue, '2', timespent="1h")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
jira.exceptions.JIRAError: JiraError HTTP 400
    text: Field 'timespent' cannot be set. It is not on the appropriate screen, or unknown.
    url: ...
    response headers = ...
    response text = {"errorMessages":[],"errors":{"timespent":"Field 'timespent' cannot be set. It is not on the appropriate screen, or unknown."}}

So I scoured the Internet for a long time, till I found this post
about how to do it via the REST API – the only official
interface to Jira. Here is what needs to be sent as the body to the
POST request.

    "transition": {
        "id": "2"
    "update": {
        "worklog": [
                "add": {
                    "timeSpent": "2m"

I felt that to be odd, till I looked at both the api documentation
for transition
and the doc for transition using the
python library
and I found out why I have not been
successful till now.

The REST api supports two ways to update the issue while doing a
transition – you can set certain fields using the fields option, or
you can use the update option to do more complex changes.

The comment in the Python code revealed that the update method has
not yet been implemented.

    def transition_issue(self, issue, transition, fields=None, comment=None, **fieldargs):

        # TODO: Support update verbs (same as issue.update())

That put me in a bind. I had only one way to hack around this problem
now – using the REST api for the specific operation I wanted, and the
Python library for the rest of the work – ugly, but works for now,
till the Python library is complete.

So here was the final solution that did what I wanted.

from jira import JIRA
import requests

jira = JIRA("https://JIRA_URL", basic_auth=('USER_NAME', 'PASSWORD'))

d = {}
d["transition"]={"id": "2"}
d["update"]={"worklog": [{"add": {"timeSpent": "1h"}}]}

s = requests.Session()
s.auth = ("USER", "PASSWORD")
s.headers.update({"Content-Type": "application/json"})


issue_list = jira.search_issues("assignee = currentUser() AND resolution = Unresolved  and status != Closed and updatedDate < '2015-10-01' and project='PROJECT' ORDER BY updatedDate DESC")

for i in issue_list:
    print i"/rest/api/2/issue/"+i.key+"/transitions", data=json.dumps(d))

German cycle superhighway opens its first stretch

“Commute” by triplefivedrew

The first 5km of a 100km cycle only superhighway has opened to public in Germany.

When complete, the route will connect 10 western cities including Duisburg, Bochum, and Hamm, and four universities. Martin Toennes of regional development group RVR says almost two million people live within 1.2 miles of the bicycle highway and will be able to use sections of it for their daily commutes. With the rise in popularity of electric bicycles to help with undulating terrain, RVR says the bike way, which utilizes mostly abandoned railroad tracks in the Ruhr Valley, could replace up to 50,000 motor vehicles during daily commuting hours.

When finished, it would be the longest surfaced urban cycling commute track in the world.

Continue reading “German cycle superhighway opens its first stretch”

Using your gut microbes to find the perfect diet

Cave Man Paleo breakfast. Photo by Katherine Lim
Cave Man Paleo breakfast. Photo by Katherine Lim

It seems every generation has its own bouquet of diets that people swear by.

In the early 80s, diet guru Nathan Pritikin believed that we should shun all fats and food containing cholesterol. He died of leukemia in ’85, but apparently his autopsy revealed that he had “arteries like those of a child and a heart like that of a young man”.

His arch rival in the time, Robert Atkins, of the Atkin’s Diet fame, espoused just the opposite – low-carb, high fat diets. His controversial death threw up allegations of a life long history of cardiac issues and obesity. But still there are people around who swear about it.

Loads of new diets have sprung up in recent years, with a loud number of them blaming carbs, sugar, starches and other GI (glycaemic index) manipulating food groups to be the cause of diet issues in the population.

Now a new article goes a bit deeper. It follows the published “study from an Israeli team led by Eran Segal”, to suggest that looking at all carbs the same way and avoiding them is too simplistic an approach. Human body is too complex and different sources of carbs affect different people in different ways. One of the major reason that they pointed out was the difference in the profile of the microbes in our digestive system!
Continue reading “Using your gut microbes to find the perfect diet”

Software patents put on hold in India

In a welcome move, the Indian patent office has temporarily stopped issuing software patents.

“In view of several representations received regarding interpretation and scope of section 3(k) of the Patents Act 1970 (as amended), the Guidelines for Examination of Computer Related Inventions… are kept in abeyance till discussions with stakeholders are completed and contentious issues are resolved,” the Controller General of Patents said in a notification issued last week.

Again, this is a temporary measure and given the intensive lobbying that happens behind doors, it could still be revised. But thanks to Ispirt, The Software Freedom Law Center, this is being considered seriously by the office.

As the article points out, software patents are ravaging the US software industry. For the big guys, they are used akin to the Mutually Assured Destruction mentality of the cold war, with every company keeping a vast portfolio of patents to fight back with if they are attacked for the same. But there is a big impact on smaller companies too. Bloomberg reports that:

Big companies are not the only ones being clobbered. According to a 2012 study by Boston University Law School professors Michael J. Meurer and James Bessen, some 90 percent of all patent-troll lawsuits are aimed at small and midsize companies. And these companies, when faced with unfathomable potential legal costs, often pay off the trolls just to make them go away.
Overall, Meurer and Bessen found, this abusive system is draining billions of dollars annually from the economy, transferring an estimated $29 billion in 2011 alone from the bank accounts of companies that produce things to patent trolls. Of this, small and midsize businesses, the types that are often at the cutting edge of innovation, paid about 37 percent of the total–money that could have been put to much better use.

Back to WordPress

It seems every year I change my blog backend, hoping it will make a difference to the frequency in blogging. After 10+ years blogging, I am older and wiser enough to know that it doesn’t. It is a losing battle. Content I would like to share with my family goes to Facebook, random quips go to Twitter. Pretty much wherever there is a more suitable audience.

In any case, writing or not, it is much better to move to a hosted solution, and I moved my domain and migrated my Jekyll website (painfully) to the hosted site.