annotate Lib/whichdb.py @ 80661:94de77bd0b4b 2.7

Issue #16194: document imp.load_dynamic problems when read several extension modules from the same binary object file.
author Andrew Svetlov <andrew.svetlov@gmail.com>
date Thu, 29 Nov 2012 19:51:28 +0200
parents 14cafb8d1480
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
33804
e9cbe0adb28a SF patch #1038388: __main__ for whichdb.py
Raymond Hettinger <python@rcn.com>
parents: 30723
diff changeset
1 # !/usr/bin/env python
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
2 """Guess which db package to use to open a db file."""
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
3
16949
09ba15ee1961 RISCOS changes by dschwertberger.
Guido van Rossum <guido@python.org>
parents: 16888
diff changeset
4 import os
24489
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
5 import struct
29811
6443a0fee7e1 patch #766650 - whichdb not identifying dbm DBs when dbm linked with gdbm
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 29573
diff changeset
6 import sys
24489
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
7
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
8 try:
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
9 import dbm
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
10 _dbmerror = dbm.error
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
11 except ImportError:
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
12 dbm = None
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
13 # just some sort of valid exception which might be raised in the
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
14 # dbm test
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
15 _dbmerror = IOError
16949
09ba15ee1961 RISCOS changes by dschwertberger.
Guido van Rossum <guido@python.org>
parents: 16888
diff changeset
16
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
17 def whichdb(filename):
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
18 """Guess which db package to use to open a db file.
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
19
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
20 Return values:
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
21
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
22 - None if the database file can't be read;
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
23 - empty string if the file can be read but can't be recognized
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
24 - the module name (e.g. "dbm" or "gdbm") if recognized.
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
25
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
26 Importing the given module may still fail, and opening the
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
27 database using that module may still fail.
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
28 """
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
29
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
30 # Check for dbm first -- this has a .pag and a .dir file
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
31 try:
20654
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 17055
diff changeset
32 f = open(filename + os.extsep + "pag", "rb")
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
33 f.close()
29811
6443a0fee7e1 patch #766650 - whichdb not identifying dbm DBs when dbm linked with gdbm
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 29573
diff changeset
34 # dbm linked with gdbm on OS/2 doesn't have .dir file
6443a0fee7e1 patch #766650 - whichdb not identifying dbm DBs when dbm linked with gdbm
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 29573
diff changeset
35 if not (dbm.library == "GNU gdbm" and sys.platform == "os2emx"):
6443a0fee7e1 patch #766650 - whichdb not identifying dbm DBs when dbm linked with gdbm
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 29573
diff changeset
36 f = open(filename + os.extsep + "dir", "rb")
6443a0fee7e1 patch #766650 - whichdb not identifying dbm DBs when dbm linked with gdbm
Andrew MacIntyre <andymac@bullseye.apana.org.au>
parents: 29573
diff changeset
37 f.close()
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
38 return "dbm"
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
39 except IOError:
24489
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
40 # some dbm emulations based on Berkeley DB generate a .db file
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
41 # some do not, but they should be caught by the dbhash checks
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
42 try:
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
43 f = open(filename + os.extsep + "db", "rb")
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
44 f.close()
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
45 # guarantee we can actually open the file using dbm
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
46 # kind of overkill, but since we are dealing with emulations
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
47 # it seems like a prudent step
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
48 if dbm is not None:
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
49 d = dbm.open(filename)
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
50 d.close()
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
51 return "dbm"
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
52 except (IOError, _dbmerror):
bcc35a0f1a78 catch the situation where Berkeley DB is used to emulate dbm(3) library
Skip Montanaro <skip@pobox.com>
parents: 20654
diff changeset
53 pass
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
54
30723
6f15e73b59f2 Backport checkin:
Walter Dörwald <walter@livinglogic.de>
parents: 29811
diff changeset
55 # Check for dumbdbm next -- this has a .dir and a .dat file
13852
c480529807ab Add missing 'try:'. Patch by Rob W. W. Hooft, #101071 (closed.)
Thomas Wouters <thomas@python.org>
parents: 13741
diff changeset
56 try:
29461
8b1766c8ad3b Treat empty dat/dir pairs as dumbdbm. Fixes #744687.
Martin v. Löwis <martin@v.loewis.de>
parents: 28999
diff changeset
57 # First check for presence of files
29573
e2f783488024 Patch #755087: Deal with emptied dumbdbm files correctly.
Martin v. Löwis <martin@v.loewis.de>
parents: 29461
diff changeset
58 os.stat(filename + os.extsep + "dat")
e2f783488024 Patch #755087: Deal with emptied dumbdbm files correctly.
Martin v. Löwis <martin@v.loewis.de>
parents: 29461
diff changeset
59 size = os.stat(filename + os.extsep + "dir").st_size
29461
8b1766c8ad3b Treat empty dat/dir pairs as dumbdbm. Fixes #744687.
Martin v. Löwis <martin@v.loewis.de>
parents: 28999
diff changeset
60 # dumbdbm files with no keys are empty
29573
e2f783488024 Patch #755087: Deal with emptied dumbdbm files correctly.
Martin v. Löwis <martin@v.loewis.de>
parents: 29461
diff changeset
61 if size == 0:
29461
8b1766c8ad3b Treat empty dat/dir pairs as dumbdbm. Fixes #744687.
Martin v. Löwis <martin@v.loewis.de>
parents: 28999
diff changeset
62 return "dumbdbm"
20654
edd9d0b3c47e SF patch #474590 -- RISC OS support
Guido van Rossum <guido@python.org>
parents: 17055
diff changeset
63 f = open(filename + os.extsep + "dir", "rb")
13741
f65b86738d3b Added support to recognize Python's internal "dumbdbm" database.
Moshe Zadka <moshez@math.huji.ac.il>
parents: 11742
diff changeset
64 try:
34545
9d66fba78444 Replace list of constants with tuples of constants.
Raymond Hettinger <python@rcn.com>
parents: 33804
diff changeset
65 if f.read(1) in ("'", '"'):
13741
f65b86738d3b Added support to recognize Python's internal "dumbdbm" database.
Moshe Zadka <moshez@math.huji.ac.il>
parents: 11742
diff changeset
66 return "dumbdbm"
f65b86738d3b Added support to recognize Python's internal "dumbdbm" database.
Moshe Zadka <moshez@math.huji.ac.il>
parents: 11742
diff changeset
67 finally:
f65b86738d3b Added support to recognize Python's internal "dumbdbm" database.
Moshe Zadka <moshez@math.huji.ac.il>
parents: 11742
diff changeset
68 f.close()
29461
8b1766c8ad3b Treat empty dat/dir pairs as dumbdbm. Fixes #744687.
Martin v. Löwis <martin@v.loewis.de>
parents: 28999
diff changeset
69 except (OSError, IOError):
13741
f65b86738d3b Added support to recognize Python's internal "dumbdbm" database.
Moshe Zadka <moshez@math.huji.ac.il>
parents: 11742
diff changeset
70 pass
f65b86738d3b Added support to recognize Python's internal "dumbdbm" database.
Moshe Zadka <moshez@math.huji.ac.il>
parents: 11742
diff changeset
71
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
72 # See if the file exists, return None if not
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
73 try:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
74 f = open(filename, "rb")
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
75 except IOError:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
76 return None
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
77
10933
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
78 # Read the start of the file -- the magic number
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
79 s16 = f.read(16)
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
80 f.close()
10933
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
81 s = s16[0:4]
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
82
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
83 # Return "" if not at least 4 bytes
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
84 if len(s) != 4:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
85 return ""
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
86
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
87 # Convert to 4-byte int in native byte order -- return "" if impossible
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
88 try:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
89 (magic,) = struct.unpack("=l", s)
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
90 except struct.error:
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
91 return ""
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
92
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
93 # Check for GNU dbm
72413
14cafb8d1480 Close #13007: whichdb should recognize gdbm 1.9 magic numbers
Jesus Cea <jcea@jcea.es>
parents: 34545
diff changeset
94 if magic in (0x13579ace, 0x13579acd, 0x13579acf):
7755
fb4b4d069cc7 Mass check-in after untabifying all files that need it.
Guido van Rossum <guido@python.org>
parents: 4932
diff changeset
95 return "gdbm"
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
96
28999
e107c921b8f3 detect old version 2 hash files and return "bsddb185" as the appropriate
Skip Montanaro <skip@pobox.com>
parents: 24489
diff changeset
97 # Check for old Berkeley db hash file format v2
8172
5732ec2487c5 Support byte-swapped dbhash (bsddb) files. Found by Ben Sayer.
Guido van Rossum <guido@python.org>
parents: 7755
diff changeset
98 if magic in (0x00061561, 0x61150600):
28999
e107c921b8f3 detect old version 2 hash files and return "bsddb185" as the appropriate
Skip Montanaro <skip@pobox.com>
parents: 24489
diff changeset
99 return "bsddb185"
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
100
28999
e107c921b8f3 detect old version 2 hash files and return "bsddb185" as the appropriate
Skip Montanaro <skip@pobox.com>
parents: 24489
diff changeset
101 # Later versions of Berkeley db hash file have a 12-byte pad in
e107c921b8f3 detect old version 2 hash files and return "bsddb185" as the appropriate
Skip Montanaro <skip@pobox.com>
parents: 24489
diff changeset
102 # front of the file type
10933
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
103 try:
11742
840e18eec07f Untabify to pass the -tt test.
Fred Drake <fdrake@acm.org>
parents: 10933
diff changeset
104 (magic,) = struct.unpack("=l", s16[-4:])
10933
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
105 except struct.error:
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
106 return ""
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
107
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
108 # Check for BSD hash
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
109 if magic in (0x00061561, 0x61150600):
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
110 return "dbhash"
cc6abc99d2dd Skip Montanaro:
Guido van Rossum <guido@python.org>
parents: 8172
diff changeset
111
3825
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
112 # Unknown
c3ec69b1fe36 Function to guess which db package created a database.
Guido van Rossum <guido@python.org>
parents:
diff changeset
113 return ""
33804
e9cbe0adb28a SF patch #1038388: __main__ for whichdb.py
Raymond Hettinger <python@rcn.com>
parents: 30723
diff changeset
114
e9cbe0adb28a SF patch #1038388: __main__ for whichdb.py
Raymond Hettinger <python@rcn.com>
parents: 30723
diff changeset
115 if __name__ == "__main__":
e9cbe0adb28a SF patch #1038388: __main__ for whichdb.py
Raymond Hettinger <python@rcn.com>
parents: 30723
diff changeset
116 for filename in sys.argv[1:]:
e9cbe0adb28a SF patch #1038388: __main__ for whichdb.py
Raymond Hettinger <python@rcn.com>
parents: 30723
diff changeset
117 print whichdb(filename) or "UNKNOWN", filename