memo

2014-02-27

python で frozen なモジュールって何?

import すると Hello world... と出力される __hello__ モジュールの存在を知った。

$ python -c 'import __hello__'
Hello world...

さて、この __hello__ がどこから来てるのかと気になったので、まずは __file__ を見てみる。

Python 2.7.6 (default, Dec 15 2013, 20:27:01) 
[GCC 4.8.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import __hello__
Hello world...
>>> print __hello__.__file__
<frozen>

<frozen> って何?

http://docs.python.org/2/library/imp.html#imp.init_frozen

Frozen modules are modules written in Python whose compiled byte-code object is incorporated into a custom-built Python interpreter by Python's freeze utility. See Tools/freeze/ for now.

https://wiki.python.org/moin/Freeze

__hello__ 自体は Python/frozen.c から来ているっぽい。

作ってみる

__myhello__.py:

print 'hello world!'

hello.py:

import __myhello__
print __myhello__.__file__
$ python ~/src/Python-2.7.6/Tools/freeze/freeze.py hello.py
Name                      File
----                      ----
m BaseHTTPServer            /usr/lib64/python2.7/BaseHTTPServer.py
m FixTk                     /usr/lib64/python2.7/lib-tk/FixTk.py
m SocketServer              /usr/lib64/python2.7/SocketServer.py
m StringIO                  /usr/lib64/python2.7/StringIO.py
m Tkconstants               /usr/lib64/python2.7/lib-tk/Tkconstants.py
m Tkinter                   /usr/lib64/python2.7/lib-tk/Tkinter.py
m UserDict                  /usr/lib64/python2.7/UserDict.py
m __builtin__
m __future__                /usr/lib64/python2.7/__future__.py
m __main__                  hello.py
m __myhello__               __myhello__.py
... snip ...
freezing urllib ...
freezing urlparse ...
freezing uu ...
freezing warnings ...
freezing weakref ...
freezing webbrowser ...
generating table of frozen modules
Warning: unknown modules remain: _collections _ctypes _functools _hashlib _heapq _io _locale _random _socket _ssl _struct array binascii cPickle cStringIO datetime fcntl itertools math operator readline select strop termios time
Now run "make" to build the target: hello
$ : なんか libpython2.7.a の path が違ってたので Makefile を修正
$ vim Makefile
$ make
x86_64-pc-linux-gnu-gcc -pthread -DNDEBUG -fwrapv -I/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/include/python2.7 -I/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/include/python2.7 -c config.c
x86_64-pc-linux-gnu-gcc -pthread -DNDEBUG -fwrapv -I/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/include/python2.7 -I/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/include/python2.7 -c frozen.c
x86_64-pc-linux-gnu-gcc -pthread -DNDEBUG -fwrapv -I/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/include/python2.7 -I/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/include/python2.7 -c M_BaseHTTPServer.c
... snip ...
x86_64-pc-linux-gnu-gcc -pthread -L/usr/lib64 -Xlinker -export-dynamic config.o frozen.o M_BaseHTTPServer.o M_FixTk.o M_SocketServer.o M_StringIO.o M_Tkconstants.o M_Tkinter.o M_UserDict.o M___future__.o M___main__.o M___myhello__.o M__abcoll.o M__osx_support.o M__sysconfigdata.o M__threading_local.o M__weakrefset.o M_abc.o M_atexit.o M_base64.o M_bdb.o M_calendar.o M_cmd.o M_codecs.o M_collections.o M_contextlib.o M_copy.o M_copy_reg.o M_ctypes.o M_ctypes___endian.o M_difflib.o M_dis.o M_distutils.o M_distutils__log.o M_doctest.o M_dummy_thread.o M_dummy_threading.o M_email.o M_email___parseaddr.o M_email__base64mime.o M_email__charset.o M_email__encoders.o M_email__errors.o M_email__feedparser.o M_email__generator.o M_email__header.o M_email__iterators.o M_email__message.o M_email__mime.o M_email__parser.o M_email__quoprimime.o M_email__utils.o M_encodings.o M_encodings__aliases.o M_fnmatch.o M_formatter.o M_ftplib.o M_functools.o M_genericpath.o M_getopt.o M_getpass.o M_gettext.o M_glob.o M_hashlib.o M_heapq.o M_httplib.o M_inspect.o M_io.o M_keyword.o M_linecache.o M_locale.o M_logging.o M_mimetools.o M_mimetypes.o M_ntpath.o M_nturl2path.o M_opcode.o M_optparse.o M_os.o M_os2emxpath.o M_pdb.o M_pickle.o M_pkgutil.o M_posixpath.o M_pprint.o M_pydoc.o M_pydoc_data.o M_pydoc_data__topics.o M_quopri.o M_random.o M_re.o M_repr.o M_rfc822.o M_shlex.o M_site.o M_socket.o M_sre_compile.o M_sre_constants.o M_sre_parse.o M_ssl.o M_stat.o M_string.o M_struct.o M_subprocess.o M_sysconfig.o M_tempfile.o M_textwrap.o M_threading.o M_token.o M_tokenize.o M_traceback.o M_tty.o M_types.o M_unittest.o M_unittest__case.o M_unittest__loader.o M_unittest__main.o M_unittest__result.o M_unittest__runner.o M_unittest__signals.o M_unittest__suite.o M_unittest__util.o M_urllib.o M_urlparse.o M_uu.o M_warnings.o M_weakref.o M_webbrowser.o /usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/lib64/libpython2.7.a   -lpthread -ldl  -lutil -lm  -o hello
/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/lib64/libpython2.7.a(posixmodule.o): In function `posix_tmpnam':
posixmodule.c:(.text+0x31b5): warning: the use of `tmpnam_r' is dangerous, better use `mkstemp'
/usr/bin/../../etc/env.d/alternatives/python/_current/usr/bin/../../../../../../../usr/bin/../../etc/env.d/alternatives/python2/_current/usr/bin/../../../../../../../usr/lib64/libpython2.7.a(posixmodule.o): In function `posix_tempnam':
posixmodule.c:(.text+0x4ae): warning: the use of `tempnam' is dangerous, better use `mkstemp'
$ ls hello
hello*
$ ./hello
hello world!
<frozen>

確かに <frozen> になってる。