2013-03-31

RHEL6: ifconfig is obsolete!

前回エントリで、expand_config を見て気付いたことがある。

RHEL6 では、インターフェイスに複数の IP アドレスを設定できるらしい。そういえば OS インストール時のネットワーク設定画面では、複数 IP アドレスが登録できそうな UI になっていた。今まで試したことはなかったが、実際にそこで複数 IP アドレスを設定してみると、ifcfg-* は次のようになる。

RHEL6.4: /etc/sysconfig/network-scripts/ifcfg-eth0:

DEVICE=eth0
TYPE=Ethernet
UUID=7f36ffb3-0b2a-48d5-9e81-18b685396f06
ONBOOT=yes
NM_CONTROLLED=yes
BOOTPROTO=none
HWADDR=00:0C:29:94:42:BD
IPADDR=192.168.0.1
PREFIX=24
IPADDR2=192.168.0.2
PREFIX2=24
IPADDR3=192.168.0.3
PREFIX3=24
DEFROUTE=yes
IPV4_FAILURE_FATAL=yes
IPV6INIT=no
NAME="System eth0"

これは完全に意図通りに動く。もう仮想インターフェイスなんて(eth0:1 とか)必要ない。ていうか、できるんだったらもっと早く(略)。尤も、IP アドレス毎に ifup / ifdown する必要があるなら、仮想インターフェイスは相変わらず有用ではある。

しかしインターフェイスに複数の IP アドレスを設定できるなら、今現在インターフェイスで有効な IP アドレスを知る手段も必要になる。これらは 2 つで 1 つ、どちらか一方だけでは意味がない。しかし残念ながら、ifconfig はその役には立たないらしい。

[rhel64]# ifconfig eth0
eth0      Link encap:Ethernet  HWaddr 00:0C:29:94:42:BD
          inet addr:192.168.0.1  Bcast:192.168.0.255  Mask:255.255.255.0
          inet6 addr: fe80::20c:29ff:fe94:42bd/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:42649 errors:0 dropped:0 overruns:0 frame:0
          TX packets:18439 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:26605808 (25.3 MiB)  TX bytes:2001382 (1.9 MiB)

困った時の、man 頼み。

[rhel64]# man ifconfig
NAME
       ifconfig - configure a network interface

SYNOPSIS
       ifconfig [interface]
       ifconfig interface [aftype] options | address ...

NOTE
       This  program  is obsolete!  For replacement check ip addr and ip link.
       For statistics use ip -s link.

obsolete! と言ってくれたところで、一体どれだけの人が気付くというのか。今回のことがなければ、私も man を読もうとは思わなかったし。それはともかく、これからは ip addr を使え、と。

[rhel64]# ip addr show eth0
2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:94:42:bd brd ff:ff:ff:ff:ff:ff
    inet 192.168.0.1/24 brd 192.168.0.255 scope global eth0
    inet 192.168.0.2/24 brd 192.168.0.255 scope global secondary eth0
    inet 192.168.0.3/24 brd 192.168.0.255 scope global secondary eth0
    inet6 fe80::20c:29ff:fe94:42bd/64 scope link
       valid_lft forever preferred_lft forever

この ip addr は RHEL5 でも動く。(RHEL4 以前は知らない)

以上より、

もう ifconfig は時代遅れらしいよ。

ちなみに前回の話に出た Webmin (1.620)だが、やはりこの複数 IP アドレスには対応していない。2 番目以降の設定は Webmin 画面からは見えないし、変更することもできない。よって Webmin でネットワーク設定を行うつもりなら、この複数 IP アドレス機能も使わない方が良い。

2013-03-27

RHEL6: PREFIX overrides NETMASK in `ifcfg-*'

RHEL6 インストール画面で固定 IP アドレスを設定すると、ifcfg-* には NETMASK の代わりに PREFIX という項目が記入される。名前から NETMASK の代替であることは分かるし、実際にそう動く。しかし、もし PREFIX と NETMASK の両方が設定され、その内容が矛盾していたらどうなるのか。

似た関係に NETMASK / NETWORK / BROADCAST があるが、これは公式ドキュメントに記載がある。

BROADCAST=address
where address is the broadcast address. This directive is deprecated, as the value is calculated automatically with ipcalc.
NETMASK=mask
where mask is the netmask value.
NETWORK=address
where address is the network address. This directive is deprecated, as the value is calculated automatically with ipcalc.

曰く、「NETWORK と BROADCAST は非推奨です」と。しかし、PREFIX については何処にも記述が見当たらない。試しに grep -i prefix /etc/sysconfig/network-scripts/* してみると、この辺りの処理を行っている場所は 1 か所しかない。

RHEL6.4: /etc/sysconfig/network-scripts/network-functions:

expand_config ()
{
    local i=0 val
    for idx in '' {0..255} ; do
        ipaddr[$i]=$(eval echo '$'IPADDR$idx)
        if [ -z "${ipaddr[$i]}" ]; then
           [ "$idx" ] && [ $idx -gt 2 ] && break
           continue
        fi
        prefix[$i]=$(eval echo '$'PREFIX$idx)
        netmask[$i]=$(eval echo '$'NETMASK$idx)
        broadcast[$i]=$(eval echo '$'BROADCAST$idx)
        arpcheck[$i]=$(eval echo '$'ARPCHECK$idx)

        if [ "${prefix[$i]}x" != "x" ]; then
            val=$(/bin/ipcalc --netmask "${ipaddr[$i]}/${prefix[$i]}")
            netmask[$i]=${val##NETMASK=}
        fi

        if [ "${netmask[$i]}x" = "x" ]; then
            val=$(/bin/ipcalc --netmask "${ipaddr[$i]}")
            netmask[$i]=${val##NETMASK=}
        fi

        if [ "${prefix[$i]}x" = "x" ]; then
            val=$(/bin/ipcalc --prefix ${ipaddr[$i]} ${netmask[$i]})
            prefix[$i]=${val##PREFIX=}
        fi

        if [ "${broadcast[$i]}x" = "x" ]; then
            val=$(/bin/ipcalc --broadcast ${ipaddr[$i]} ${netmask[$i]})
            broadcast[$i]=${val##BROADCAST=}
        fi

        if [ "${arpcheck[$i]}x" != "x" ]; then
            arpcheck[$i]=${arpcheck[$i]##ARPCHECK=}
            arpcheck[$i]=${arpcheck[$i],,*}
        fi

        i=$((i+1))
    done

    if [ -z "${NETWORK}" ]; then
        eval $(/bin/ipcalc --network ${ipaddr[0]} ${netmask[0]})
    fi
}

これによると、

  1. PREFIX が設定されていれば、PREFIX から NETMASK が計算される。
  2. NETMASK が未設定(空)であれば、IPADDR から NETMASK が計算(推測)される。
  3. PREFIX が未設定(空)であれば、IPADDR / NETMASK から PREFIX が計算される。

つまり、PREFIX は NETMASK より強い。ついでに言うと、公式ドキュメント通り BROADCAST と NETWORK はどちらも IPADDR / NETMASK から自動計算されるが、それは値が未設定(空)である場合に限られる。

念のため RHEL5 でも確認しておくと、

RHEL5.9: /etc/sysconfig/network-scripts/network-functions:

expand_config ()
{
    if [ -z "${NETMASK}" ]; then
	eval `/bin/ipcalc --netmask ${IPADDR}`
    fi

    if [ -z "${PREFIX}" ]; then
	eval `/bin/ipcalc --prefix ${IPADDR} ${NETMASK}`
    fi

    if [ -z "${BROADCAST}" ]; then
	eval `/bin/ipcalc --broadcast ${IPADDR} ${NETMASK}`
    fi

    if [ -z "${NETWORK}" ]; then
	eval `/bin/ipcalc --network ${IPADDR} ${NETMASK}`
    fi
}
  1. NETMASK が未設定(空)であれば、IPADDR から NETMASK が計算(推測)される。
  2. PREFIX が未設定(空)であれば、IPADDR / NETMASK から PREFIX が計算される。

これだけではどちらが強いのか分からないが、合わせて expand_config の呼び出し元(/etc/sysconfig/network-scripts/ifup-eth)を見ると、実際に使われるのは PREFIX の方だと分かる。

よって RHEL5 でも、PREFIX は NETMASK より強い。RHEL4 以前は使ってないので知らない。

そもそも何故こんなことを気にするかというと、現在の Webmin (1.620)が PREFIX に対応してないっぽいから。Webmin は NETMASK を設定するが、PREFIX には一切関与しない(消しもしない)。よって PREFIX と NETMASK の両方が ifcfg-* に記述される状況が生まれてしまう。もし Webmin でネットワーク設定を行うなら、事前に全ての PREFIX を NETMASK に変換しておいた方が良い。でないと、いつか痛い目を見る可能性がある。


2014-06-19 追記

今更だが、Webmin 1.630 にて PREFIX 対応が行われた。

2013-02-27

RHEL6: ssh-keygen: Permission denied

SSH 鍵を作ろうとすると、「Permission denied」と言われる。

[rhel62]# mkdir ~/.ssh

[rhel62]# chmod 700 ~/.ssh

[rhel62]# ls -dl ~/.ssh
drwx------. 2 root root 4096 Feb 27 09:04 /root/.ssh

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ; echo $?
Generating public/private rsa key pair.
open /root/.ssh/id_rsa failed: Permission denied.
Saving the key failed: /root/.ssh/id_rsa.

パーミッションに抜かりなどある訳がない。失礼な。こういう時、真っ先に疑うべきは SELinux。

/var/log/audit/audit.log:

type=AVC msg=audit(1361923639.970:20915): avc:  denied  { create } for  pid=1932 comm="ssh-keygen" name="id_rsa" scontext=unconfined_u:unconfined_r:ssh_keygen_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:admin_home_t:s0 tclass=file
type=SYSCALL msg=audit(1361923639.970:20915): arch=c000003e syscall=2 success=no exit=-13 a0=7f6f3282cb80 a1=241 a2=180 a3=fffffff7 items=0 ppid=1875 pid=1932 auid=0 uid=0 gid=0 euid=0 suid=0 fsuid=0 egid=0 sgid=0 fsgid=0 tty=pts3 ses=2 comm="ssh-keygen" exe="/usr/bin/ssh-keygen" subj=unconfined_u:unconfined_r:ssh_keygen_t:s0-s0:c0.c1023 key=(null)

案の定、何か文句を言っている。~/.ssh のコンテキストを確認すると、

[rhel62]# ls -dZ ~/.ssh
drwx------. root root unconfined_u:object_r:admin_home_t:s0 /root/.ssh

何処が気に入らないのかは良く分からないが、ともかく restorecon してみる。

[rhel62]# restorecon ~/.ssh

[rhel62]# ls -dZ ~/.ssh
drwx------. root root unconfined_u:object_r:ssh_home_t:s0 /root/.ssh

何か修正されたっぽいので、リトライ。

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa
Generating public/private rsa key pair.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
a7:14:6f:f0:8a:72:64:20:01:55:2b:24:4c:aa:a7:30 root@rhel62
The key's randomart image is:
+--[ RSA 2048]----+
|=++..            |
|.+ . .           |
|. o o   o        |
|.  o .   =       |
|E .   o S =      |
|.+   o o =       |
|.   . o o        |
|     o           |
|                 |
+-----------------+

動いた。ちなみに ~/.ssh を作るのを ssh-keygen に任せると、何もしなくても上手くいく。

[rhel62]# rm -fr ~/.ssh

[rhel62]# ls -dl ~/.ssh
ls: cannot access /root/.ssh: No such file or directory

[rhel62]# ssh-keygen -t rsa -N '' -f ~/.ssh/id_rsa ; echo $?
Generating public/private rsa key pair.
Created directory '/root/.ssh'.
Your identification has been saved in /root/.ssh/id_rsa.
Your public key has been saved in /root/.ssh/id_rsa.pub.
The key fingerprint is:
e6:83:f6:38:dc:fc:eb:6a:45:f1:39:05:34:7d:ad:68 root@rhel62
The key's randomart image is:
+--[ RSA 2048]----+
|           .+o  .|
|          .  .o o|
|           o + o |
|          . E .  |
|        S. . .   |
|       +  .      |
|     .ooo.       |
|     .oo+.       |
|      .oo++.     |
+-----------------+

これは理屈としては理解できるが、非常に分かり辛い動作だと思う。

この理屈に従うと、作ったファイル・ディレクトリが SELinux のポリシーに沿っているかどうか、逐一確認しなければならくなってしまう。そういうことを平気で要求する SELinux の気が知れない。だから「SELinux 氏ね」とか言われるんだよ。:-p

ところでコンテキストの修正は restorecon で行えるが、現在のコンテキストが正しいかどうかはどうやって確認すれば良いのか。

matchpathcon を使え、と。

[rhel62]# rm -fr ~/.ssh

[rhel62]# mkdir ~/.ssh

[rhel62]# chmod 700 ~/.ssh

[rhel62]# matchpathcon -V ~/.ssh ; echo $?
/root/.ssh has context unconfined_u:object_r:admin_home_t:s0, should be system_u:object_r:ssh_home_t:s0
1

[rhel62]# restorecon ~/.ssh

[rhel62]# matchpathcon -V ~/.ssh ; echo $?
/root/.ssh verified.
0

注意点として、matchpathcon には絶対パスを渡す必要がある。でないと判定に失敗する。

[rhel62]# ls -dZ .ssh
drwx------. root root unconfined_u:object_r:ssh_home_t:s0 .ssh

[rhel62]# matchpathcon -V .ssh ; echo $?
.ssh has context unconfined_u:object_r:ssh_home_t:s0, should be <<none>>
1

これも理解できる動作ではあるが、やはり分かり辛い。もう少しマシなメッセージは出せないのかと文句を言いたい。

と、いうようなことを実は 1 年以上前にやっていたのだが、最近になって RHEL6.3 では本現象が起こらないことに気が付いた。調べてみると、この辺か。

「理解できる」と言っておいてアレだが、どうやら仕様ではなかったらしい。

2013-01-20

Animes in the 4th quarter of 2012

アニメは IT エンジニアの必須科目です。 ということで簡単なレビューを。

最初、主人公は一匹狼的でカッコ良さげなのだが、ヒロインと合流してからヘタれてしまう。このヒロインは男をダメにするサゲ○○に思えてならない。アクセル・ワールドと同じ作者と聞いて、妙に納得した。この人は世界観は良いが、脚本がダメなんだと思う。音楽だけは良いと思ったら、梶浦由紀だった。これも納得。

序盤は人類が天敵にエサにされるという展開。またキツいのが始まったなあ、と思っていたら、後半は殆ど人間の話になった。人の敵は人の心の中にこそある、というのは真実だとは思うが、結果として至って普通の話になった。個人的には、最初の絶望的な雰囲気で進めて欲しかった。きっと見るのは鬱になっただろうけど。

第一章はさっぱり面白くなかったが、第二章も変わらず。団結力だけが取り柄の弱っちい主人公達が仲間割れしたら、いったい何を褒めれば良いのか。最後に強くカッコよくなるが、その過程が理不尽。想いだけで強くなれたら世話ない。第一章と同様、OP くらいしか褒められるところが無かった。

少女マンガ原作ながらイマイチだった。ヒロインが惚れっぽくて話の展開が読める。神様の仕事そっちのけで狐とイチャつくことしか頭にない神様ってどうよ。まあ確かに年頃の女子とはそういうものだろうが、話もギャグも中途半端でお気に入りのキャラも無し、というのが正直な感想。ただ OP・ED は作品の雰囲気に合った良作。

原作は読んでたつもりだったが話がさっぱり思い出せない。と思ったら、実はアニメ用のオリジナルだったらしい(by Wikipedia)。そのせいかは分からないが、個人的にはイマイチな内容だった。本シリーズにしては、話が真面目すぎる気がする。まあ私はアニメより漫画の方が面白いと思ってるので、私的には問題ない。

今度は戦車を女子化か!?と思ったら流石にそれは無かった。戦車のことは知らないが、戦車の挙動がやけにリアルで、嘘かも知れないが本当にドリフトとかしそうに思える。個人的には好きな作品だったが、決勝戦の最中に「私たちの戦いはこれからです!!」と衝撃の終わり方。決して不人気のせいではなく、内部事情だと思いたい。

本シリーズは初めての視聴。原作も未読なので、最初は女子キャラの区別が付かなかった。ご都合展開全開の作品だが(何故いちいちパンツに突っ込む?という台詞は道理)、長寿作品なだけあって各キャラの個性は立っている(主人公を除く)。ただ長女の扱いがサブキャラ並みだなと思ったら、本作は一応スピンオフ作品だとは知らなかった。

原作は最初の五話くらいで挫折。ただ現在も連載中なので、アニメで魅力を発見できるかと期待したが、もう全然ダメだった。主人公、ヒロイン、敵の親玉、どいつの台詞も嘘くさくて私には全く受け付けられない。これは次回作があっても見ないと断言できる。

前期からの続き。序盤は雰囲気が変わったように思えて心配になったが、中盤以降は元に戻ったので安心。ただし最終回は消化不良。いきなり「2 年後」もそうだが、ヨナの心の変化、どう納得したのかが良く分からなかった。サブキャラの近況描写も一瞬だし、「風」の意味も不明。まあそれを差し引いても、全体としては十分に満足。

今クールの少女マンガ原作では、ダントツの出来。ギャグベースのドタバタ劇に、出てくる女子キャラは(サブキャラでさえも)魅力的で、見ていて飽きない。少女マンガ原作はこうでないとね。今回は「種﨑敦美」を覚えた。鈴木達央も今回の演技で見直した。唯一の不満は、最終回があっさり過ぎて終わったことに気付かなかったこと。

典型的な少女マンガという印象。内気なヒロイン、自分勝手で強引なイケメン、ライバルの出現。最初「君に届け」とデジャヴったが、君届には全く及ばなかった。風早くんの方がよっぽどいい奴だし、シリアス一辺倒で話に遊びがない(最終回を除く)。次回予告は良かったが、そういう遊びを本編にも入れて欲しかった。

まず目を引くのが独特な画質。特に空間制御魔法の描写が印象的。キャラも主人公以外は魅力的で、個人的にはネコがお気に入り。ただ、話がキャラに追いついていない感じがする。キャッチコピーの「きずな」は何処に出てきた? 結局ネコが何者かも分からないし。まあ既に続編が決定しているらしいので、そちらでの解決に期待。

大して期待していなかったが、賑やかさ・パロディー・エロス(?)など、その方面で期待していた「生徒会の一存」を食ってしまった。しかしそれは同時に、万人から見るととても「疲れる」作品になってしまった可能性も否定できない。個人的には元ネタが分からないパロディーがあったのが悔しい。まだまだ勉強が足りないようだ。

前作が結構好きだったので、引き続き視聴。しかし前作の勢いが感じられず、前半は空回りが目立つ印象。林檎、飛鳥での話のような盛り上がりがもっとあれば良かった。この作品の肝は生徒会メンバーの「デレ」だから。制作会社や声優が変わったりと扱いが不憫だが、そこまでして第二期を製作する必要があったのかは疑問。

2012-12-16

Python: cElementTree returns non open object

xml.etree.cElementTree は、xml.etree.ElementTree の C 実装だ。

ElementTree クラスはエレメントの構造を包み込み、それと XML を行き来するのに使えます。

この API の C 実装である xml.etree.cElementTree も使用可能です。

C 実装であること以外、ElementTree と cElementTree の違いについては述べられていない。違いがないなら、C 実装の方を使わない手はない。しかし、

$ python
Python 2.6.6 (r266:84292, Sep 12 2011, 14:03:14)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.ElementTree
>>> html = '<html></html>'
>>> tree = xml.etree.ElementTree.fromstring(html)
>>> tree.html = html
>>> tree.html
'<html></html>'
$ python
Python 2.6.6 (r266:84292, Sep 12 2011, 14:03:14)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import xml.etree.cElementTree
>>> html = '<html></html>'
>>> tree = xml.etree.cElementTree.fromstring(html)
>>> tree.html = html
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: html

cElementTree が返すオブジェクトはオープン・オブジェクトではないらしく、属性を追加することができない。C 実装されたモジュールとはそういうもんか、とも思ったが、

$ python
Python 2.6.6 (r266:84292, Sep 12 2011, 14:03:14)
[GCC 4.4.5 20110214 (Red Hat 4.4.5-6)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import cProfile
>>> p = cProfile.Profile()
>>> p.foo = 'foo'
>>> p.foo
'foo'

同じ C 実装モジュールの cProfile では問題ない。想像するに、ElementTree の場合、木構造で大量のオブジェクトを使用するためメモリをケチってるのかも知れない。

ともかく、RHEL5 + elementtree で作ったスクリプトを RHEL6 で動そうと喜んで cElementTree を使った私にとっては、この上ないぬか喜びだった。

2012-11-21

psycopg2: Can't mogrify `None' in a tuple to `NULL'

RHEL6 付属の psycopg2 で、

# rpm -qa | grep psycopg
python-psycopg2-2.0.13-2.el6_1.1.x86_64

tuple 中にある None を mogrify するとエラーになる。

test1.py:

#!/usr/bin/python

import psycopg2.extensions

def main():
    conn = psycopg2.connect('dbname=testdb user=testuser')
    cur = conn.cursor()
    for param in [0, [0], (0,), '', [''], ('',), None, [None], (None,)]:
        print '%s\t->' % repr(param), cur.mogrify('%s', [param])

if __name__ == '__main__':
    main()
$ python test1.py
0       -> 0
[0]     -> ARRAY[0]
(0,)    -> (0)
''      -> E''
['']    -> ARRAY[E'']
('',)   -> (E'')
None    -> NULL
[None]  -> ARRAY[NULL]
(None,) ->
Traceback (most recent call last):
  File "/root/tmp/test1.py", line 12, in <module>
    main()
  File "/root/tmp/test1.py", line 9, in main
    print '%s\t->' % repr(param), cur.mogrify('%s', [param])
  File "/usr/lib64/python2.6/site-packages/psycopg2/extensions.py", line 100, in getquoted
    qobjs = [str(o.getquoted()) for o in pobjs]
AttributeError: 'str' object has no attribute 'getquoted'

落ちている場所は、

/usr/lib64/python2.6/site-packages/psycopg2/extensions.py:

# The SQL_IN class is the official adapter for tuples starting from 2.0.6.
class SQL_IN(object):
    """Adapt any iterable to an SQL quotable object."""

    def __init__(self, seq):
        self._seq = seq

    def prepare(self, conn):
        self._conn = conn

    def getquoted(self):
        # this is the important line: note how every object in the
        # list is adapted and then how getquoted() is called on it
        pobjs = [adapt(o) for o in self._seq]
        for obj in pobjs:
            if hasattr(obj, 'prepare'):
                obj.prepare(self._conn)
        qobjs = [str(o.getquoted()) for o in pobjs]
        return '(' + ', '.join(qobjs) + ')'

    __str__ = getquoted

register_adapter(tuple, SQL_IN)

print デバッグすると直ぐに分かるが、このとき o には 'NULL' という文字列(str 型)が入っている。当然、単なる文字列に getquoted なんてメソッドがあるはずがない。そりゃ落ちるわ。

何がどうあるべきなのかは分からないが、「動かないシステムに価値はない」の持論に従い、ともかく動くようにする。

test2.py:

#!/usr/bin/python

import psycopg2.extensions

# Fix a bug that can't mogrify `None' in a tuple to `NULL'
class FIXED_SQL_IN(object):
    def __init__(self, seq):
        self._seq = seq

    def prepare(self, conn):
        self._conn = conn

    def getquoted(self):
        adapt = psycopg2.extensions.adapt
        pobjs = [adapt(o) for o in self._seq]
        for obj in pobjs:
            if hasattr(obj, 'prepare'):
                obj.prepare(self._conn)
        qobjs = [getattr(o, 'getquoted', o.__str__)() for o in pobjs]
        return '(' + ', '.join(qobjs) + ')'

    __str__ = getquoted

psycopg2.extensions.register_adapter(tuple, FIXED_SQL_IN)

def main():
    conn = psycopg2.connect('dbname=testdb user=testuser')
    cur = conn.cursor()
    for param in [0, [0], (0,), '', [''], ('',), None, [None], (None,)]:
        print '%s\t->' % repr(param), cur.mogrify('%s', [param])

if __name__ == '__main__':
    main()
$ python test2.py
0       -> 0
[0]     -> ARRAY[0]
(0,)    -> (0)
''      -> E''
['']    -> ARRAY[E'']
('',)   -> (E'')
None    -> NULL
[None]  -> ARRAY[NULL]
(None,) -> (NULL)

ということを、実は 2 年くらい前に RHEL5 + psycopg2-2.0.12 (from rpmforge)という組み合わせでやっていたのだが、最近になって検索すると次が出てきた。

本件は psycopg2-2.4 で直っている模様。しかし私が試した限り、この変更部分を 2.0 系に持ってきても動かない。None に対してアダプターを登録しても、全く動く気配がない。None に対するアダプターが動くようになる変更が 2.4 までの何処かに入ったのかも知れないが、私的にはもう上述の方法で解決しているのでこれ以上は調べる気なし。

2012-10-31

Animes in the 3rd quarter of 2012

アニメは IT エンジニアの必須科目です。 ということで簡単なレビューを。

前期は面白く無かったのに、第二期が始まってしまった。何とか面白いこと言おうと一生懸命なのは伝わってくるが、殆ど空回るので見てて痛々しい。ただ、黄・紫・メガネの掛け合いは良かった。ていうか「コミック百合姫」とかあるんですか? つくづく日本人って凄いと思う。確かに女子しか出てこないし、タイトルの意味もよく分かった。

最初はどうなることかと思ったが、我慢して見てたら後半は普通に見れた。キャラ付けもできてると思うし、意外なことに AKB が当てている声も慣れればそれっぽく聞こえた(一部を除く)。ただ、それなら襲名メンバーにプロ声優を当てたのが中途半端だと思う。突っ込み所を数えれば切りが無いが、結果としてこれはこれでアリだった気がする。

最初の一人目、幼馴染とはいえ、さっきまでの敵同士が手のひら返して「オレたち親友」とか言ってる所からもうダメだった。その後も仲良しごっこ、恋愛ごっこ、主人公のコンプレックス丸出し言動など、色々とイタいところが多すぎる。せっかく世界観はなかなか良いと思うのに、脚本で全てが台無しになるという良い例だった。

主人公がイライラするのは前作と同様。個人的にはエレナがツボったが、エウレカスイッチでヒステリーになるのが残念。前作もそうだったが、このシリーズはヒステリー持ちが多くて楽しくない。全体的な点としては、エウレカの存在感が大きすぎて今作キャラがすっかり霞んでしまった感がある。寧ろエウレカは出さない方が良かったのでは。

前回はイマイチだったが、今回も同様。ロボットものなのに途中からロボットに乗るの放棄するし、いったい何処に向かっているのか。敵味方が行使する力の理屈も世界観もさっぱり伝わってこないので、楽しむものがキャラくらいしか無い。しかしキャラの魅力も今ひとつなので詰んでる。絵は綺麗なだけに、色々と勿体ない作品だった。

基本、一話毎に新キャラが出るので、キャラを覚えられない。これは構成のミスだと思う。数あるキャラでは、秀吉がお気に入り。米を食って幸せ一杯の「ウマー」にやられた。声が名塚佳織というのも意外で良かった。少年サンデーでも短期連載があったが、両者の中身は全くの別物。笑えるという意味では漫画の方が勢いがあって良かった。

前作に引き続き、話がさっぱり分からない。もうこれは「要、予習・復習」とかいうレベルではなく、これがカッコイイと勘違いしているのでは。せめて重要そうな「歴史再現」の説明はもっと kwsk。訳の分からなさは徹底しているので、後はキャラを楽しむだけ。もう少しビギナーへの配慮が欲しかった。普通は Wikipedia とか読まないからね。

サンライズにしては絵がチャチく感じる。チラ見した限りは原作の方が綺麗に見える。中身は典型的なドタバタ劇で、花澤香菜(ヒロインの中の人)の頑張りが伝わってくる。が、それでも枠の中に収まっている感が否めない。他作品と比べるのは良くないが、同じサンライズとして銀魂・SKET DANCE くらいを期待してしまうのは酷だろうか。

主人公は苦もなく強力な力を手に入れる -> 強いのでモテる、というご都合ハーレム展開。一応、神々との戦いでは何か理屈が働いてるっぽいのだが、神話マニアじゃないから良く分からん。取り巻きに好みさえ居れば、まあ見れる。私は青い人(喜多村英梨)が真ん中だったので無問題だった。もし続きがあれば、青い人目当てで見ると思う。

武将を女子化するのはもういい加減に食傷ぎみだが、絵は好みの部類。しかしヒロインが大してイケてない主人公にデレるとか、ぜんぜん信長っぽくない。史実の改変を許容しているので、話もどうしてもご都合展開になってしまう。加えて主人公は典型的な「気持ち」だけの人で努力の描写が欠如している。残念だが私には楽しむのは無理だった。

視聴前の印象よりは良かったが、その後の期待には及ばなかった感じ。個人的には第二話がピーク。合唱がテーマの割には合唱シーンが少ない。その合唱も全員が同じパートを歌うのではなく、少なくとも(キーが異なるのだから)男女でパートを分けた歌をもっと聞きたかった。と細かい不満を言いたくなるくらい、個人的には惜しい作品。

果たして「超訳」は言い過ぎだったと思うが、まあ確かに今風のノリとツッコミでアレンジされている。ワクワクする面白さは無いが、退屈することもない。逆に、百人一首に思い入れがあると受け付けないかも知れない。ところで毎度こういうのを見るにつけ、つくづく人間って千年経っても 1 ミリも進歩してないんだなあと実感する。

原作はどうもに読む気にならないが、アニメ版は素直に面白かった。テンポが良いのと、何より白石涼子(姫子)の力が大きい。何でこの人はこんなにも方言キャラにハマるのだろうか。もし別の声優が当たっていたら、今よりずっとつまらなかったと思う。後釜は「銀魂」とのことで、銀魂 -> SKET DANCE の無限ループが見えた気がする。

アサルトライフルを女子化とか誰が考えた。挙句に「T バック」とか「撃鉄落ちちゃう」とか、バカじゃねーの? もう、同じ日本人として誇りに思うよ:-D。メインキャラには萌えなかった(高等部の方が良かった)が、その他でお腹一杯になったので良し。ライフルへの愛が伝わってくる作品ではあるが、一般人にはなかなか勧められない作品。

前期は未見、原作は既読。そのせいかも知れないが、これはアニメ化する意味があったのだろうか。本作の魅力は女子キャラと発酵のうんちくだと思っているが、アニメになったせいで後者が著しく損なわれてしまった。かといって前者が立っているかというと、何か声優がミスマッチのような気がするし。まあ原作の復習としては丁度良い感じ。

少女マンガ原作だが、結果はイマイチ。まず個人的な好みの問題として、ヒロインに萌えなかったのが大きい。そして中盤から主人公が精神世界に行きっぱなしになり、ずっと支離滅裂な世界を見せられた後、現実に戻ったらハッピーエンドを通り越してお葬式。って感情移入する暇が全く無いんだけど。原作もこうなの? ただ ED は良かった。

やっぱり「ガンダム」の冠は重いよね、という予想通りの結果。AGE の意味が分かったときには新鮮な驚きはあったが、親子三代はやり過ぎだろう。作風から低年齢が主なターゲットに見えるが、ガンダムファンはみんな高年齢なので評価されるのは難しいと思う。とはいえ SEED の例もあるし、そのうち当たりもあるだろうと次に期待。

前作に続き視聴。キャラは倍に増えたが、話はますます暗くなった。どいつもこいつもコンプレックスの固まりで、見てるこっちが陰鬱になってしまう。パズルの楽しさは何処にいった。あと、やっぱり個人的に萌えるキャラが居ない。エレナは相変わらず出番が少ないし。何を思ったか更に 3 期に続くようだが、このままでは期待できる要素が無い。

ジャンプのスポーツ漫画らしく、必殺技がデフォルト。まだ本作は人間の範疇に見えなくもないので我慢できるが、そのうち影分身とかするようにならないか心配。必殺技に目をつむって人間関係だけを見れば、普通に面白いと思う。個人的には、もっと(本作にも無い訳ではないが)正しい努力の積み重ねが結果に結びつくという描写が欲しい。

思わず見とれてしまう程の、絵の美しさ。これだけでも見る価値はある。話の方はグッとくる面白さは無いが、地味に面白い。絵のせいもあり独特な雰囲気があるので、深夜にしんみり雰囲気に浸って見るのがお勧め。個人的には色々と納得いかない推理も多かったが、それはきっと私がバカだからだろう。あと、1st OP は良かった。

OP や初話のノリで期待して見ると、実は結構な重い話に裏切られる。各キャラが個々のイベントにマジレスし過ぎ。そりゃ本当に人格が入れ替わったら大変だよ。心を壊す輩も出てくるさ。しかしその葛藤をアニメにする意味が分からん。ハッピーエンドになるのは分かってるが、道中もハッピーにして欲しかった。キャラが魅力的なだけに残念。

しかしこう書き連ねてみると、いい加減にアニメ見過ぎだな。もう少し絞らないと時間がいくらあっても足りない。しかしアタリかハズレかなんて見ないと分からないしなあ。