tox-3.2.0 以降で usedevelop を指定しながら、deps に自身を指定するとハマる件

バグを踏み抜きました。

tox-3.2.0 以降で、次のような tox.ini を作っていると、テストを実行してもパッケージが更新されなくなります。

[testenv]
usedevelop = True
deps =
    .[extra]

具体的な条件としては

  • usedevelop を指定している
  • 自身を deps に extra 込みで指定している

のふたつです。

変更点を読み解いていくと、3.2.0 から deps のインストールコマンドが pip install から python -m pip に置き換わったのがきっかけのようです。この変更がなぜ問題を引き起こしているのかまでは追いかけきれませんでした。


この条件を満たすと、tox 内の virtualenv は次のような状況に陥ります。

  • 対象のコードは site-packages 以下にインストールされる
  • tox は usedevelop モードで動作するので、二度目以降は対象コードはインストールされない

そのため、この状態から抜け出すには --recreate (-r) をつけて、環境を作りなさなければなりません。

回避策は以下のいずれか。

1) deps に自身を書かない。extras を指定したい場合は tox.ini に extras 設定を追加する

[testenv]
usedevelop = True
extras = foo,bar,baz

2) install_command オプションに pip install を指定する (旧動作に戻す)

[testenv]
usedevelop = True
deps =
    .[extra]
install_command = pip install {opts} {packages}

3) tox-3.1.3 にバージョンを下げる


お使いの環境やプロジェクトに合わせて適切なものを選ぶと良いでしょう。
ちなみに 1) は tox-2.4 (2016-10-12) 以降向けです。

さて、Sphinx ではどうしようかしら。

Google 図形描画で書いた図を取り込む sphinxcontrib-googledrive をリリースしました。

ひとつ前の記事で書いた『マスタリング docutils』では、作図に Google 図形描画を使いました。

以前は Cacoo を使ったり、Inkscape を使ったりしていたんですが、維持するのにお金が必要だったり、
CI 環境を作るのが面倒くさかったりして、今回は Google 図形描画を使うことにしました。
あまり図が複雑ではなかったのと、手軽に書きたかったというのも、ツール選びに関係していそうです。

執筆中は時間もなかったので、書いた図は手でエクスポートして貼り込んでいましたが、いま振り返ると先にこのツールを作っておけばよかったと思います。
なにせ、図を書き換えるたびに

1. エクスポートして
2. (余計な空白が入るので) ImageMagick でトリミングして
3. リネームして特定の場所に置く

というのを手動で実行する必要があるのです。
『マスタリング docutils』では図は数点しかないものの、執筆に合わせて何度も書き換えていたので、
それに合わせてなんどもこの作業を繰り返していました。
一度二度ならいいのですが、何度もやってるとミスするんですよね、こういうやつ。

さて、もう執筆は終わって時間が取れたということで、やることはひとつです。
我々は技術の子ですから、こういう無駄な作業は自動化する以外に選択肢はありませんね。
ということで、作りました。
github.com

Google DriveAPI を使って画像をダウンロードし、いい感じにトリミングしてくれる Sphinx 拡張です。
しかも、PDF 出力のときはベクターデータで埋め込むようにしています。
(注意: まだ PDF のトリミング処理は実装していません)

これで図形の微調整を繰り返しても安心ですね。
全国の Google Drive 愛好家の皆さんはぜひ使ってみて、意見を貰えるとありがたいです。

おまけ:残念なところ

README ではリンクを貼るだけで説明を端折っていますが、Google Drive API を使うためにいくつかの作業が必要です。

  • Google Cloud Console でプロジェクトを作る
  • Google Drive API を有効にする
  • サービスアカウントを作る

最後のものは OAuth2 で代替できたのですが、CI 環境で扱いづらいのでサービスアカウントを使うことにしました。
公開範囲の管理にも関連するのですが、いまのところはこのやり方で行こうと思ってます。

技術書典5 で『マスタリング docutils』を出版しました

先週末、技術書典5に「マークアップ言語愛好会」というサークルで参加し、『マスタリング docutils』という本を出版しました。
techbookfest.org
techbookfest.org

マスタリング docutils

この本はこんなまえがきからはじまります。

みなさんは docutils をご存知でしょうか。
docutils はふたつの側面を持つソフトウェアです。
ひとつは Python 製のドキュメント処理フレームワークとしての側面。
もうひとつはそのフレームワークの上に実装されたドキュメント変換ツール群としての側面です。


本書では、前者のドキュメント処理フレームワークとしての docutils にスポットを当て、どのような構造をしているのか、
どのような順序で処理が行われるのか、そしてどのように拡張するのかについて紹介します。

Sphinx はこの docutils の上に構築されたツールです。したがって、SphinxSphinx 拡張を作る上で避けては通れません。しかし、残念なことに docutils はドキュメントや解説が少なく、理解がとてもむずかしいという問題があります。
自分が Sphinx の拡張を書き始めたときに、最初につまづいた (そして今も時々つまづく) のがここです。

本書はその問題をカバーすべく、docutils がどのような構造をしているのか、どのようなフローで処理が進むのか、
そしてどこが拡張ポイントなのかというのを紹介したおそらく世界初の docutils 解説書です。

執筆から販売まで

申し込んだ時点から予想はしていたのですが、今回は執筆時間に充てる時間が限られていました。
9月半ばに開催された PyCon JP 2018 での発表資料づくりに手間取ってしまったため、執筆できるようになったのが 2週間前でした。
そこからハイペースに執筆をして仕上げたのが本書です。

執筆期間が短いとボリュームが…という懸念があったものの書き上げてみると 60ページ弱になりましたし、
肝心のクオリティについても、(断腸の思いで一部見送った章があるものの) おおよそまんぞく行くものができました。

普段からよく触って中も覗いている docutils ですが、今回の執筆にあたって改めてこんなことをしています。

  • 歴史を追うために Doc-SIG の投稿を(ピックアップしながら)斜め読みした
  • 経緯を知るために PEP 256-258 をひたすら読んだ
  • 説明のために docutils のコードを読みふけった

ですので、内容についても胸を張ってお見せできるものです。

ひとつ残念だったのは、ギリギリすぎるスケジュールによって印刷に回す時間が取れなかったことですね。
そもそも技術書典に申し込んだゴールのひとつが Sphinx を使って、執筆から出版(印刷)までの過程を体感してみるというものだったので、自分の目標としては未達成でした。残念。

ツール

今回執筆に使ったのはこのあたりのツール / サービスです。

  • Sphinx (執筆、出力)
  • gitlab (CI)
  • Google drawings (画像)
  • slack (オンラインレビュー / 監視)
  • ラクスル (ダウンロードカード印刷)
  • ジョナサン (セルフ缶詰スペース)

反省

Twitter でいろいろ書いたのを貼り付けておきます。









今後の予定

本書をほしいという奇特な方が現れたので、Booth でダウンロード販売をしています。
興味がある方はこちらからどうぞ。

また、ダウンロードカードはまだ余っているので、カードが欲しい人はお声がけください。

大事なこと

本書で docutils に興味を持った人は、実際に docutils フレームワークをフル活用している事例として Sphinx があるので、
ぜひとも一緒に開発しませんか!
Sphinx プロジェクトではいつでも協力者を求めていますよ!

Re: Sphinx コードの半減期と未来予想図

ぼちぼち Sphinx-1.8 をリリースしようというこのタイミングで、以前書いた Sphinx コードの半減期と未来予想図 - Hack like a rolling stone を見かけたので、1年半ぶりに試してみました。

将来、また実行したくなったときにさくっと再現できるようにこんな Dockerfile を書きました。全部 RUN で書いてるのでとても雑ですね。

FROM ubuntu:bionic

RUN apt update; apt install -y python3 python3-pip git; apt-get clean
RUN pip3 install git-of-theseus
RUN git clone https://github.com/sphinx-doc/sphinx /sphinx
RUN git-of-theseus-analyze --ignore 'tests/*' /sphinx
RUN git-of-theseus-stack-plot /cohorts.json
RUN git-of-theseus-survival-plot /survival.json
RUN for mod in application builders directives domains environment ext util writers; \
do (cd /sphinx; echo $mod; find sphinx/$mod* -type f -exec git annotate {} \; | perl -ne 'm/(\d+)-\d+-\d+/; print $1, "\n"' | sort | uniq -c; echo); \
done
CMD cp /*.png /mnt

現時点の半減期グラフはこうなりました。なお、今回は tests/ ディレクトリは対象外にしています。
f:id:tk0miya:20180826183051p:plain

徐々にコード規模が増えてきてますね。
5年以上前のコードも徐々に新しいコードに入れ替わっていっています。2010-2012 あたりのコードは完全に虫の息ですね。


もうひとつのグラフは主要モジュールごとの年代比率です。
f:id:tk0miya:20180826164448p:plain
どのモジュールもここ 3年で大きく手が入っていますね。environment などは 75% 以上の書き換えが行われています。
これは行ごとのタイムスタンプから計算しているので、実装が大幅に変わったかどうかはわかりません (typo 修正にも反応する)が、リリースから 10年が経過したいまでもあちこちに手が入っていることがわかります。

ext や writers あたりは比較的古いコードがそのまま残されているようです。
この傾向は自分の感覚とも一致しています。


ところで、以前の記事ではこんなゴールを挙げていました。

  • Sphinx を細かくモジュール分割すること
  • モジュールの結合度を下げること
  • Sphinx 自身を Sphinx API で作ること

自分の感触としては、まだ道半ばという感じです。
クラス変数を使う箇所をかなり削ったり、API やモジュールの責務を整理したりと、一歩ずつ前に進んでいるので引き続き頑張っていきたいところです。

Sphinx 開発進捗報告 (2018.8)

みなさん、お久しぶりです。tk0miya です。

大変多くの方にスポンサーをしていただいたこともあって(参考)、なるべく定期的に進捗を報告したいなと思っていたのですが、ワールドカップを見ている間に今年もあっという間に半分以上過ぎてしまいました。時間が経つのは早いですね。

というわけで、Sphinx の開発進捗報告です。
f:id:tk0miya:20180804194048p:plain
イシューと PR の残数はこんな感じで遷移しています。
多少ジグザグしているものの、今年に入ってからおおよそ右肩上がりで推移していることがわかるかと思います。

片付けた件数はそれぞれイシューが 415件、PR が 526件でした。
それなりにクローズしているのですが、新たに投稿されるものがそれなりにあるということですね。

ちなみに、Sphinx プロジェクトでは久しぶりに新しいメンバーを迎えました。
検索やドキュメントまわりを担当してくれる TimKam です。
僕が不得意な JavaScript まわりをテコ入れしてくれるようなので、非常に期待しています。

さて、Sphinx は 9月にバージョン 1.8 のリリースを予定しています。
続いて来年の春にはいよいよ 2.0 がやってきます。
もともとは定期的なリリースのひとつでしかなかったのですが、古い API の削除や Python 2.7 のサポート終了など、いくつか大きい変更も行われます。

Enjoy documentation!

blockdiag を github に移動しました。

blockdiag の開発拠点を bitbucket から github に移動しました。

開発を始めた 2011年ごろ、僕は git より mercurial を好んでいたので bitbucket をメインリポジトリとしてチョイスしたのですが、
CI などを含めた周辺サービスとして、github に破れた感が長引いていました。drone.io も止まっていましたしね。

長らく更新すらしていなかったので、完全に見て見ぬふりをしていたのですが、新たにバグが報告されたのを受けて
重い腰を上げて github に移行することにしました。

イシューの移動

ソースコードそのものは、github の import 機能がいい感じにやってくれるので、何も考える必要はありません。
しかし、イシューについてはそうもいきません。

そこで @shimizukawa さんが改造した bitbucket_issue_migrator を使います。
www.freia.jp

ただ、この記事にも書いてありますが、そのまま利用すると全ての移行イシューの投稿者が自分になってしまいます。
その例として、Sphinx では先頭 2000件ぐらいのイシューは @shimizukawa アイコンが表示されています。

今回はその轍を踏まないようにアカウントを作ろうとしたのですが、残念ながら失敗に終わりました。
github の規約上、1人につき free account は1件までという規約があるそうで、それに引っかかってしまいました*1
というわけで、移行したイシューはすべて自分がオーナーになってます。

使い方は記事を見てください。

PR の移行

ツールが見当たらなかったこともあって、早々に諦めました。

CI 他の設定

まだやっていません。

今後の見通し

github に移動したことを受けてちょこちょこ進めていこうかと思っています。
ただ、Sphinx に割く時間がメインなのはしばらく変わらないと思います。
開発をぐいぐいと進めたいと思ってる人は、PR を投げるなりメンテナに立候補するなりしてください。

*1:知らずにトライしてしまい、サポートの方に余計な手間を掛けさせてしまいました。申し訳ない。

僕自身のスポンサーシップをはじめました

タイトルのとおりです。僕を支援していただくためのスポンサーシップをはじめました。

おかげさまでとても多くの方に賛同していただき、かなりの額を支援していただきました。
Sphinx やら blockdiag やら、自分が関わっているプロダクトが多くの人に使われている結果なのだと思うと、これからも継続していこうと思いを新たにしました。

ここでは、スポンサーシップを初めたときの自分の考えをまとめておこうかと思います。

なぜはじめたのか

gist にも書いたように、お茶代の捻出が目的です。
Sphinx のメンテナをやるようになってから、ちょくちょく喫茶店で開発をするようになりました。
通勤の電車の中や自宅でも活動しいますが、休日はまとまった時間を使うために近所の喫茶店にこもることが多々あります。
集中しやすいとか、気分転換とか、いくつかの要素があるんじゃないかと思っています。

ありがたいことに僕の OSS 活動にはあまり費用が掛かっていません。
最近は GitHubTravis CI のように、いろんなサービスで OSS 向けに無料のサービス提供をしていますし、所属している会社(株式会社タイムインターメディア)が開発機材を貸与してくれています*1。確かにドメインの更新費用やちょっとしたサービス利用料(S3 やら DNS やら)があるにはあるのですが、ちょっとした持ち出しで済んでいました。
そんな低コストの活動の中で、ひとつだけ "それなりの額" が掛かっているのが喫茶店代なのです。

チリも積もれば、とはよく言ったもので、一杯ではたいしたことがない紅茶も、たくさん飲めば結構な額に積み上がるんですね。束で買ったコーヒーチケットが雄弁に語っています。
f:id:tk0miya:20180421151943j:plain

喫茶店で開発してるなんて贅沢してるなー、と自分でも思う部分があるのですが、開発がはかどっているのも実感としてあります。そこで、この費用を個人の持ち出しではなく、スポンサーという形で協力してもらえないかと今回呼びかけてみました。

なぜ個人へのスポンサーなのか

今回募集しているスポンサーシップは、個人に対するものです。
Sphinx プロジェクトや blockdiag プロジェクトで呼びかけているものではありません。

理想で言えば、Sphinx プロジェクトとして広く (海外からも) 支援を受けたほうが、金額も集まりやすいですし、より多くの開発者に還元することができそうです。では、なぜ今回はプロジェクトとしてのスポンサーシップにしなかったのでしょうか。理由はふたつあります。

ひとつは先ほど説明したように、そもそものモチベーションがお茶代の支援という、極めて個人的で、しかも目標額が低いものだったのもあり、プロジェクトとして呼びかけるのは仰々しすぎました。

もうひとつは分配の問題です。現在の Sphinx プロジェクトはかなり多くの部分を僕がカバーしているとは言え、他のメンテナも要所要所で手助けしてくれているのも確かです。プロジェクトとしてスポンサーを集めた場合は、彼らにも同様に支援がなされるべきです。それを考えると一気に事務コストが増えます。公平な分配とはなんなのか。予算管理が必要になるのではないか。また、国際送金や税金についても考えなくてはなりません。

こうしたことを考えたときに、プロジェクトとしてスポンサーシップを進めるのはあまりに手間がかかりすぎると考えたので、こちらの線で検討するのは早々に諦めました。こうした分野に知見がある方が手伝ってくれるのであれば、いつかはプロジェクト規模でできると良いですが、今はその時ではないと考えています (自分の可処分時間を考えても)。

OSS でお金をもらうことについて

正直なところ、自分が OSS でお金をいただくことについては、自分の中でもスッキリはしていません。
自分ではない誰かが対価を得ることや、寄付を受けることについては気にならないのですが、いざ自分になると…という謎の感情があります。

あまり意識をしたことはないのですが、自分の中では OSS 活動は奉仕活動に近い、無償の活動だという思い込みがあるのかもしれません。一方で、それぞれの開発者のリソースは有限ですから、その活動は何かしらの形で讃えられてもおかしくないし、OSS でうまく稼げるのであればそれはそれでよい、とする見方も同居しています。
他者に対しては継続的でよいやり方だ、と褒め称える一方で、自分の場合はその部分にブレーキを踏んでいるのかもしれません。正直、自分でもなんでそんな考え方になっているのか、うまく説明できません。

もしかすると、対価を得てしまうと責任が発生するのではないかと恐れているのかもしれませんね。

最終的には半年以上悩んで、はじめて見ることにしました*2

責任感

ということで、責任感はあります。
プロジェクトへの支援であればまだしも、僕個人への支援ですので、もし1年間遊び呆けてしまったら、スポンサーに向けて顔向けできない、というプレッシャーはあります。
急に仕事が忙しくなってしまったら、Sphinx の開発に飽きてしまったらどうしよう、みたいな考えも頭によぎります。

とはいえ、そんなことを心配し続けても仕方がありませんし、そういうぼんやりとした不安はねじ伏せて、前に進むだけです。
いままでも Sphinx のメンテナであることのプレッシャーは多少なりともありましたし、忙しかった時期も遊んでいた時期も含めて、年間通じてメンテナンスし続けていたわけですしね。
お金をもらっていても、もらっていなくても、やることそのものは変わりません。

ということで、顔の皮を厚くしてこれまでのペースで "ほどほどに" やっていこうと思います。
スポンサーシップのおかげで「より速く前に進む」のではなく、これまでのペースを維持するということに捉えて、プレッシャーにしないように意識していこうと思います*3

ちなみに、6月にはワールドカップがあるので、その時期は活動が鈍るのは決定しています。あしからず。

申し訳無さ

つらつらと吐露していくと、他のメンテナ、他の OSS 開発者への申し訳無さみたいなものはあります。
それぞれ自分の時間や、何かしらの費用を持ち出しで OSS への貢献をしているのに、自分だけスポンサードされてよいのか、と思ったりもします。

ここも整理ができていないことのひとつです。なにか思うところがあったら教えてください。

指摘いただいたこと

おっしゃるとおりです。
いまの Sphinx プロジェクトはひとりに作業が偏ってるのであまり健全とは言えません。
過去を振り返っても、作者の Georg が開発していた時期、 @shimizukawa が引き継いで*4メンテナンスしていた時期、そして今、とどの時期もメインのメンテナが作業の大部分をしているというプロジェクトの構造は大きく変わっていません。

ですので、今の時点では協力してもらうべき「他のデベロッパ」がほとんどいないというのがそもそもの問題です。
ドキュメントという地味な分野は人気がないのか、あまり開発に参加したいという人が少ないのです。

ですから、あらためて声を大にしていいます。

Sphinx プロジェクトではメンテナを募集しています。
未経験者歓迎です。

イシューの切り分け、バグの再現確認、ドキュメントの更新、使い方の質問へのフォローアップなどなど、Sphinx の内部構造を知らなくてもできる作業も山ほどあります。
メンテナには日本人が多いので、日本語での相談なども気軽にできます。
興味がある方は声を掛けてもらえるとありがたいです。

税金


そのとおりですね。
寄付額が年間 110万円を超えると贈与税がかかりますので、もし他にスポンサーシップをはじめる人がいたらご注意ください。
自分の場合は問題なさそうです。

まとめ

  • スポンサーシップをはじめました
  • おちこんだりもしたけど、私は元気です
  • スポンサーは引き続き募集中です

*1:いつも言っていますが、非常にありがたいです。感謝しています。

*2:gist の履歴を見ると分かりますね。最初に作ったのは随分前です

*3:そうは言っても、今年に入ってからのペースは結構なものです。スポンサーシップにかかわらずどこかでギアを緩めないと、ふと燃え尽きてしまいそうなのでコントロールしたいところです。

*4:より正確には Georg がフェードアウトしていっただけなので、引き継いではいないようですが…