やんごとなき事情によりxrea内でWEBサーバを移動しました。

というわけで、このブログ(web.pyによる自作ブログ)を移したわけですが、今までのようにバイナリ化して動かすにはサーバと似た環境が手元にないといけません。が、移動した先のサーバでは環境がだめ。

ということで、python2.5をxreaにインストールしました。virtual-pythonもいいんですが、xreaのサーバはpython2.4なので。ちょっと工夫すれば入るし、快適ですね。以下作業ログ。

Pythonをインストール

まずはPythonのソースをダウンロードしてコンパイル。 ~/root/usr/local にいれます。

mkdir -p ~/root/usr/local/src
cd ~/root/usr/local/src
wget http://www.python.org/ftp/python/2.5.4/Python-2.5.4.tgz
tar zxvf Python-2.5.4.tgz
cd Python-2.5.4
./configure --prefix=~/root/usr/local
make
make install

サクっと入ります。で、次にeasy_installを入れるわけですが、はいりません。OpenSSLとの絡みで hashlib.md5 が使えないから。 easy_install を入れるときに md5 を検証するのに使ってるんですよね。

hashlibをインストール

なんで、自前でhashlibを単体でいれます。

cd ~/root/usr/local/src
wget http://code.krypto.org/python/hashlib/hashlib-20081119.tar.gz
tar zxvf hashlib-20081119.tar.gz
cd hashlib-20081119
vi setup.py

はい、 setup.py を編集しましょう。普通にbuildするとこれでも md5 が入りません。

105   if (ssl_inc_dir and
106     ssl_lib is not None and
107     openssl_ver >= 0x00907000):
108
109     print 'Using OpenSSL version 0x%08x from' % openssl_ver
110     print ' Headers:\t', ssl_inc_dir
111     print ' Library:\t', ssl_lib
112
113     # The _hashlib module wraps optimized implementations
114     # of hash functions from the OpenSSL library.
115     exts.append( Extension('_hashlib', ['_hashopenssl.c'],
116                include_dirs = [ ssl_inc_dir ],
117                library_dirs = [ os.path.dirname(ssl_lib) ],
118                libraries = osNameLibsMap[os.name]) )
119   exts.append( Extension('_sha', ['shamodule.c']) )         
120   exts.append( Extension('_md5',                  
121           sources = ['md5module.c', 'md5.c'],
122           depends = ['md5.h']) )

119-120あたり、強制的に _md5 を入れるようにします。あとは

~/root/usr/local/bin/python setup.py build
~/root/usr/local/bin/python setup.py install

hashlib が入ります。

easy_installをインストール

これで md5 が使えるようになったので

cd ~/root/usr/local/src
wget http://peak.telecommunity.com/dist/ez_setup.py
~/root/usr/local/bin/python ez_setup.py

これで無事 easy_install が入ります。あとは

~/root/usr/local/bin/easy_install -U -Z MySQL_Python

てな感じで必要なモジュールを入れていきましょう。

というわけで

わりと普通にxreaでPythonが使えています。


なんか、趣味では最近はC言語ばっかりだったりするわけですが。

さて、関数型言語系をカジった人なら誰しも取り付かれる、モノ、それがパターンマッチ。パターンマッチが使えると、とにかく直感的にコードをかけますよね。

つーわけで、Pythonでパターンマッチを実装してみました。機能的には

  • リスト,タプルに対するパターンマッチ
  • パターン変数への束縛
  • ガード条件
  • 任意のオブジェクトに対するパターンマッチ
  • 部分パターンの束縛(Ocamlのas)

あたりを実装してみました。これだけあれば、かなり便利にコードをかけます。できるだけ、手軽に書けるように工夫してみました。こんな感じです。

変数束縛とガード。 getattr でごにょごにょしてるので簡単にかけます。

m = Match([1,2,3]) 
if m.when([1,2,m.var]) and m.var > 2:
  print m.var
# >> 3

こう使えば、Pythonに念願のswitchが!

m = Match(10)
if m(9):
  print 1
elif m(10):
  print 2
else:
  False
# >> 2

部分パターンを束縛してみます。 [1,2,m.var] 全体を all というパターン変数に束縛します。

m = Match([1,2,3]) 
if m.when([1,2,m.var]) and m.var > 5:
  False
elif m.when(m._as_all([1,2,m.var])):
  print m.all
  print m.var
else:
  raise StandardError("")
# >> [1, 2, 3]
# >> 3

任意のオブジェクトにも使えます。いわゆるレコードに対するマッチも簡単にできるということです。

class Test(object):
  def __init__(self, v1, v2):
    self.v1 = v1
    self.v2 = v2
  def __repr__(self):
    return "Test(%s, %s)"%(repr(self.v1), repr(self.v2))
m = Match([1, Test(2, 3)])
if m.when([1, m._class(Test, {"v1":2, "v2": m.v2})]):
  print m.v2
else:
  False
# >> 3

オブジェクトに対するパターンマッチは __match__ メソッドを定義するとカスタマイズできます。ここらのアイデアはScalaからいただきました。

class Test2(Test):
  def __match__(self):
    return {"value": self.v1 + self.v2}
m = Match([1, 2, Test2(3,4)])
if m.when([1,2, m._class(Test2, {"value": m.var})]):
  m.var
else:
  False
# >> 7

結構いい感じな気がします。

ダウンロード

patternmatch.py

実装のお話

ソースコードはこんな感じ。

class Match(object):
  class _var(str): pass
  class _class(object):
    def __init__(self, klass, attrs):
      self.klass= klass
      self.attrs= sorted(attrs.iteritems())
    def match(self, m, obj):
      props = getattr(obj, "__match__", lambda: obj.__dict__)()
      return issubclass(obj.__class__, self.klass) and \
            m.when(self.attrs, sorted(props.iteritems()))
  class _as(object):
    def __init__(self, name, pattern = None):
      self.name = name
      self.pattern = pattern
    def __call__(self, pattern):
      self.pattern = pattern
      return self

  def __init__(self, obj):
    self.obj = obj
    self.bind = {}

  def __getitem__(self, key):
    if not self.bind.has_key(key):
      if key.startswith("_as_"):
        return self._as(self._var(key[4:]))
      return self._var(key)
    return self.bind[key]
  __getattr__ = __getitem__
  __call__ = lambda self, *a, **k : self.when(*a, **k)

  def when(self, pattern, obj = None):
    if not obj: obj = self.obj
    if isinstance(pattern, (self._var, self._class, self._as)):
      if isinstance(obj, (list, tuple)):
        pattern = [pattern]
        obj     = [obj]

    if not isinstance(obj, (list, tuple)) and \
      not isinstance(pattern, (list, tuple)) :
      obj = [obj]
      pattern = [pattern]

    if not isinstance(obj, (list, tuple)) or  \
      not isinstance(pattern, (list, tuple)) :
      self.bind = {}
      return False

    if len(obj) != len(pattern):
      if not ((pattern[-1].__class__ == self._var) and pattern[-1].startswith("__")):
        self.bind = {}
        return False

    for i, (value, pat) in enumerate(zip(obj, pattern)):
      if value == pat:
        continue
      elif pat.__class__ == self._var and pat.startswith("__"): 
        self.bind[str(pat)] = obj[i:]
        return True
      elif pat.__class__ == self._var:
        self.bind[str(pat)] = value
      elif pat.__class__ == self._class:
        if not pat.match(self, value):
          self.bind ={}
          return False
      elif pat.__class__ == self._as:
        if not self.when(pat.pattern, value):
          self.bind ={}
          return False
        self.bind[str(pat.name)] = value
      elif isinstance(value, (list, tuple)) and isinstance(pat, (list,tuple)):
        if not self.when(pat, value):
          self.bind = {}
          return False
      else:
        self.bind = {}
        return False

    return True

まぁわりかしシンプルですね。

 

  今年も終わりが近づいてまいりました。年をとると時間がすぎるのが速いナァ・・・と痛感しております。


Python2.6きましたね。ということで、自分用にも主な変更点メモ。なぐり書きなのでミス多いかも。個人的な注目部分は

  • with文
  • multiprocessing
  • itertoolsへのメソッド追加
  • ABCの導入
  • クラスデコレータの導入
  • ネットワーク系ライブラリ(http,ftp,telnet..etc)でタイムアウトが設定できるようになった。

あたりですかね。ではどうぞ。

Python 3.0由来の変更点

  • 複素数へオブジェクトを変換する __complex__ メソッド。
  • 例外補足のためのもう一つ書き方: except TypeError as exc
  • build-inの reduce() に加え、 functools.reduce の追加。(3.0では reduce はfunctools経由でしか使えない)

3.0では他にもbuild-in関数に変更がある。3.0互換のコードを書きたいなら必要に応じて from future_builtins import hex,map のようにimportすること。

また、 -3 コマンドラインスイッチにより 3.0 で削除される機能を使っている場合、警告を出せる。

PEP 343: ‘with’ statement

with open('/etc/passwd', 'r') as f:
    for line in f:
        print line
        ... more processing code ...
  • withに入るとオブジェクトの __enter__() 、抜けるときに __exit__(type, value, traceback) が呼ばれる。例外発生しなかった場合、 type, value,traceback はNone。
  • contextlib を使うと簡単に書ける。

PEP 399: メインモジュールからの明示的相対的import

Pythonでは -m スイッチでモジュールをスクリプトとして動かせる。が、パッケージ内部のモジュールを動かそうとした場合、相対的importが上手く働かない。本修正で、 __package__ 属性がモジュールに追加された。この属性がある場合、 __name__ の代わりにこの値からの相対importを行う。

PEP302スタイルのインポータは __package__ を必要に応じてセットできる。 runpy モジュールの -m スイッチはこれを行っているので、パッケージ内からスクリプトを実行しても相対的importは正しく動く。

PEP 371: multiprocessing module

プロセス間通信を実装したモジュール。並列計算などを実装できる。詳しくは Atsushiさんの記事 参照

PEP3101: さらに高度な文字列フォーマット

3.0では % オペレータはさらに高機能になる。2.6ではこの %str.format メソッドで実装している。

"User ID: {0}".format("root") -> "User ID: root"

'User ID: {uid}   Last seen: {last_login}'.format(
      uid='root',
      last_login = '5 Mar 2008 07:20') ->
  'User ID: root   Last seen: 5 Mar 2008 07:20'

'Platform: {0.platform}\nPython version: {0.version}'.format(sys) ->
    'Platform: darwin\n
    Python version: 2.6a1+ (trunk:61261M, Mar  5 2008, 20:29:41) \n
    [GCC 4.0.1 (Apple Computer, Inc. build 5367)]'

fmt = '{0:15} ${1:>6}'
fmt.format('Registration', 35) ->
  'Registration    $    35'

くわしくは PEP3101 参照。

PEP3105: 関数としての print

3.0で print 文は print 関数になる。2.6では __future__ に定義されている。

from __future__ import print_function
print('# of entries', len(dictionary), file=sys.stderr)

def print(*args, sep=' ', end='\n', file=None)

PEP 3112: Byte リテラル

3.0` では文字列はデフォルトでUnicodeになり、8bitリテラルは別に用意される。 b'string'byte コンストラクタだ。2.6 ではstrとおなじ bytes 型を定義し、 b'' 記法をサポートする。

また、 __future__ で文字列リテラルを全てUnicodeにすることができる。

from __future__ import unicode_literals

s = ('\u751f\u3080\u304e\u3000\u751f\u3054'
    '\u3081\u3000\u751f\u305f\u307e\u3054')

print len(s)               # 12 Unicode characters

PEP 3116: 新しいI/Oライブラリ

Pythonではダックタイピングにより、ファイル-likeオブジェクトは read() , write() が定義されていればよかった。ただ、文字列を扱う場合 readline() が定義されていたほうがよい。このようなケースに応じた基底クラスがPython3.0では io モジュールに用意される。

  • RawIOBase
  • BufferedIOBase
  • TextIOBase

など。

くわしくは PEP 3116 参照。

PEP 3119: Abstract Base Classes

Abstract Base Class(ABC)はJAVAのインターフェースのようなもの。ABCのサポートは ABCMeta というメタクラスを含む abc モジュールで構成される。 ABCMetaisinstanceissubclass のbuilt-in関数で特別に扱われる。

ABCは通常の継承のように

import collections
class Storage(collections.MutableMapping):
  ...

ともABCの register() メソッドをつかって

import collections
class Storage:
    ...
collections.MutableMapping.register(Storage)

ともできる。 register を使えば、組み込み型や他者の書いたクラスを ABC とすることができる。

ABCはJAVAと違い、Pythonが自動でそのインターフェースをチェックしてくれるわけではない。チェックするためには

if not isinstance(d, collections.MutableMapping):
    raise ValueError("Mapping object expected, not %r" % d)

のように書く。

独自のABCは以下のように定義する

from abc import ABCMeta, abstractmethod, abstractproperty

class Drawable():
    __metaclass__ = ABCMeta

    @abstractmethod
    def draw(self, x, y, scale=1.0):
        pass

    @abstractproperty
    def readonly(self):
      return self._x

    def draw_doubled(self, x, y):
        self.draw(x, y, scale=2.0)

これでDrawableから派生したクラスでdrawメソッド、readonlyプロパティが定義されていなければ TypeError が出るようになる。

PEP 3127: 数値リテラル及び文法

3.0では8進数は0開始でなく 0o or 0O 開始になり、2進数リテラル 0b or 0B がサポートされる。2.6では0開始8進数表記も使えるが 0o or 0O 開始も使えるし、 oct() 関数は0開始も文字列を返す。ただし、 future_builtins.oct は0o開始の文字列を返す。また、 int , long 関数は 0o0b 開始文字列も扱えるようになった。

PEP 3129: クラスデコレータ

@foo
@bar
class A:
  pass

class A:
  pass

A = foo(bar(A))

と同義になる。

PEP 3141: 数値の型階層

3.0ではSchemeに習った数値の型階層が導入される。これらの型は numbers モジュールを通して 2.6 にバックポートされた。

  • Number
    • Complex
      • Real : floor()trunc() を定義
        • Rational : numeratordenominator を定義。実装は fractions モジュールで。
          • Integral

また、 math.trunc() も3.0からバックポートされた。fractionはこのように使う。

>>> from fractions import Fraction
>>> a = Fraction(2, 3)
>>> b = Fraction(2, 5)
>>> float(a), float(b)
(0.66666666666666663, 0.40000000000000002)
>>> a+b
Fraction(16, 15)
>>> a/b
Fraction(5, 3)
>>> (2.5) .as_integer_ratio()
(5, 2)
>>> (3.1415) .as_integer_ratio()
(7074029114692207L, 2251799813685248L)
>>> (1./3) .as_integer_ratio()
(6004799503160661L, 18014398509481984L)

その他の言語の変更

  • **kw 引数にPythonの辞書以外の UserDict のようなどんなマッピングでも使えるようになった。
  • next(iterator, [default]) メソッド追加。見ての通りiteratorの次の要素を、なければdefaultを返す。
  • タプルに index()count() が追加された(listと同じ)。
  • 組み込み型のsliceのサポートが向上。
  • プロパティが getter , setter , deleter というデコレータをサポート。
class C(object):
    @property
    def x(self):
        return self._x

    @x.setter
    def x(self, value):
        self._x = value

    @x.deleter
    def x(self):
        del self._x

class D(C):
    @C.x.getter
    def x(self):
        return self._x * 2

    @x.setter
    def x(self, value):
        self._x = value / 2
  • setintersection(), intersection_update(), union(), update(), difference(), difference_update() が引数に複数のiterableを取れるようになった。
  • 浮動小数点に関する様々な改良が追加された。
  • 親クラスから __hash__() を継承したクラスで __hash__ = None とすることでhashableでないことを示せる。
  • Exception のインタフェースが変更。 message 属性がdeprecated。
  • GeneratorExit の親クラスが Exception から BaseException に変更
  • Generatorオブジェクトに gi_code 属性を追加。
  • compile() 関数でキーワード引数が取れるようになった。
  • complex コンストラクタでカッコにかこわれている数値がOKになった。 complex('(3+4j)')
  • string.translate() に変換テーブルとして None を渡せるようになった。 None は恒等変換として扱われる。
  • dir() 組み込み関数が、引数に渡されたオブジェクトの __dir__() メソッドを見るようになった。 __dir__() は文字列のlistを返す必要がある。これにより __getattr__()__getattribute__() で、擬似属性みたいなのを実現しているクラスでもそのリストが返せる。
  • instance methodオブジェクトで im_self__self__im_func__func__ でも参照できるようになった。
  • class文内で locals() を使った場合、自由変数(クラスの属性でない変数)は含まれなくなった。

新規、改善、非推奨モジュール

  • 3.0警告モードで以下のモジュールは非推奨。

    • audiodev, bgenlocations, buildtools, bundlebuilder, Canvas, compiler, dircache, dl, fpformat, gensuitemodule, ihooks, imageop, imgfile, linuxaudiodev, mhlib, mimetools, multifile, new, pure, statvfs, sunaudiodev, test.testall, and toaiff.
  • asyncore , asynchat でメンテ再開。多くのパッチやバグフィックスが含まれた。

  • cgi でクエリ文字列付きPOSTリクエストにおいてクエリ文字列が解釈されるようになった。(/add.py?category=1へのPOSTなど)

  • parse_qsparse_qslcgi モジュールから urlparse モジュールへ。 cgi でもまだ使えるが PendingDeprecationWarning が出る。

  • cmathモジュールが改良された。

  • collections.namedtuple が新しく定義。

>>> var_type = collections.namedtuple('variable',
...             'id name type size')
# Names are separated by spaces or commas.
# 'id, name, type, size' would also work.
>>> var_type._fields
('id', 'name', 'type', 'size')

>>> var = var_type(1, 'frequency', 'int', 4)
>>> print var[0], var.id           # Equivalent
1 1
>>> print var[2], var.type          # Equivalent
int int
>>> var._asdict()
{'size': 4, 'type': 'int', 'id': 1, 'name': 'frequency'}
>>> v2 = var._replace(name='amplitude')
>>> v2
variable(id=1, name='amplitude', type='int', size=4)
  • collections.dequemaxlen 引数を取れるようになった。maxlenを超えて要素を追加すると自動で先頭が破棄される。
  • datetime モジュールの strftime() で’%f’が扱えるようになった。
  • decimal モジュールで exp() , log10() が追加、また as_tuple()sign,digits,exponent をフィールドとするnamed tupleを得られる。
  • difflib.SequenceMathcer クラスが a,b,size 属性をもったnamed tupleを返すようになった。
  • ftplib でタイムアウトが設定できるようになった。
  • glob.glob() がunicodeファイル名を返すようになった。
  • gopherlib 削除。
  • heapq モジュールに merge(iter1, iter2, ...)heappushpop(heap, item) が追加。
  • httplib.HTTPConnection でタイムアウトが設定できるようになった。
  • inspect モジュールの関数の多くがnamed tupleを返すようになった。
  • itertools に多数の関数を追加。

    • izip_longest(iter1, iter2, …[, fillvalue])
    • product(iter1, iter2, …, [repeat=N])
    • combinations(iterable, r)
    • permutations(iter[, r])
    • chain(*iterables) は新しく itertools.chain.from_iterable(iterable) とも書けるように。
  • math モジュールに関数を追加。

    • isinf() ,isnan(): 無限とNaNを判別。
    • copysign() : IEEE 754のサインビットをコピー。 math.copysign(1, -0.0)-1.0
    • factorial() :階乗を計算。
    • fsum() : iterableの数値を足すが、出来る限り精度を失うことを避ける。
    • acosh(), asinh() ,atanh()
    • log1p()
    • trunc() : 0の方向へ丸める。
  • MmeWritermimify モジュールが非推奨に。 email パッケージを使うこと。

  • md5 モジュールが非推奨に。 hashlib を使うこと。

  • mmap オブジェクトで文字列検索を行う rfind(),find() メソッドを追加。

  • operator モジュールに methodcaller() 関数追加。

>>> # Equivalent to lambda s: s.replace('old', 'new')
>>> replacer = operator.methodcaller('replace', 'old', 'new')
>>> replacer('old wine in old bottles')
'new wine in new bottles'
  • operator.attrgetter でドットを含む名前が取れるように。
>>> inst_name = operator.attrgetter(
...        '__class__.__name__')
>>> inst_name('')
'str'
>>> inst_name(help)
'_Helper'
  • os.walk()followlinks=False パラメータ追加。 True にセットされるとシンボリックリンクをたどる。無限ループ注意。
  • os.path.splitext() でドット始まりのファイル名の扱いが変更に。 ('.ipython', '') から ('', '.ipython')
  • os.path.relpath(path, start='.') が追加。 start からの相対パスを返す。
  • pdb に新しいコマンド run を追加。
  • posixfile モジュールが非推奨に。 fcntl.lockf() を変わりに使うこと。
  • pickletoolsoptimize() 関数追加。
  • popen2 モジュールが非推奨に。 subprocess モジュールを使うこと。
  • random モジュールの Random オブジェクトが32-bitと64-bit環境間でpickleできるようになった。また triangular(low,hight,mode) 関数追加。
  • re モジュールで長い正規表現を行うとき、シグナルをチェックするようにしたので、時間のかかる検索に割り込まれても大丈夫になった。また、正規表現は正規表現専用の仮想マシンコードの変換されるがベリファイアがなかったので、不正なコードを実行される可能性があった。今回ベリファイアを追加。
  • rgmimg モジュール削除。
  • sched.scheduler インスタンスに queue 属性追加。この属性は (time,priority,action,argument) から構成されるnamed tupleのリストを返す。
  • select モジュールがepoll,kqueueシステムコールのラッパ関数を導入。
  • sets モジュールが非推奨に。組み込み set, frozenset を使うこと。
  • sha モジュール非推奨。 hashlib モジュールを使うこと。
  • shutil.copytree()ignore=callable 引数追加。 ignore でコピーしないファイルリストを返すことが出来る。また ignore_patterns 関数を使い、以下のようにもできる
shutil.copytree('Doc/library', '/tmp/library',
                ignore=shutil.ignore_patterns('*~', '.svn'))
  • smtplib でSMTP over SSL, LMTPをサポート。
  • subprocess.Popen オブジェクトに terminate(), kill(), send_signal() 追加。
  • sys に様々な追加。

    • float.h 由来の情報を持った float_info オブジェクト。
    • .pyc.pyo を作るか制御する dont_write_bytecode
    • オブジェクトの使用メモリを取得する sys.getsizeof() 。組み込みオブジェクトは正しい数値を返す。
    • sys.getprofile() , sys.gettrace()
  • telnetlib でタイムアウトが設定できるようになった。

  • tempfile.NamedTemporaryFiledelete=False を指定することで自動削除しなくできる。

  • tempfile.SpooledTemporaryFile を追加。メモリ上に確保し、メモリにのらなくなるとファイルに書き出す。

  • test.test_supportwith 文を使った関数を提供する。

  • textwrap モジュールで空白文字を保持するため drop_whitespace=False を指定できるようになった。

  • timeit モジュールで文字列だけでなくcallableも受け取れるようになった。

  • タートルグラフィックを扱う turtle モジュールにかなりの改良。

  • urllib でタイムアウトを設定できるようになった。

  • zipfile.ZipFileextract()extractall(), open(), read() を追加。

  • ASTを扱う ast モジュール追加

  • JSONを扱う json モジュール追加

  • Property Listを扱う plistlib モジュール追加。

  • OpenSSL の上に構築された、 ssl モジュール追加。 socket モジュールのSSLサポートはまだ使えるが、3.0では削除される予定。このモジュールを使うためには、通常通りTCPコネクションを張り、 ssl.wrap_socket() 関数に渡す。

  • 3.0由来の組み込み関数を含む future_builtins モジュールを追加。

    • ascii : repr() と同義。3.0では repr() はunicode, ascii() はASCII byte文字列を返す。
    • filter,map : 2.xではリストを, 3.0ではイテレータを返す。
    • hex, oct : __hex__()__oct__() ではなく、 __index__() をよびその結果を変換する。

Python2.6への移行

  • ハッシュできないクラスは __hash__=None を行うべき。
  • collection.deque.__init__() は、iterableの要素を追加する前に自身の内容をクリアする。これは list.__init__() と同じ。
>>> from collections.deque
>>> a = deque([1,2,3])
>>> deque.__init__(a, [4,5,6])
>>> a
# python2.6 => deque([4,5,6])
# python2.5 => deque([1,2,3,4,5,6])
  • object.__init__() はこれまで任意の引数を渡すことができ、これらの引数は無視していた。2.6では余計な引数を渡すと TypeError がでる。
  • Decimal コンストラクタは前後に空白があっても大丈夫に。以前はInvalidOperation例外がでていた。一方、 Context.create_decimal() は余分な空白があると ConversionSyntax 例外が出るようになった。
  • __import__ で間違ってファイルパスを渡すと、指定したファイルをimportしていたが、これは決してそのように意図したわけではない。今はこのようなケースをチェックし、 ImportError を出すようになった。
  • C API: PyImport_ImportPyImport_ImportModule のデフォルトが相対importでなく完全importになった。これは他のモジュールをimportするC拡張に影響する。
  • socket.error 例外は IOError を継承するようになったので、 StandardError のサブクラスになった。
  • xmlrpclibdatetime.datedatetime.time を自動的に xmlrpclib.DateTime に変換しなくなった。なぜならこの挙動は全てのアプリケーションにとって必ずしも有用とは限らないからだ。 xmlrpclib を使っているコードは datetime インスタンスを変換すべきである。
  • 3.0警告モード: Exception クラスにスライシングおよびインデックスアクセスすると警告。
  • 3.0警告モード: 2つの辞書や、比較メソッドを実装していないオブジェクト間で比較演算子を適応すると警告。ただし、 dict1 == dict2 は動く。