kenkovlog

Haskell, Python, Vim, ...

Python のライセンスと標準ライブラリ、サードパーティライブラリのimport について

Python のモジュールを公開するにあたって気になったことが あったので、ライセンスについて調べてみました。

まずは基本

そもそもPython のライセンスは PSF License (Python Software Foundation License) です。 これはBSD スタイルのGPL 互換のライセンス となっています。 BSD ライセンスとの主な違いは、「被許諾者はPython 2.7.3に加えた変更の要約を当該成果物に含めること」でしょうか。 バージョン番号は古いですが 翻訳 もあるので、参考にしてください。

標準ライブラリについても 一部を除いてPSF License となっているようです。

標準ライブラリをimport する

僕が疑問に思ったのは次のようなことです。
例えば、次のようなモジュールを作成した時、

#! /usr/bin/env python
# coding:utf-8
import datetime
def now():
    return datetime.datetime.now()

ライセンス条文にある

PSFのライセンス契約、およびPSFの著作権表示、「Copyright (c) 2001 Python Software Foundation; All Rights Reserved」を記載する

必要があるかどうか分かりませんでした。
これについては、詳しくPSF ライセンスの条文を見てみると

2. 本ライセンス契約に定める諸条件に従って、PSFは被許諾者に対し、
単体もしくは派生バージョンのPython 2.1.1を複製、解析、テスト、
公然と実行および/または表示、派生成果物の作成、頒布、その他の方法で使用する非独占的な、
権利使用料無料の、世界規模のライセンスを付与します。
ただし、単体または被許諾者が作成する派生バージョンのPython 2.1.1に、PSFのライセンス契約、
およびPSFの著作権表示、すなわち「Copyright (c) 2001 Python Software Foundation; All Rights Reserved」
を記載することを条件とします。

と書いてあります。 この

ただし、単体または被許諾者が作成する派生バージョンのPython 2.1.1に、

というところがポイントで、「単体または...派生バージョンの...」と書いてあります。
import しただけではPython 単体を使用しているわけではないので、派生バージョンかどうかを考えれば よいことになります。 派生バージョンのソフトウェアと考えられるものとしては

があり、 派生ソフトウェアと見なさない行為として

  • 単なる同梱
  • API を介した呼出
  • OSS による作業

があるということです。 (詳しくは 知る、読む、使う! オープンソースライセンス を参照のこと)
このことから、標準ライブラリをインポートして使うだけであればこれは単なるAPI 呼びだし(コンパイルしていないので静的、動的リンクはしない) なので

PSFのライセンス契約、およびPSFの著作権表示、すなわち「Copyright (c) 2001 Python Software Foundation; All Rights Reserved」を記載する

必要はないと考えられます。

僕ははじめ、import すると派生バージョンになるのかと思っていたのがそもそもの勘違いの元でした。

サードパーティライブラリをインポートする

サードパーティライブラリをインポートするようなモジュールを作成する時はどうでしょうか? 例えばMIT ライセンスのサードパーティライブラリをインポートする時を考えてみましょう。 ただし、サードパーティライブラリはインポートするのみで、同梱したりはせず、インストールするように README などに書いておくものとします。
MIT ライセンスの条文を読んでみると

以下に定める条件に従い、本ソフトウェアおよび関連文書のファイル(以下「ソフトウェア」)の複製を取得するすべての人に対し、
ソフトウェアを無制限に扱うことを無償で許可します。これには、ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、
サブライセンス、および/または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます。

上記の著作権表示および本許諾表示を、ソフトウェアのすべての複製または重要な部分に記載するものとします。

と書いてあります。関連する箇所は

ソフトウェアの複製を使用、複写、変更、結合、掲載、頒布、
サブライセンス、および/または販売する権利、およびソフトウェアを提供する相手に同じことを許可する権利も無制限に含まれます。

ですね。
さて、ライブラリをインポートしただけでは上記のものにはあてはまらないと考えられます。 (掲載があやしいですが、英語ではpublish であり、おそらくソースコードの掲載、公開などを意味するのでしょう)

また、BSD ライセンス の場合も同様に 必要ないと考えられます。

ただ、MIT ライセンスとBSD ライセンスのライブラリをimport している実際のモジュールを見てみると、NOTICE ファイルに著作権表示と承諾許諾表示を書いているものが多いですね; 書いた方がよいのでしょうか?

GPL ライセンスの場合も同様にして、(この場合は)コピーレフトは適用されないと考えられます。 例えば、GPL ライセンスのサードパーティライブラリをimport のみ(同梱はしない)してMIT ライセンスのモジュールを作成することが可能です。 しかし、リンクしてバイナリコードに変換したり、サードパーティライブラリを同梱して頒布したりする場合には全体をGPL に適用しなくてはいけません。 つまりこの場合は

サードパーティライブラリ: GPL
自分のモジュール:         MIT
-------------------------------
まとめて頒布: GPL

という形になるでしょう。

py2exe を使うとき

py2exe を使うときは、実行可能なバイナリコードを作成するので、上記に述べたライセンスの話はあてはまりません。 なぜなら、import したライブラリのバイナリコードが複製されて頒布されるからです。 この場合は各ライセンス条項をしっかりと読んで対応しましょう。 (例えばGPL のライブラリを使用したらコピーレフトになるなど。)

まとめ

そもそもimport すると派生ソフトウェアになるのか? という疑問から今回ライセンスについて調べました。 結論からいうと、import しただけでは派生ソフトウェアにならず著作権表示やライセンス許諾表示を記載する必要 はないようです。(コピーレフトも同様)
もっと簡単に言えば、import したライブラリのソースコード(もしくはコンパイル済みであればバイナリコード) を少しでも含むか含まないかで判断したらよさそうです。もちろん、正確には条文を読まなければなりませんが;
import したソースコードを同梱(再頒布) したりpy2exe でバイナリコードに変換したりした場合には 再頒布となるため、 その限りではなく、各ライセンス条文を読んで理解する必要があります。

Arch Linux でMTP の設定

Galaxy Nexus を接続する時などに使う。

mtp のインストール

$ sudo pacman -S libmtp mtpfs

インストールした時に出てきた表示にしたがい、次を行う。

$ sudo modprobe fuse

あと、fuse を/etc/rc.conf のMODULES に追加する。

...
MODULES=(... fuse ...)
...

次にfuse の設定を行う。/etc/fuse.conf のuser_allow_other のコメントを外す。

# 次のコメントアウトをはずす
user_allow_other

次に、udev の設定をする。/etc/udev/rules.d/ 以下に次のような
51-android.rules というファイルを作成する。

UBSYSTEM="usb", ATTR{idVendor}=="0502", MODE="0666"

フロントエンド

フロントエンドとしてgmtp を使う。AUR からインストールする。

$ yaourt -S gmtp

今回フロントエンドとしてgmtp を使用しているのは、
コマンドラインからmtpfs を

$ sudo mptfs -o allow_other /path/to/mount/point

のように使用すると、はじめ接続できていますがしばらくすると

通信端点が接続されていません。

となってうまくいかなかったからです。

使用方法

コマンドラインから

$ sudo gmtp

さくらVPS にArch Linux をインストールする。

さくらVPS にArch Linux をインストールしました。
インストール方法については既出の記事 があり、これはarchboot というものを使用してインストールしています。
今回僕は、Arch Linux 公式のインストーラ(archlinux-2011.08.19-core-dual.iso)を使用してArch Linux をインストールしました。
というのも、archboot の利用に関して、ArchWiki にも書いてある通り

Those files are no official Arch Linux releases.
Use them on your own risk.

ということなので、公式のインストーラを使用したかったためです。

インストール方針

ArchWikiのBooting an ISO Directly From Grub2 のページを参考に、Grub2 からISO(インストーラ) を起動してインストールします。

具体的には次のステップでインストールします。

  • Debian をインストールする。(さくらVPS にはカスタムインストールでインストールできる)
  • Grub2 の設定を変更してISO から起動できるようにする。
  • ISO からArch Linux をインストールする。

Debian をインストールするのは、

  • Grub2 をインストール直後から使用できる
  • ディスク全体を使用せずにインストールする(手動パーティッション)

ためです。
後からArch Linux をインストールするので、ディスク全体を使用せずにインストールする必要があります。

Debian インストール

というわけで、まずDebian をインストールします。
インストールはパーティッションの設定を除いて通常通りです。

パーティッションは、後でArch Linux をインストールすることを考えて設定します。
今回僕は

sda1    Primary 200MB   /boot
sda5    Logical 3GB     /
sda6    Logical 1GB     swap

にしました。
僕の場合、全体で20GB あります。今回Debian インストールに使用したパーティッションは後でArch Linux の/home にしようと思います。

さて、インストールが完了したら次にGrub2 の設定をします。
まずインストーラのISO ファイルを取得します。

# mkdir /archives
# cd /archives
# wget http://ftp.jaist.ac.jp/pub/Linux/ArchLinux/iso/2011.08.19/archlinux-2011.08.19-core-dual.iso

Grub2 の設定はArchWiki に従います。
/etc/grub.d/40_custon に

menuentry "Archlinux-2011.08.19-netinstall-x86_64.iso" {
set isofile="/archives/archlinux-2011.08.19-netinstall-x86_64.iso"
loopback loop (hd0,7)$isofile
linux (loop)/arch/boot/x86_64/vmlinuz archisolabel=ARCH_201108 img_dev=/dev/sda7 img_loop=$isofile earlymodules=loop
initrd (loop)/arch/boot/x86_64/archiso.img
}

を追加します。

あとはGrub2 をアップデートします。

# grub-mkconfig -o /boot/grub/grub.cfg

これで設定終了です。reboot します。

Arch Linux インストール

うまく設定出来ていると、Grub のメニュー画面ArchLinux を選択すればインスーラが起動するはずです。
インストーラが起動したら設定を開始します。
まず、パーティッションの設定をします。

# cfdisk

ここで、ArchLinux のパーティッションを設定します。先程のDebian のパーティッションは現在使用しているので削除できません。
ですので、Debian のパーティッションを削除せずに、新しくパーティッションを追加します。
僕は

sda3    Primary 100MB   /boot
sda7    Logical 10GB    /
sda8    Logical 1GB     swap

にしました。
全体としては
f:id:kenkov:20120318031034p:image
という風になりました。
さて、ここで一度reboot します。そうしないと、インストール中のmountpoint の設定で現在のパーティッションの設定が反映されません。

reboot したら、通常通りインストールを進めればok です。

インストール時の注意点としては、

  • rc.conf でネットワーク(固定ip など) の設定
  • resolv.conf の設定

をしなければなりません。

あと、インストールが終了したらすぐにreboot してはならず、さくらVPS の注意 にあるように
/etc/inittab に

co:2345:respawn:/sbin/agetty -h 115200 ttyS0 vt100

/boot/grub/menu.lst に

serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1
terminal --timeout=10 serial console

を、kernel の行に

kernel 〜〜〜 console=tty0 console=ttyS0,115200n8r

を追加しなければなりません。この設定をしないとリモートコンソールを使用できなくなります。(つまり詰む。)

なお、リモートコンソールが使えなくなった時の対策にssh をインストールしておくといいかもしれません。
ssh をインストールするには、インストールパッケージの選択でopenssh を選択して、/mnt/etc/ssh/ 以下のssh の設定をいじればよいです。(インストールした時にマウントしたパーティッションは/mnt/ 以下にマウントされています。)

さて、ここまで出来たらreboot します。

うまくいっているように願います………

Arch Linux の設定

うまく設定出来ていればArch Linux が起動するはずです。

さて、Debian で使用していたパーティッションをcfdisk で削除します。今の状態ですと、sda1、sda5、sda6 を削除します。

注意点としては、Logical パーティッションを削除すると番号がずれる可能性があることです。番号がずれた場合には、/etc/fstab、/boot/grub/menu.list をそれにあわせて変更する必要があります。
今回ですと、

  • sda7 -> sda5
  • sda8 -> sda6

という風に変わるので、この通りにfstab とmenu.list を編集します。
(はじめからこのことを考えてパーティッションを変更していればよかったですね…;;;)

さて、必要なくなった場所に/home を作成します。今の場合だとsda1 というPrimary パーティッションをcfdisk で作成して

# mkfs -t ext4 /dev/sda1

でファイルシステムを作成します。そして、/etc/fstab に追加します。

最終的なパーティッションは

sda1            Primary ext4    10272.01
sda5            Logical ext4    10001.95
sda6            Logical swap    1003.49
sda3    Boot    Primary ext3    197.41

となりました。

終り

以上で終わりです。
素敵なArch 生活を送れますね!

Arch Linux でのパッケージのインストールについて

新しくArch Linux をインストールした時に、以前使っていたパッケージ達を
そのままインストールしたい場合が多いかと思います。
その時に使えるコマンドについてです。

pacman でインストールされているパッケージを表示するには

$ pacman -Q

を用います。
ただし、このコマンドだけではsync したデータベースからインストールしたパッケージの他に、AUR などからインストールしたパッケージも表示されてしまいます。

AUR など、sync したデータベース以外からインストールしたパッケージを表示するには

$ pacman -Qm

を使います。

また、これら二つの差分を表示するには

$ pacman -Qq > allPackages
$ pacman -Qmq > notInSync
$ diff allPackages notInSync  | grep '^<' | cut -c 3- > syncOnly

上のコマンドの最後の行を行えばよいです。
ここでは、バージョンなどの情報を表示しないため、-q オプションを付けました。

pacman に上のdiff をとるコマンドと同等のオプションがあるかもしれませんが、
調べても分かりませんでしたので、今回はdiff を使いました。

さて、これが出来たらsync したデータベースからインストールするには

$ sudo pacman -S `cat syncOnly` --needed --noconfirm

を行えばよいです。

Arch Linux でautofs の設定

autofs を使用すると、メディアを必要な時(アクセスした時)に自動的にマウントできるようになります。
利点としては、

  • 手動でマウントする必要がなくなる
  • fstab で設定すると不必要なものまで全てマウントしてしまうので動作が重くなることがあるが、autofs を使えば、必要になった時にマウントできる。

などがあげられます。
頻繁にアクセスするようなメディアでなければ、autofs の設定をするとよいかもしれません。

設定について

ここではbackup に使うHD をautofs によりオートマウントする設定をすることにします。事前にfdisk やGParted などでHD を(ext4 などに)フォーマットしておきます。

まず、デバイスについて確認します。

$ sudo fdisk -l
デバイス ブート      始点        終点     ブロック   Id  システム
/dev/sdb1            2048   976773119   488385536   83  Linux

次にautofs をインストールしましょう。

$ sudo pacman -S autofs

autofs の設定ファイルは

  • /etc/autofs/

以下にあります。

今回は、このHD を/media 以下にbackup という名前でマウントすることにします。

まず、/etc/autofs/autofs.master の設定をします。

$ cat /etc/autofs/autofs.master
/media /etc/autofs/auto.backup --ghost

これは、/media というベースディレクトリに対して/etc/autofs/auto.backup に設定した通りにメディアをマウントするという意味です。
このように、autofs ではまずautofs.master でマウントするベースディレクトリを設定しておき、次に設定ファイル(ここではauto.backup) を読み込むことでマウントするメディアを設定します。

/etc/autofs/auto.backup を見てみましょう。

backup -fstype=ext4,rw  :/dev/sdb1

これは、/dev/sdb1 をfiletype がext4 でread-write でbackup という名前でマウントするという設定です。ベースディレクトリが/media なので、このメディアは/media/backup としてマウントされます。

注意点としては、あらかじめ作成しておかなければいけないディレクトリは/media のみです。/media/backup は自動で作成されるので、自分で作成しておく必要はありません。

これで準備ができたので、autofs を起動しましょう。

$ sudo /etc/rc.d/autofs start

実際に自動でマウントされることを確認しましょう。

$ cd /media/backup

今後起動時にautofs を自動起動するには、/etc/rc.conf のDAEMONS にautofs を、MODULES にautofs4 を設定してください。

これで一通りの設定が終わりました。

さて、autofs.master の設定に戻ってみましょう。

$ cat /etc/autofs/autofs.master
/media /etc/autofs/auto.backup --ghost

この行に--ghost というオプションが加わっています。これは、実際にはマウントされていない状態でも/media/backup というディレクトリを表示する設定です。実際にマウントされていない状態でも、どのような名前でマウントしているか分かりやすいようにこのオプションを設定しています。

ここでは、autofs の設定の一連の流れをみましたが、より詳しい情報は

などを確認してみてください。

Arch Linux でのtexlive のフォントエラー

Arch Linux でtexlive をアップグレードしたら、dvipdfmx した時にフォントエラーが出るようになったので、その対処法を。

texlive のバージョンはこちらです。

$ pacman -Qi texlive-langcjk

Name           : texlive-langcjk
Version        : 2011.24689-1
URL            : http://tug.org/texlive/
Licenses       : GPL
Groups         : texlive-lang
Provides       : None
Depends On     : texlive-core
Optional Deps  : None
Required By    : None
Conflicts With : None
Replaces       : None
Installed Size : 254099.00 KiB
Packager       : R&#233;my Oudompheng <[email protected]>
Architecture   : any
Build Date     : 2011年12月04日 18時05分59秒
Install Date   : 2012年02月25日 16時24分05秒
Install Reason : Explicitly installed
Install Script : Yes
Description    : TeX Live - CJK (Chinese, Japanese, Korean) macros and fonts

texlive-langcjk インストール直後に、日本語ファイル

\documentclass{jarticle}
\begin{document}
こんにちは
\end{document}

をコンパイルすると

$ platex test.tex
This is e-pTeX, Version 3.1415926-p3.2-110825-2.3 (utf8.euc) (TeX Live 2012/dev/Arch Linux)
 restricted \write18 enabled.
entering extended mode
(./test.tex
pLaTeX2e <2006/11/10> (based on LaTeX2e <2011/06/27> patch level 0)
Babel <v3.8m> and hyphenation patterns for english, dumylang, nohyphenation, af
rikaans, arabic, basque, bulgarian, catalan, pinyin, croatian, czech, danish, d
utch, ukenglish, usenglishmax, esperanto, estonian, farsi, finnish, french, gal
ician, german, ngerman, swissgerman, hungarian, icelandic, indonesian, interlin
gua, irish, italian, kurmanji, latin, latvian, lithuanian, mongolian, mongolian
lmc, bokmal, nynorsk, polish, portuguese, romanian, russian, serbian, serbianc,
 slovak, slovenian, spanish, swedish, turkish, turkmen, ukrainian, uppersorbian
, welsh, ancientgreek, ibycus, monogreek, greek, coptic, loaded.
(/usr/share/texmf-dist/tex/platex/base/jarticle.cls
Document Class: jarticle 2006/06/27 v1.6 Standard pLaTeX class
(/usr/share/texmf-dist/tex/platex/base/jsize10.clo)) (./test.aux) [1]
(./test.aux) )
Output written on test.dvi (1 page, 272 bytes).
Transcript written on test.log.
$ dvipdfmx
test.dvi -> test.pdf
[1
kpathsea: Running mktexpk --mfmode / --bdpi 600 --mag 0+577/600 --dpi 577 rml
mktexpk: don't know how to create bitmap font for rml.
mktexpk: perhaps rml is missing from the map file.
kpathsea: Appending font creation commands to missfont.log.

** WARNING ** Could not locate a virtual/physical font for TFM "rml".
** WARNING ** >> There are no valid font mapping entry for this font.
** WARNING ** >> Font file name "rml" was assumed but failed to locate that font.
** ERROR ** Cannot proceed without .vf or "physical" font for PDF output...

Output file removed.

とdvipdfmx するとエラーが出てしまいます。
これは、エラー出力の通りフォントを読みこめていないのが原因です。

対処法は、/etc/texmf/dvipdfmx/dvipdfmx.cfg の設定を以下のように変更します。

%% Put additonal fontmap files here (usually for Type0 fonts)
% 次の行のコメントアウトを外す
f  cid-x.map

Haskell も文字列と文字コードについて

Haskell の文字列と文字コードについて。

例えば日本語文字列をprint で表示してみると、

Prelude> print "こ"
"\12371"

と表示されます。
これは、 Unicode のコードポイント と呼ばれるものが表示されています。

次に、文字列をCodec.Binary.UTF8.String.encodeString を使ってUTF8 文字列に直してから表示してみると

Prelude> :m + Codec.Binary.UTF8.String
Prelude Codec.Binary.UTF8.String> print $ encodeString "こ"
"\227\129\147"

と表示されます。
これは、 "こ"のコードポイントに対応するUTF8 エンコーディング が表示されています。

Haskell のコード内で文字列をUTF8 エンコードする処理が必要な場合には、Codec.Binary.UTF8.String モジュールを使うとよいでしょう。
このモジュールを使うためにはcabal で utf8-string をインストールしましょう。

$ cabal install utf8-string

また、

Prelude> putStrLn "こんにちは"
"こんにちは"

といったように、putStrLn を使って表示をした場合や、ファイル入出力を
行う際には、(最新のHaskell Platform を使用しているならば)System.IO が
自動的にHaskell の内部文字列とUTF8 文字列の変換をしてくれるようです。

に詳しく書かれているので参照してください。