ドキュメントされていない仕様が What’s New にだけコッソリと、兼 目を疑う誤訳

What’s old ではじめて知ったり再認識した機能は結構あるんだけれど。

翻訳しながら熟読してると、結構「そこにしかない」記述があんのね。

ワタシ、Python 公式ドキュメントでは割と褒めてばっかりいるけど、本当のところいくつか大きな不満があって、一つには「言語リファレンスが使いにくい」ことで、例えばジェネレータやイテレータといった基本言語機能の「とっかかり」を掴むのがまず大変で、なおかつ「全てが書かれているとは限らない」ことなのね。

What’s old してて改めて感じるんだけど、Python 公式ドキュメントは「Quick Start」がとても充実していて、実は「What’s New」がその一翼を担っている、ということなのね。それゆえに、なのかどうかはわからないんだけど、「完全ではないリファレンス」が割とある。

2.6 の What’s New に、ジェネレータの属性「gi_code」が使えるようになったことが書かれていた:

Generator objects now have a :attr:`gi_code` attribute that refers to the original code object backing the generator.

スニペットも何もない、まさにこの一言だけなのね。でこの英文が「誰が何を参照しとんねん」が掴みにくい。辛うじて

ジェネレータオブジェクトが、そのジェネレータを返すオリジナルのコードオブジェクトを参照する :attr:`gi_code` 属性を持つようになりました。

という意味であろうなと訳出するも、自信が持てないのでリファレンスを参照しようとして…。yield 式のリファレンスの末尾:

根底のイテレータが完全であれば、送出された StopIteration インスタンスの value 属性は、yield 式の値となります。これは StopIteration を送出するときに明示的に設定したり、サブイテレータがジェネレータであったときに (サブジェネレータから値を返すことで) 自動的に設定できます。

ん? んんんんんんんんんん?? んなわけない、んなわけない。なんだこの訳? 原文はこう:

When the underlying iterator is complete, the value attribute of the raised StopIteration instance becomes the value of the yield expression. It can be either set explicitly when raising StopIteration, or automatically when the sub-iterator is a generator (by returning a value from the sub-generator).

is complete は「実装がパーフェクトならば」なんて意味じゃない。仕方ないので訳を訂正しておいた:

根底のイテレータの完了時、引き起こされた StopIteration インスタンスの value 属性はその yield 式の値となります。 StopIteration を起こす際に明示的にセットされるか、サブイテレータがジェネレータであれば (サブイテレータからかえる値で) 自動的にセットされるかのどちらかです。

2.7 から間違っていたのだろうかと思ってみてみたら、3 系で初登場の表現らしい。そして前後よくみるとわかるのだが、訳者が明らかに直前までと違う。だってその前ではちゃんと「完了」と訳出できてんだもん。こういうの結構多いが、なんで前後よくみて翻訳できないんであろうか。

さて、本題の gi_code なんだけど、こんな感じ:

 1 me@host: ~$ cat hoge.py
 2 a = 1
 3 b = 2
 4 g = (i for i in range(10))
 5 
 6 print(g.gi_code)
 7 
 8 me@host: ~$ python hoge.py
 9 <code object <genexpr> at 0000000001D2FE30, file "hoge.py", line 3>
10 me@host: ~$ 

なるほど。たぶんプロファイラとかデバッグとかで使えるってことだろう。