Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
Z
ZODB
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Kirill Smelkov
ZODB
Commits
266cadf9
Commit
266cadf9
authored
Feb 14, 2013
by
Stephan Richter
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Fixed up as many unit tests as I could. There are between 13-16
failures left.
parent
de1ed537
Changes
46
Show whitespace changes
Inline
Side-by-side
Showing
46 changed files
with
457 additions
and
327 deletions
+457
-327
src/ZODB/BaseStorage.py
src/ZODB/BaseStorage.py
+1
-1
src/ZODB/ConflictResolution.py
src/ZODB/ConflictResolution.py
+17
-16
src/ZODB/ConflictResolution.txt
src/ZODB/ConflictResolution.txt
+21
-21
src/ZODB/Connection.py
src/ZODB/Connection.py
+4
-3
src/ZODB/DB.py
src/ZODB/DB.py
+5
-6
src/ZODB/DemoStorage.test
src/ZODB/DemoStorage.test
+11
-8
src/ZODB/ExportImport.py
src/ZODB/ExportImport.py
+1
-0
src/ZODB/FileStorage/FileStorage.py
src/ZODB/FileStorage/FileStorage.py
+6
-4
src/ZODB/FileStorage/tests.py
src/ZODB/FileStorage/tests.py
+1
-1
src/ZODB/POSException.py
src/ZODB/POSException.py
+1
-4
src/ZODB/blob.py
src/ZODB/blob.py
+11
-10
src/ZODB/fsrecover.py
src/ZODB/fsrecover.py
+1
-1
src/ZODB/historical_connections.txt
src/ZODB/historical_connections.txt
+4
-4
src/ZODB/persistentclass.txt
src/ZODB/persistentclass.txt
+10
-8
src/ZODB/serialize.py
src/ZODB/serialize.py
+10
-4
src/ZODB/tests/MinPO.py
src/ZODB/tests/MinPO.py
+8
-3
src/ZODB/tests/blob_basic.txt
src/ZODB/tests/blob_basic.txt
+8
-7
src/ZODB/tests/blob_consume.txt
src/ZODB/tests/blob_consume.txt
+11
-10
src/ZODB/tests/blob_layout.txt
src/ZODB/tests/blob_layout.txt
+31
-19
src/ZODB/tests/blobstorage_packing.txt
src/ZODB/tests/blobstorage_packing.txt
+14
-7
src/ZODB/tests/dbopen.txt
src/ZODB/tests/dbopen.txt
+8
-7
src/ZODB/tests/multidb.txt
src/ZODB/tests/multidb.txt
+12
-8
src/ZODB/tests/testBroken.py
src/ZODB/tests/testBroken.py
+3
-3
src/ZODB/tests/testCache.py
src/ZODB/tests/testCache.py
+14
-10
src/ZODB/tests/testConfig.py
src/ZODB/tests/testConfig.py
+3
-1
src/ZODB/tests/testDB.py
src/ZODB/tests/testDB.py
+13
-1
src/ZODB/tests/testDemoStorage.py
src/ZODB/tests/testDemoStorage.py
+5
-7
src/ZODB/tests/testMVCCMappingStorage.py
src/ZODB/tests/testMVCCMappingStorage.py
+2
-2
src/ZODB/tests/testPersistentList.py
src/ZODB/tests/testPersistentList.py
+16
-12
src/ZODB/tests/testPersistentMapping.py
src/ZODB/tests/testPersistentMapping.py
+13
-17
src/ZODB/tests/testPersistentWeakref.py
src/ZODB/tests/testPersistentWeakref.py
+1
-1
src/ZODB/tests/testRecover.py
src/ZODB/tests/testRecover.py
+9
-9
src/ZODB/tests/testSerialize.py
src/ZODB/tests/testSerialize.py
+3
-1
src/ZODB/tests/testUtils.py
src/ZODB/tests/testUtils.py
+11
-11
src/ZODB/tests/test_fsdump.py
src/ZODB/tests/test_fsdump.py
+3
-1
src/ZODB/tests/test_persistentclass.py
src/ZODB/tests/test_persistentclass.py
+0
-52
src/ZODB/tests/testblob.py
src/ZODB/tests/testblob.py
+6
-5
src/ZODB/tests/testconflictresolution.py
src/ZODB/tests/testconflictresolution.py
+4
-4
src/ZODB/tests/testcrossdatabasereferences.py
src/ZODB/tests/testcrossdatabasereferences.py
+17
-12
src/ZODB/tests/testfsIndex.py
src/ZODB/tests/testfsIndex.py
+15
-10
src/ZODB/tests/testfsoids.py
src/ZODB/tests/testfsoids.py
+2
-1
src/ZODB/tests/testhistoricalconnections.py
src/ZODB/tests/testhistoricalconnections.py
+2
-1
src/ZODB/tests/testpersistentclass.py
src/ZODB/tests/testpersistentclass.py
+33
-4
src/ZODB/tests/util.py
src/ZODB/tests/util.py
+33
-2
src/ZODB/utils.py
src/ZODB/utils.py
+10
-8
tox.ini
tox.ini
+43
-0
No files found.
src/ZODB/BaseStorage.py
View file @
266cadf9
...
@@ -21,6 +21,7 @@ from __future__ import print_function
...
@@ -21,6 +21,7 @@ from __future__ import print_function
import
threading
import
threading
import
time
import
time
import
logging
import
logging
import
sys
from
struct
import
pack
as
_structpack
,
unpack
as
_structunpack
from
struct
import
pack
as
_structpack
,
unpack
as
_structunpack
import
zope.interface
import
zope.interface
...
@@ -41,7 +42,6 @@ except ImportError:
...
@@ -41,7 +42,6 @@ except ImportError:
log
=
logging
.
getLogger
(
"ZODB.BaseStorage"
)
log
=
logging
.
getLogger
(
"ZODB.BaseStorage"
)
import
sys
class
BaseStorage
(
UndoLogCompatible
):
class
BaseStorage
(
UndoLogCompatible
):
...
...
src/ZODB/ConflictResolution.py
View file @
266cadf9
...
@@ -13,30 +13,31 @@
...
@@ -13,30 +13,31 @@
##############################################################################
##############################################################################
import
logging
import
logging
import
sys
from
pickle
import
PicklingError
from
pickle
import
PicklingError
import
six
import
zope.interface
import
zope.interface
from
ZODB.POSException
import
ConflictError
from
ZODB.POSException
import
ConflictError
from
ZODB.loglevels
import
BLATHER
from
ZODB.loglevels
import
BLATHER
from
ZODB.serialize
import
_protocol
from
ZODB.serialize
import
_protocol
,
_Unpickler
try
:
try
:
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
as
BytesIO
except
ImportError
:
except
ImportError
:
# Py3
# Py3
from
io
import
String
IO
from
io
import
Bytes
IO
try
:
try
:
from
cPickle
import
Unpickler
,
Pickler
from
cPickle
import
Pickler
except
ImportError
:
except
ImportError
:
# Py3
# Py3
from
pickle
import
Unpickler
,
Pickler
from
pickle
import
Pickler
logger
=
logging
.
getLogger
(
'ZODB.ConflictResolution'
)
logger
=
logging
.
getLogger
(
'ZODB.ConflictResolution'
)
ResolvedSerial
=
'rs'
ResolvedSerial
=
b
'rs'
class
BadClassName
(
Exception
):
class
BadClassName
(
Exception
):
pass
pass
...
@@ -69,8 +70,8 @@ def find_global(*args):
...
@@ -69,8 +70,8 @@ def find_global(*args):
if
cls
==
1
:
if
cls
==
1
:
# Not importable
# Not importable
if
(
isinstance
(
args
,
tuple
)
and
len
(
args
)
==
2
and
if
(
isinstance
(
args
,
tuple
)
and
len
(
args
)
==
2
and
isinstance
(
args
[
0
],
basestring
)
and
isinstance
(
args
[
0
],
six
.
string_types
)
and
isinstance
(
args
[
1
],
basestring
)
isinstance
(
args
[
1
],
six
.
string_types
)
):
):
return
BadClass
(
*
args
)
return
BadClass
(
*
args
)
else
:
else
:
...
@@ -80,8 +81,8 @@ def find_global(*args):
...
@@ -80,8 +81,8 @@ def find_global(*args):
def
state
(
self
,
oid
,
serial
,
prfactory
,
p
=
''
):
def
state
(
self
,
oid
,
serial
,
prfactory
,
p
=
''
):
p
=
p
or
self
.
loadSerial
(
oid
,
serial
)
p
=
p
or
self
.
loadSerial
(
oid
,
serial
)
p
=
self
.
_crs_untransform_record_data
(
p
)
p
=
self
.
_crs_untransform_record_data
(
p
)
file
=
String
IO
(
p
)
file
=
Bytes
IO
(
p
)
unpickler
=
Unpickler
(
file
)
unpickler
=
_
Unpickler
(
file
)
unpickler
.
find_global
=
find_global
unpickler
.
find_global
=
find_global
unpickler
.
persistent_load
=
prfactory
.
persistent_load
unpickler
.
persistent_load
=
prfactory
.
persistent_load
unpickler
.
load
()
# skip the class tuple
unpickler
.
load
()
# skip the class tuple
...
@@ -221,13 +222,13 @@ def persistent_id(object):
...
@@ -221,13 +222,13 @@ def persistent_id(object):
_unresolvable
=
{}
_unresolvable
=
{}
def
tryToResolveConflict
(
self
,
oid
,
committedSerial
,
oldSerial
,
newpickle
,
def
tryToResolveConflict
(
self
,
oid
,
committedSerial
,
oldSerial
,
newpickle
,
committedData
=
''
):
committedData
=
b
''
):
# class_tuple, old, committed, newstate = ('',''), 0, 0, 0
# class_tuple, old, committed, newstate = ('',''), 0, 0, 0
try
:
try
:
prfactory
=
PersistentReferenceFactory
()
prfactory
=
PersistentReferenceFactory
()
newpickle
=
self
.
_crs_untransform_record_data
(
newpickle
)
newpickle
=
self
.
_crs_untransform_record_data
(
newpickle
)
file
=
String
IO
(
newpickle
)
file
=
Bytes
IO
(
newpickle
)
unpickler
=
Unpickler
(
file
)
unpickler
=
_
Unpickler
(
file
)
unpickler
.
find_global
=
find_global
unpickler
.
find_global
=
find_global
unpickler
.
persistent_load
=
prfactory
.
persistent_load
unpickler
.
persistent_load
=
prfactory
.
persistent_load
meta
=
unpickler
.
load
()
meta
=
unpickler
.
load
()
...
@@ -269,7 +270,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
...
@@ -269,7 +270,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
resolved
=
resolve
(
old
,
committed
,
newstate
)
resolved
=
resolve
(
old
,
committed
,
newstate
)
file
=
String
IO
()
file
=
Bytes
IO
()
pickler
=
Pickler
(
file
,
_protocol
)
pickler
=
Pickler
(
file
,
_protocol
)
if
sys
.
version_info
[
0
]
<
3
:
if
sys
.
version_info
[
0
]
<
3
:
pickler
.
inst_persistent_id
=
persistent_id
pickler
.
inst_persistent_id
=
persistent_id
...
@@ -277,7 +278,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
...
@@ -277,7 +278,7 @@ def tryToResolveConflict(self, oid, committedSerial, oldSerial, newpickle,
pickler
.
persistent_id
=
persistent_id
pickler
.
persistent_id
=
persistent_id
pickler
.
dump
(
meta
)
pickler
.
dump
(
meta
)
pickler
.
dump
(
resolved
)
pickler
.
dump
(
resolved
)
return
self
.
_crs_transform_record_data
(
file
.
getvalue
(
1
))
return
self
.
_crs_transform_record_data
(
file
.
getvalue
())
except
(
ConflictError
,
BadClassName
):
except
(
ConflictError
,
BadClassName
):
pass
pass
except
:
except
:
...
...
src/ZODB/ConflictResolution.txt
View file @
266cadf9
...
@@ -86,7 +86,7 @@ use:
...
@@ -86,7 +86,7 @@ use:
.. -> src
.. -> src
>>> import ConflictResolution_txt
>>> import ConflictResolution_txt
>>> exec
src in ConflictResolution_txt.__dict__
>>> exec
(src, ConflictResolution_txt.__dict__)
>>> PCounter = ConflictResolution_txt.PCounter
>>> PCounter = ConflictResolution_txt.PCounter
>>> PCounter.__module__ = 'ConflictResolution_txt'
>>> PCounter.__module__ = 'ConflictResolution_txt'
...
@@ -198,7 +198,7 @@ Here's an example of a broken _p_resolveConflict method::
...
@@ -198,7 +198,7 @@ Here's an example of a broken _p_resolveConflict method::
.. -> src
.. -> src
>>> exec
src in ConflictResolution_txt.__dict__
>>> exec
(src, ConflictResolution_txt.__dict__)
>>> PCounter2 = ConflictResolution_txt.PCounter2
>>> PCounter2 = ConflictResolution_txt.PCounter2
>>> PCounter2.__module__ = 'ConflictResolution_txt'
>>> PCounter2.__module__ = 'ConflictResolution_txt'
...
@@ -293,11 +293,11 @@ and newState [#get_persistent_reference]_. They have an oid, `weak` is
...
@@ -293,11 +293,11 @@ and newState [#get_persistent_reference]_. They have an oid, `weak` is
False, and `database_name` is None. `klass` happens to be set but this is
False, and `database_name` is None. `klass` happens to be set but this is
not always the case.
not always the case.
>>> isinstance(new.oid,
str
)
>>> isinstance(new.oid,
bytes
)
True
True
>>> new.weak
>>> new.weak
False
False
>>> print
new.database_name
>>> print
(new.database_name)
None
None
>>> new.klass is PCounter
>>> new.klass is PCounter
True
True
...
@@ -431,7 +431,7 @@ integrity issues.
...
@@ -431,7 +431,7 @@ integrity issues.
.. -> src
.. -> src
>>> exec
src in ConflictResolution_txt.__dict__
>>> exec
(src, ConflictResolution_txt.__dict__)
>>> PCounter3 = ConflictResolution_txt.PCounter3
>>> PCounter3 = ConflictResolution_txt.PCounter3
>>> PCounter3.__module__ = 'ConflictResolution_txt'
>>> PCounter3.__module__ = 'ConflictResolution_txt'
...
@@ -475,47 +475,47 @@ integrity issues.
...
@@ -475,47 +475,47 @@ integrity issues.
>>> from ZODB.ConflictResolution import PersistentReference
>>> from ZODB.ConflictResolution import PersistentReference
>>> ref1 = PersistentReference('my_oid')
>>> ref1 = PersistentReference(
b
'my_oid')
>>> ref1.oid
>>> ref1.oid
'my_oid'
'my_oid'
>>> print
ref1.klass
>>> print
(ref1.klass)
None
None
>>> print
ref1.database_name
>>> print
(ref1.database_name)
None
None
>>> ref1.weak
>>> ref1.weak
False
False
>>> ref2 = PersistentReference(('my_oid', 'my_class'))
>>> ref2 = PersistentReference((
b
'my_oid', 'my_class'))
>>> ref2.oid
>>> ref2.oid
'my_oid'
'my_oid'
>>> ref2.klass
>>> ref2.klass
'my_class'
'my_class'
>>> print
ref2.database_name
>>> print
(ref2.database_name)
None
None
>>> ref2.weak
>>> ref2.weak
False
False
>>> ref3 = PersistentReference(['w', ('my_oid',)])
>>> ref3 = PersistentReference(['w', (
b
'my_oid',)])
>>> ref3.oid
>>> ref3.oid
'my_oid'
'my_oid'
>>> print
ref3.klass
>>> print
(ref3.klass)
None
None
>>> print
ref3.database_name
>>> print
(ref3.database_name)
None
None
>>> ref3.weak
>>> ref3.weak
True
True
>>> ref3a = PersistentReference(['w', ('my_oid', 'other_db')])
>>> ref3a = PersistentReference(['w', (
b
'my_oid', 'other_db')])
>>> ref3a.oid
>>> ref3a.oid
'my_oid'
'my_oid'
>>> print
ref3a.klass
>>> print
(ref3a.klass)
None
None
>>> ref3a.database_name
>>> ref3a.database_name
'other_db'
'other_db'
>>> ref3a.weak
>>> ref3a.weak
True
True
>>> ref4 = PersistentReference(['m', ('other_db', 'my_oid', 'my_class')])
>>> ref4 = PersistentReference(['m', ('other_db',
b
'my_oid', 'my_class')])
>>> ref4.oid
>>> ref4.oid
'my_oid'
'my_oid'
>>> ref4.klass
>>> ref4.klass
...
@@ -525,22 +525,22 @@ integrity issues.
...
@@ -525,22 +525,22 @@ integrity issues.
>>> ref4.weak
>>> ref4.weak
False
False
>>> ref5 = PersistentReference(['n', ('other_db', 'my_oid')])
>>> ref5 = PersistentReference(['n', ('other_db',
b
'my_oid')])
>>> ref5.oid
>>> ref5.oid
'my_oid'
'my_oid'
>>> print
ref5.klass
>>> print
(ref5.klass)
None
None
>>> ref5.database_name
>>> ref5.database_name
'other_db'
'other_db'
>>> ref5.weak
>>> ref5.weak
False
False
>>> ref6 = PersistentReference(['my_oid']) # legacy
>>> ref6 = PersistentReference([
b
'my_oid']) # legacy
>>> ref6.oid
>>> ref6.oid
'my_oid'
'my_oid'
>>> print
ref6.klass
>>> print
(ref6.klass)
None
None
>>> print
ref6.database_name
>>> print
(ref6.database_name)
None
None
>>> ref6.weak
>>> ref6.weak
True
True
...
...
src/ZODB/Connection.py
View file @
266cadf9
...
@@ -48,12 +48,13 @@ from ZODB.POSException import ConflictError, ReadConflictError
...
@@ -48,12 +48,13 @@ from ZODB.POSException import ConflictError, ReadConflictError
from
ZODB.POSException
import
Unsupported
,
ReadOnlyHistoryError
from
ZODB.POSException
import
Unsupported
,
ReadOnlyHistoryError
from
ZODB.POSException
import
POSKeyError
from
ZODB.POSException
import
POSKeyError
from
ZODB.serialize
import
ObjectWriter
,
ObjectReader
from
ZODB.serialize
import
ObjectWriter
,
ObjectReader
from
ZODB.utils
import
p64
,
u64
,
z64
,
oid_repr
,
positive_id
,
bytes
from
ZODB.utils
import
p64
,
u64
,
z64
,
oid_repr
,
positive_id
from
ZODB
import
utils
from
ZODB
import
utils
import
six
import
six
global_reset_counter
=
0
global_reset_counter
=
0
def
resetCaches
():
def
resetCaches
():
"""Causes all connection caches to be reset as connections are reopened.
"""Causes all connection caches to be reset as connections are reopened.
...
@@ -494,7 +495,7 @@ class Connection(ExportImport, object):
...
@@ -494,7 +495,7 @@ class Connection(ExportImport, object):
if
invalidated
is
None
:
if
invalidated
is
None
:
# special value: the transaction is so old that
# special value: the transaction is so old that
# we need to flush the whole cache.
# we need to flush the whole cache.
self
.
_cache
.
invalidate
(
self
.
_cache
.
cache_data
.
keys
(
))
self
.
_cache
.
invalidate
(
list
(
self
.
_cache
.
cache_data
.
keys
()
))
elif
invalidated
:
elif
invalidated
:
self
.
_cache
.
invalidate
(
invalidated
)
self
.
_cache
.
invalidate
(
invalidated
)
...
@@ -1013,7 +1014,7 @@ class Connection(ExportImport, object):
...
@@ -1013,7 +1014,7 @@ class Connection(ExportImport, object):
for
k
,
v
in
items
:
for
k
,
v
in
items
:
del
everything
[
k
]
del
everything
[
k
]
# return a list of [ghosts....not recently used.....recently used]
# return a list of [ghosts....not recently used.....recently used]
return
everything
.
items
(
)
+
items
return
list
(
everything
.
items
()
)
+
items
def
open
(
self
,
transaction_manager
=
None
,
delegate
=
True
):
def
open
(
self
,
transaction_manager
=
None
,
delegate
=
True
):
"""Register odb, the DB that this Connection uses.
"""Register odb, the DB that this Connection uses.
...
...
src/ZODB/DB.py
View file @
266cadf9
...
@@ -535,9 +535,7 @@ class DB(object):
...
@@ -535,9 +535,7 @@ class DB(object):
detail
[
c
]
=
1
detail
[
c
]
=
1
self
.
_connectionMap
(
f
)
self
.
_connectionMap
(
f
)
detail
=
detail
.
items
()
return
sorted
(
detail
.
items
())
detail
.
sort
()
return
detail
def
cacheExtremeDetail
(
self
):
def
cacheExtremeDetail
(
self
):
detail
=
[]
detail
=
[]
...
@@ -611,8 +609,9 @@ class DB(object):
...
@@ -611,8 +609,9 @@ class DB(object):
'ngsize'
:
con
.
_cache
.
cache_non_ghost_count
,
'ngsize'
:
con
.
_cache
.
cache_non_ghost_count
,
'size'
:
len
(
con
.
_cache
)})
'size'
:
len
(
con
.
_cache
)})
self
.
_connectionMap
(
f
)
self
.
_connectionMap
(
f
)
m
.
sort
()
# Py3: Simulate Python 2 m.sort() functionality.
return
m
return
sorted
(
m
,
key
=
lambda
x
:
(
x
[
'connection'
],
x
[
'ngsize'
],
x
[
'size'
]))
def
close
(
self
):
def
close
(
self
):
"""Close the database and its underlying storage.
"""Close the database and its underlying storage.
...
@@ -932,7 +931,7 @@ class DB(object):
...
@@ -932,7 +931,7 @@ class DB(object):
raise
NotImplementedError
raise
NotImplementedError
if
txn
is
None
:
if
txn
is
None
:
txn
=
transaction
.
get
()
txn
=
transaction
.
get
()
if
isinstance
(
ids
,
basestring
):
if
isinstance
(
ids
,
six
.
string_types
):
ids
=
[
ids
]
ids
=
[
ids
]
txn
.
join
(
TransactionalUndo
(
self
,
ids
))
txn
.
join
(
TransactionalUndo
(
self
,
ids
))
...
...
src/ZODB/DemoStorage.test
View file @
266cadf9
...
@@ -55,8 +55,7 @@ Let's add some data:
...
@@ -55,8 +55,7 @@ Let's add some data:
>>>
db
=
DB
(
storage
)
>>>
db
=
DB
(
storage
)
>>>
conn
=
db
.
open
()
>>>
conn
=
db
.
open
()
>>>
items
=
conn
.
root
()[
'1'
]
.
items
()
>>>
items
=
sorted
(
conn
.
root
()[
'1'
]
.
items
())
>>>
items
.
sort
()
>>>
items
>>>
items
[(
'a'
,
1
),
(
'b'
,
2
)]
[(
'a'
,
1
),
(
'b'
,
2
)]
...
@@ -106,7 +105,7 @@ the new underlying storages:
...
@@ -106,7 +105,7 @@ the new underlying storages:
The
object
id
of
the
new
object
is
quite
random
,
and
typically
large
:
The
object
id
of
the
new
object
is
quite
random
,
and
typically
large
:
>>>
print
u64
(
conn
.
root
()[
'2'
]
.
_p_oid
)
>>>
print
(
u64
(
conn
.
root
()[
'2'
]
.
_p_oid
)
)
3553260803050964942
3553260803050964942
Let
's look at some other methods:
Let
's look at some other methods:
...
@@ -201,7 +200,8 @@ DemoStorage supports Blobs if the changes database supports blobs.
...
@@ -201,7 +200,8 @@ DemoStorage supports Blobs if the changes database supports blobs.
>>> db = DB(base)
>>> db = DB(base)
>>> conn = db.open()
>>> conn = db.open()
>>> conn.root()['blob'] = ZODB.blob.Blob()
>>> conn.root()['blob'] = ZODB.blob.Blob()
>>> conn.root()['blob'].open('w').write('state 1')
>>> with conn.root()['blob'].open('w')
as
file
:
... _ = file.write(b'state 1')
>>> transaction.commit()
>>> transaction.commit()
>>> db.close()
>>> db.close()
...
@@ -216,7 +216,8 @@ DemoStorage supports Blobs if the changes database supports blobs.
...
@@ -216,7 +216,8 @@ DemoStorage supports Blobs if the changes database supports blobs.
>>> conn.root()['blob'].open().read()
>>> conn.root()['blob'].open().read()
'state 1'
'state 1'
>>> _ = transaction.begin()
>>> _ = transaction.begin()
>>> conn.root()['blob'].open('w').write('state 2')
>>> with conn.root()['blob'].open('w')
as
file
:
... _ = file.write(b'state 2')
>>> transaction.commit()
>>> transaction.commit()
>>> conn.root()['blob'].open().read()
>>> conn.root()['blob'].open().read()
'state 2'
'state 2'
...
@@ -238,7 +239,8 @@ It isn't necessary for the base database to support blobs.
...
@@ -238,7 +239,8 @@ It isn't necessary for the base database to support blobs.
>>> _ = transaction.begin()
>>> _ = transaction.begin()
>>> conn.root()['blob2'] = ZODB.blob.Blob()
>>> conn.root()['blob2'] = ZODB.blob.Blob()
>>> conn.root()['blob2'].open('w').write('state 1')
>>> with conn.root()['blob2'].open('w')
as
file
:
... _ = file.write(b'state 1')
>>> conn.root()['blob2'].open().read()
>>> conn.root()['blob2'].open().read()
'state 1'
'state 1'
...
@@ -263,7 +265,8 @@ storage wrapped around it when necessary:
...
@@ -263,7 +265,8 @@ storage wrapped around it when necessary:
'BlobStorage'
'BlobStorage'
>>> _ = transaction.begin()
>>> _ = transaction.begin()
>>> conn.root()['blob'].open('w').write('state 2')
>>> with conn.root()['blob'].open('w')
as
file
:
... _ = file.write(b'state 2')
>>> transaction.commit()
>>> transaction.commit()
>>> conn.root()['blob'].open().read()
>>> conn.root()['blob'].open().read()
'state 2'
'state 2'
...
@@ -358,7 +361,7 @@ To test this, we need to hack random.randint a bit.
...
@@ -358,7 +361,7 @@ To test this, we need to hack random.randint a bit.
>>> rv = 42
>>> rv = 42
>>> def faux_randint(min, max):
>>> def faux_randint(min, max):
... print
'called randint'
... print
('called randint')
... global rv
... global rv
... rv += 1000
... rv += 1000
... return rv
... return rv
...
...
src/ZODB/ExportImport.py
View file @
266cadf9
...
@@ -17,6 +17,7 @@ import os
...
@@ -17,6 +17,7 @@ import os
from
tempfile
import
TemporaryFile
from
tempfile
import
TemporaryFile
import
logging
import
logging
import
six
import
six
import
sys
from
ZODB.blob
import
Blob
from
ZODB.blob
import
Blob
from
ZODB.interfaces
import
IBlobStorage
from
ZODB.interfaces
import
IBlobStorage
...
...
src/ZODB/FileStorage/FileStorage.py
View file @
266cadf9
...
@@ -26,7 +26,7 @@ from ZODB.FileStorage.fspack import FileStoragePacker
...
@@ -26,7 +26,7 @@ from ZODB.FileStorage.fspack import FileStoragePacker
from
ZODB.fsIndex
import
fsIndex
from
ZODB.fsIndex
import
fsIndex
from
ZODB
import
BaseStorage
,
ConflictResolution
,
POSException
from
ZODB
import
BaseStorage
,
ConflictResolution
,
POSException
from
ZODB.POSException
import
UndoError
,
POSKeyError
,
MultipleUndoErrors
from
ZODB.POSException
import
UndoError
,
POSKeyError
,
MultipleUndoErrors
from
ZODB.utils
import
p64
,
u64
,
z64
,
as_bytes
,
as_text
,
bytes
from
ZODB.utils
import
p64
,
u64
,
z64
,
as_bytes
,
as_text
import
binascii
import
binascii
import
contextlib
import
contextlib
...
@@ -48,10 +48,10 @@ except ImportError:
...
@@ -48,10 +48,10 @@ except ImportError:
from
pickle
import
Pickler
,
loads
from
pickle
import
Pickler
,
loads
try
:
try
:
from
base64
import
decodestring
as
decodebytes
,
encodestring
as
decodebytes
except
ImportError
:
# Py3
# Py3
from
base64
import
decodebytes
,
encodebytes
from
base64
import
decodebytes
,
encodebytes
except
ImportError
:
from
base64
import
decodestring
as
decodebytes
,
encodestring
as
encodebytes
# Not all platforms have fsync
# Not all platforms have fsync
...
@@ -1901,7 +1901,7 @@ class TransactionRecordIterator(FileStorageFormatter):
...
@@ -1901,7 +1901,7 @@ class TransactionRecordIterator(FileStorageFormatter):
def
__iter__
(
self
):
def
__iter__
(
self
):
return
self
return
self
def
next
(
self
):
def
__next__
(
self
):
pos
=
self
.
_pos
pos
=
self
.
_pos
while
pos
<
self
.
_tend
:
while
pos
<
self
.
_tend
:
# Read the data records for this transaction
# Read the data records for this transaction
...
@@ -1934,6 +1934,8 @@ class TransactionRecordIterator(FileStorageFormatter):
...
@@ -1934,6 +1934,8 @@ class TransactionRecordIterator(FileStorageFormatter):
raise
StopIteration
()
raise
StopIteration
()
next
=
__next__
class
Record
(
BaseStorage
.
DataRecord
):
class
Record
(
BaseStorage
.
DataRecord
):
...
...
src/ZODB/FileStorage/tests.py
View file @
266cadf9
...
@@ -82,7 +82,7 @@ directory for blobs is kept.)
...
@@ -82,7 +82,7 @@ directory for blobs is kept.)
>>> conn = db.open()
>>> conn = db.open()
>>> conn.root()[1] = ZODB.blob.Blob()
>>> conn.root()[1] = ZODB.blob.Blob()
>>> with conn.root()[1].open('w') as file:
>>> with conn.root()[1].open('w') as file:
... file.write(b'some data')
...
_ =
file.write(b'some data')
>>> conn.root()[2] = ZODB.blob.Blob()
>>> conn.root()[2] = ZODB.blob.Blob()
>>> with conn.root()[2].open('w') as file:
>>> with conn.root()[2].open('w') as file:
... _ = file.write(b'some data')
... _ = file.write(b'some data')
...
...
src/ZODB/POSException.py
View file @
266cadf9
...
@@ -116,10 +116,7 @@ class ConflictError(POSError, transaction.interfaces.TransientError):
...
@@ -116,10 +116,7 @@ class ConflictError(POSError, transaction.interfaces.TransientError):
if
data
is
not
None
:
if
data
is
not
None
:
# avoid circular import chain
# avoid circular import chain
from
ZODB.utils
import
get_pickle_metadata
from
ZODB.utils
import
get_pickle_metadata
self
.
class_name
=
"%s.%s"
%
get_pickle_metadata
(
data
)
self
.
class_name
=
'.'
.
join
(
get_pickle_metadata
(
data
))
## else:
## if message != "data read conflict error":
## raise RuntimeError
self
.
serials
=
serials
self
.
serials
=
serials
...
...
src/ZODB/blob.py
View file @
266cadf9
...
@@ -359,13 +359,13 @@ class FilesystemHelper:
...
@@ -359,13 +359,13 @@ class FilesystemHelper:
log
(
"Blob temporary directory '%s' does not exist. "
log
(
"Blob temporary directory '%s' does not exist. "
"Created new directory."
%
self
.
temp_dir
)
"Created new directory."
%
self
.
temp_dir
)
if
not
os
.
path
.
exists
(
os
.
path
.
join
(
self
.
base_dir
,
LAYOUT_MARKER
)):
layout_marker_path
=
os
.
path
.
join
(
self
.
base_dir
,
LAYOUT_MARKER
)
layout_marker
=
open
(
if
not
os
.
path
.
exists
(
layout_marker_path
):
os
.
path
.
join
(
self
.
base_dir
,
LAYOUT_MARKER
),
'wb'
)
with
open
(
layout_marker_path
,
'w'
)
as
layout_marker
:
layout_marker
.
write
(
utils
.
as_bytes
(
self
.
layout_name
)
)
layout_marker
.
write
(
self
.
layout_name
)
else
:
else
:
layout
=
open
(
os
.
path
.
join
(
self
.
base_dir
,
LAYOUT_MARKER
),
'rb'
with
open
(
layout_marker_path
,
'r'
)
as
layout_marker
:
).
read
().
strip
()
layout
=
open
(
layout_marker_path
,
'r'
).
read
().
strip
()
if
layout
!=
self
.
layout_name
:
if
layout
!=
self
.
layout_name
:
raise
ValueError
(
raise
ValueError
(
"Directory layout `%s` selected for blob directory %s, but "
"Directory layout `%s` selected for blob directory %s, but "
...
@@ -517,7 +517,7 @@ def auto_layout_select(path):
...
@@ -517,7 +517,7 @@ def auto_layout_select(path):
# use.
# use.
layout_marker
=
os
.
path
.
join
(
path
,
LAYOUT_MARKER
)
layout_marker
=
os
.
path
.
join
(
path
,
LAYOUT_MARKER
)
if
os
.
path
.
exists
(
layout_marker
):
if
os
.
path
.
exists
(
layout_marker
):
layout
=
open
(
layout_marker
,
'r
b
'
).
read
()
layout
=
open
(
layout_marker
,
'r'
).
read
()
layout
=
layout
.
strip
()
layout
=
layout
.
strip
()
log
(
'Blob directory `%s` has layout marker set. '
log
(
'Blob directory `%s` has layout marker set. '
'Selected `%s` layout. '
%
(
path
,
layout
),
level
=
logging
.
DEBUG
)
'Selected `%s` layout. '
%
(
path
,
layout
),
level
=
logging
.
DEBUG
)
...
@@ -559,7 +559,8 @@ class BushyLayout(object):
...
@@ -559,7 +559,8 @@ class BushyLayout(object):
# Create the bushy directory structure with the least significant byte
# Create the bushy directory structure with the least significant byte
# first
# first
for
byte
in
oid
.
decode
():
for
byte
in
oid
.
decode
():
directories
.
append
(
'0x%s'
%
binascii
.
hexlify
(
byte
.
encode
()))
directories
.
append
(
'0x%s'
%
binascii
.
hexlify
(
byte
.
encode
()).
decode
())
return
os
.
path
.
sep
.
join
(
directories
)
return
os
.
path
.
sep
.
join
(
directories
)
def
path_to_oid
(
self
,
path
):
def
path_to_oid
(
self
,
path
):
...
@@ -568,7 +569,7 @@ class BushyLayout(object):
...
@@ -568,7 +569,7 @@ class BushyLayout(object):
path
=
path
.
split
(
os
.
path
.
sep
)
path
=
path
.
split
(
os
.
path
.
sep
)
# Each path segment stores a byte in hex representation. Turn it into
# Each path segment stores a byte in hex representation. Turn it into
# an int and then get the character for our byte string.
# an int and then get the character for our byte string.
oid
=
''
.
join
(
binascii
.
unhexlify
(
byte
[
2
:])
for
byte
in
path
)
oid
=
b
''
.
join
(
binascii
.
unhexlify
(
byte
[
2
:])
for
byte
in
path
)
return
oid
return
oid
def
getBlobFilePath
(
self
,
oid
,
tid
):
def
getBlobFilePath
(
self
,
oid
,
tid
):
...
@@ -599,7 +600,7 @@ class LawnLayout(BushyLayout):
...
@@ -599,7 +600,7 @@ class LawnLayout(BushyLayout):
# OID z64.
# OID z64.
raise
TypeError
()
raise
TypeError
()
return
utils
.
repr_to_oid
(
path
)
return
utils
.
repr_to_oid
(
path
)
except
TypeError
:
except
(
TypeError
,
binascii
.
Error
)
:
raise
ValueError
(
'Not a valid OID path: `%s`'
%
path
)
raise
ValueError
(
'Not a valid OID path: `%s`'
%
path
)
LAYOUTS
[
'lawn'
]
=
LawnLayout
()
LAYOUTS
[
'lawn'
]
=
LawnLayout
()
...
...
src/ZODB/fsrecover.py
View file @
266cadf9
...
@@ -215,7 +215,7 @@ def scan(f, pos):
...
@@ -215,7 +215,7 @@ def scan(f, pos):
s
=
0
s
=
0
while
1
:
while
1
:
l
=
data
.
find
(
"."
,
s
)
l
=
data
.
find
(
b
"."
,
s
)
if
l
<
0
:
if
l
<
0
:
pos
+=
len
(
data
)
pos
+=
len
(
data
)
break
break
...
...
src/ZODB/historical_connections.txt
View file @
266cadf9
...
@@ -64,7 +64,7 @@ historical state.
...
@@ -64,7 +64,7 @@ historical state.
>>> conn.root()['first']['count']
>>> conn.root()['first']['count']
1
1
>>>
historical_conn.root().keys(
)
>>>
sorted(historical_conn.root().keys()
)
['first']
['first']
>>> historical_conn.root()['first']['count']
>>> historical_conn.root()['first']['count']
0
0
...
@@ -96,7 +96,7 @@ commit.
...
@@ -96,7 +96,7 @@ commit.
>>> historical_conn = db.open(transaction_manager=transaction1,
>>> historical_conn = db.open(transaction_manager=transaction1,
... at=historical_serial)
... at=historical_serial)
>>>
historical_conn.root().keys(
)
>>>
sorted(historical_conn.root().keys()
)
['first']
['first']
>>> historical_conn.root()['first']['count']
>>> historical_conn.root()['first']['count']
0
0
...
@@ -110,7 +110,7 @@ root.
...
@@ -110,7 +110,7 @@ root.
>>> serial = conn.root()._p_serial
>>> serial = conn.root()._p_serial
>>> historical_conn = db.open(
>>> historical_conn = db.open(
... transaction_manager=transaction1, before=serial)
... transaction_manager=transaction1, before=serial)
>>>
historical_conn.root().keys(
)
>>>
sorted(historical_conn.root().keys()
)
['first']
['first']
>>> historical_conn.root()['first']['count']
>>> historical_conn.root()['first']['count']
0
0
...
@@ -120,7 +120,7 @@ underlying mechanism is a storage's loadBefore method. When you look at a
...
@@ -120,7 +120,7 @@ underlying mechanism is a storage's loadBefore method. When you look at a
connection's ``before`` attribute, it is normalized into a ``before`` serial,
connection's ``before`` attribute, it is normalized into a ``before`` serial,
no matter what you pass into ``db.open``.
no matter what you pass into ``db.open``.
>>> print
conn.before
>>> print
(conn.before)
None
None
>>> historical_conn.before == serial
>>> historical_conn.before == serial
True
True
...
...
src/ZODB/persistentclass.txt
View file @
266cadf9
...
@@ -26,12 +26,13 @@ Let's look at an example:
...
@@ -26,12 +26,13 @@ Let's look at an example:
... return self.name, self.kind
... return self.name, self.kind
>>> import ZODB.persistentclass
>>> import ZODB.persistentclass
>>> class C:
>>> C = ZODB.persistentclass.PersistentMetaClass(
... __metaclass__ = ZODB.persistentclass.PersistentMetaClass
... 'C', (object, ), dict(
... __init__ = __init__
... __init__ = __init__,
... __module__ = '__zodb__'
... __module__ = '__zodb__',
... foo = foo
... foo = foo,
... kind = 'sample'
... kind = 'sample',
... ))
This example is obviously a bit contrived. In particular, we defined
This example is obviously a bit contrived. In particular, we defined
the methods outside of the class. Why? Because all of the items in a
the methods outside of the class. Why? Because all of the items in a
...
@@ -65,8 +66,9 @@ We can create and use instances of the class:
...
@@ -65,8 +66,9 @@ We can create and use instances of the class:
We can modify the class and none of the persistent attributes will
We can modify the class and none of the persistent attributes will
change because the object hasn't been saved.
change because the object hasn't been saved.
>>> import six
>>> def bar(self):
>>> def bar(self):
...
print 'bar', self.name
...
six.print_('bar', self.name)
>>> C.bar = bar
>>> C.bar = bar
>>> c.bar()
>>> c.bar()
bar first
bar first
...
@@ -102,7 +104,7 @@ values:
...
@@ -102,7 +104,7 @@ values:
Now, if we modify the class:
Now, if we modify the class:
>>> def baz(self):
>>> def baz(self):
...
print 'baz', self.name
...
six.print_('baz', self.name)
>>> C.baz = baz
>>> C.baz = baz
>>> c.baz()
>>> c.baz()
baz first
baz first
...
...
src/ZODB/serialize.py
View file @
266cadf9
...
@@ -165,7 +165,7 @@ else:
...
@@ -165,7 +165,7 @@ else:
return
super
(
_Unpickler
,
self
).
find_class
(
modulename
,
name
)
return
super
(
_Unpickler
,
self
).
find_class
(
modulename
,
name
)
return
self
.
find_global
(
modulename
,
name
)
return
self
.
find_global
(
modulename
,
name
)
_oidtypes
=
str
,
type
(
None
)
_oidtypes
=
bytes
,
type
(
None
)
# Py3: Python 3 uses protocol 3 by default, which is not loadable by Python
# Py3: Python 3 uses protocol 3 by default, which is not loadable by Python
# 2. If we want this, we can add a condition here for Python 3.
# 2. If we want this, we can add a condition here for Python 3.
...
@@ -697,9 +697,15 @@ def get_refs(a_pickle):
...
@@ -697,9 +697,15 @@ def get_refs(a_pickle):
refs
=
[]
refs
=
[]
u
=
pickle
.
Unpickler
(
BytesIO
(
a_pickle
))
u
=
pickle
.
Unpickler
(
BytesIO
(
a_pickle
))
if
sys
.
version_info
[
0
]
<
3
:
u
.
persistent_load
=
refs
u
.
persistent_load
=
refs
u
.
noload
()
u
.
noload
()
u
.
noload
()
u
.
noload
()
else
:
# Py3: There is no `noload()` in Python 3.
u
.
persistent_load
=
refs
.
append
u
.
load
()
u
.
load
()
# Now we have a list of referencs. Need to convert to list of
# Now we have a list of referencs. Need to convert to list of
# oids and class info:
# oids and class info:
...
...
src/ZODB/tests/MinPO.py
View file @
266cadf9
...
@@ -15,7 +15,6 @@
...
@@ -15,7 +15,6 @@
import
functools
import
functools
from
persistent
import
Persistent
from
persistent
import
Persistent
@
functools
.
total_ordering
class
MinPO
(
Persistent
):
class
MinPO
(
Persistent
):
def
__init__
(
self
,
value
=
None
):
def
__init__
(
self
,
value
=
None
):
self
.
value
=
value
self
.
value
=
value
...
@@ -23,12 +22,18 @@ class MinPO(Persistent):
...
@@ -23,12 +22,18 @@ class MinPO(Persistent):
def
__cmp__
(
self
,
aMinPO
):
def
__cmp__
(
self
,
aMinPO
):
return
cmp
(
self
.
value
,
aMinPO
.
value
)
return
cmp
(
self
.
value
,
aMinPO
.
value
)
# Py3: Python 3 does not support cmp() anymore.
# Py3: Python 3 does not support cmp() anymore.
This is insane!!
def
__eq__
(
self
,
aMinPO
):
def
__eq__
(
self
,
aMinPO
):
return
self
.
value
==
aMinPO
.
value
return
self
.
value
==
aMinPO
.
value
def
__ne__
(
self
,
aMinPO
):
return
self
.
value
!=
aMinPO
.
value
def
__gt__
(
self
,
aMinPO
):
return
self
.
value
>
aMinPO
.
value
def
__lt__
(
self
,
aMinPO
):
def
__lt__
(
self
,
aMinPO
):
return
self
.
value
<
=
aMinPO
.
value
return
self
.
value
<
aMinPO
.
value
def
__repr__
(
self
):
def
__repr__
(
self
):
return
"MinPO(%s)"
%
self
.
value
return
"MinPO(%s)"
%
self
.
value
src/ZODB/tests/blob_basic.txt
View file @
266cadf9
...
@@ -34,7 +34,7 @@ We can open a new blob file for reading, but it won't have any data::
...
@@ -34,7 +34,7 @@ We can open a new blob file for reading, but it won't have any data::
But we can write data to a new Blob by opening it for writing::
But we can write data to a new Blob by opening it for writing::
>>> f = myblob.open("w")
>>> f = myblob.open("w")
>>>
f.write(
"Hi, Blob!")
>>>
_ = f.write(b
"Hi, Blob!")
If we try to open a Blob again while it is open for writing, we get an error::
If we try to open a Blob again while it is open for writing, we get an error::
...
@@ -77,7 +77,7 @@ Before we can write, we have to close the readers::
...
@@ -77,7 +77,7 @@ Before we can write, we have to close the readers::
Now we can open it for writing again and e.g. append data::
Now we can open it for writing again and e.g. append data::
>>> f4 = myblob.open("a")
>>> f4 = myblob.open("a")
>>>
f4.write(
"\nBlob is fine.")
>>>
_ = f4.write(b
"\nBlob is fine.")
We can't open a blob while it is open for writing:
We can't open a blob while it is open for writing:
...
@@ -122,7 +122,7 @@ We can read lines out of the blob too::
...
@@ -122,7 +122,7 @@ We can read lines out of the blob too::
We can seek to certain positions in a blob and read portions of it::
We can seek to certain positions in a blob and read portions of it::
>>> f6 = myblob.open('r')
>>> f6 = myblob.open('r')
>>> f6.seek(4)
>>>
_ =
f6.seek(4)
>>> int(f6.tell())
>>> int(f6.tell())
4
4
>>> f6.read(5)
>>> f6.read(5)
...
@@ -133,7 +133,7 @@ We can use the object returned by a blob open call as an iterable::
...
@@ -133,7 +133,7 @@ We can use the object returned by a blob open call as an iterable::
>>> f7 = myblob.open('r')
>>> f7 = myblob.open('r')
>>> for line in f7:
>>> for line in f7:
... print
line
... print
(line.decode())
Hi, Blob!
Hi, Blob!
<BLANKLINE>
<BLANKLINE>
Blob is fine.
Blob is fine.
...
@@ -142,7 +142,7 @@ We can use the object returned by a blob open call as an iterable::
...
@@ -142,7 +142,7 @@ We can use the object returned by a blob open call as an iterable::
We can truncate a blob::
We can truncate a blob::
>>> f8 = myblob.open('a')
>>> f8 = myblob.open('a')
>>> f8.truncate(0)
>>>
_ =
f8.truncate(0)
>>> f8.close()
>>> f8.close()
>>> f8 = myblob.open('r')
>>> f8 = myblob.open('r')
>>> f8.read()
>>> f8.read()
...
@@ -159,12 +159,13 @@ Blobs are always opened in binary mode::
...
@@ -159,12 +159,13 @@ Blobs are always opened in binary mode::
Blobs that have not been committed can be opened using any mode,
Blobs that have not been committed can be opened using any mode,
except for "c"::
except for "c"::
>>> import six
>>> from ZODB.blob import BlobError, valid_modes
>>> from ZODB.blob import BlobError, valid_modes
>>> for mode in valid_modes:
>>> for mode in valid_modes:
... try:
... try:
... f10 = Blob().open(mode)
... f10 = Blob().open(mode)
... except BlobError:
... except BlobError:
...
print 'open failed with mode "%s"' % mode
...
six.print_('open failed with mode "%s"' % mode)
... else:
... else:
... f10.close()
... f10.close()
open failed with mode "c"
open failed with mode "c"
...
@@ -192,6 +193,6 @@ Passing data to the blob constructor
...
@@ -192,6 +193,6 @@ Passing data to the blob constructor
If you have a small amount of data, you can pass it to the blob
If you have a small amount of data, you can pass it to the blob
constructor. (This is a convenience, mostly for writing tests.)
constructor. (This is a convenience, mostly for writing tests.)
>>> myblob = Blob('some data')
>>> myblob = Blob(
b
'some data')
>>> myblob.open().read()
>>> myblob.open().read()
'some data'
'some data'
src/ZODB/tests/blob_consume.txt
View file @
266cadf9
...
@@ -7,7 +7,7 @@ an O(1) operation we call `consume`::
...
@@ -7,7 +7,7 @@ an O(1) operation we call `consume`::
Let's create a file::
Let's create a file::
>>> to_import = open('to_import', 'wb')
>>> to_import = open('to_import', 'wb')
>>>
to_import.write(
"I'm a Blob and I feel fine.")
>>>
_ = to_import.write(b
"I'm a Blob and I feel fine.")
The file *must* be closed before giving it to consumeFile:
The file *must* be closed before giving it to consumeFile:
...
@@ -32,13 +32,14 @@ We now can call open on the blob and read and write the data::
...
@@ -32,13 +32,14 @@ We now can call open on the blob and read and write the data::
"I'm a Blob and I feel fine."
"I'm a Blob and I feel fine."
>>> blob_read.close()
>>> blob_read.close()
>>> blob_write = blob.open('w')
>>> blob_write = blob.open('w')
>>>
blob_write.write(
'I was changed.')
>>>
_ = blob_write.write(b
'I was changed.')
>>> blob_write.close()
>>> blob_write.close()
We can not consume a file when there is a reader or writer around for a blob
We can not consume a file when there is a reader or writer around for a blob
already::
already::
>>> open('to_import', 'wb').write('I am another blob.')
>>> with open('to_import', 'wb') as file:
... _ = file.write(b'I am another blob.')
>>> blob_read = blob.open('r')
>>> blob_read = blob.open('r')
>>> blob.consumeFile('to_import')
>>> blob.consumeFile('to_import')
Traceback (most recent call last):
Traceback (most recent call last):
...
@@ -68,12 +69,12 @@ fails. We simulate this in different states:
...
@@ -68,12 +69,12 @@ fails. We simulate this in different states:
Case 1: We don't have uncommitted data, but the link operation fails. We fall
Case 1: We don't have uncommitted data, but the link operation fails. We fall
back to try a copy/remove operation that is successfull::
back to try a copy/remove operation that is successfull::
>>> open('to_import', 'wb').write('Some data.')
>>> with open('to_import', 'wb') as file:
... _ = file.write(b'Some data.')
>>> def failing_rename(f1, f2):
>>> def failing_rename(f1, f2):
... import exceptions
... if f1 == 'to_import':
... if f1 == 'to_import':
... raise
exceptions.
OSError("I can't link.")
... raise OSError("I can't link.")
... os_rename(f1, f2)
... os_rename(f1, f2)
>>> blob = Blob()
>>> blob = Blob()
...
@@ -95,11 +96,11 @@ exist::
...
@@ -95,11 +96,11 @@ exist::
>>> utils_cp = ZODB.utils.cp
>>> utils_cp = ZODB.utils.cp
>>> def failing_copy(f1, f2):
>>> def failing_copy(f1, f2):
... import exceptions
... raise OSError("I can't copy.")
... raise exceptions.OSError("I can't copy.")
>>> ZODB.utils.cp = failing_copy
>>> ZODB.utils.cp = failing_copy
>>> open('to_import', 'wb').write('Some data.')
>>> with open('to_import', 'wb') as file:
... _ = file.write(b'Some data.')
>>> blob.consumeFile('to_import')
>>> blob.consumeFile('to_import')
Traceback (most recent call last):
Traceback (most recent call last):
OSError: I can't copy.
OSError: I can't copy.
...
@@ -115,7 +116,7 @@ previous uncomitted data::
...
@@ -115,7 +116,7 @@ previous uncomitted data::
>>> blob = Blob()
>>> blob = Blob()
>>> blob_writing = blob.open('w')
>>> blob_writing = blob.open('w')
>>>
blob_writing.write(
'Uncommitted data')
>>>
_ = blob_writing.write(b
'Uncommitted data')
>>> blob_writing.close()
>>> blob_writing.close()
>>> blob.consumeFile('to_import')
>>> blob.consumeFile('to_import')
...
...
src/ZODB/tests/blob_layout.txt
View file @
266cadf9
...
@@ -24,9 +24,9 @@ entries per directory level:
...
@@ -24,9 +24,9 @@ entries per directory level:
>>> from ZODB.blob import BushyLayout
>>> from ZODB.blob import BushyLayout
>>> bushy = BushyLayout()
>>> bushy = BushyLayout()
>>> bushy.oid_to_path('\x00\x00\x00\x00\x00\x00\x00\x00')
>>> bushy.oid_to_path(
b
'\x00\x00\x00\x00\x00\x00\x00\x00')
'0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x00'
'0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x00'
>>> bushy.oid_to_path('\x00\x00\x00\x00\x00\x00\x00\x01')
>>> bushy.oid_to_path(
b
'\x00\x00\x00\x00\x00\x00\x00\x01')
'0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x01'
'0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x01'
>>> import os
>>> import os
...
@@ -54,9 +54,9 @@ of blobs at the same time (e.g. 32k on ext3).
...
@@ -54,9 +54,9 @@ of blobs at the same time (e.g. 32k on ext3).
>>> from ZODB.blob import LawnLayout
>>> from ZODB.blob import LawnLayout
>>> lawn = LawnLayout()
>>> lawn = LawnLayout()
>>> lawn.oid_to_path('\x00\x00\x00\x00\x00\x00\x00\x00')
>>> lawn.oid_to_path(
b
'\x00\x00\x00\x00\x00\x00\x00\x00')
'0x00'
'0x00'
>>> lawn.oid_to_path('\x00\x00\x00\x00\x00\x00\x00\x01')
>>> lawn.oid_to_path(
b
'\x00\x00\x00\x00\x00\x00\x00\x01')
'0x01'
'0x01'
>>> lawn.path_to_oid('0x01')
>>> lawn.path_to_oid('0x01')
...
@@ -98,10 +98,12 @@ already been used to create a lawn structure.
...
@@ -98,10 +98,12 @@ already been used to create a lawn structure.
>>> from ZODB.blob import LAYOUT_MARKER
>>> from ZODB.blob import LAYOUT_MARKER
>>> import os.path
>>> import os.path
>>> open(os.path.join('blobs', LAYOUT_MARKER), 'wb').write('bushy')
>>> with open(os.path.join('blobs', LAYOUT_MARKER), 'wb') as file:
... _ = file.write(b'bushy')
>>> auto_layout_select('blobs')
>>> auto_layout_select('blobs')
'bushy'
'bushy'
>>> open(os.path.join('blobs', LAYOUT_MARKER), 'wb').write('lawn')
>>> with open(os.path.join('blobs', LAYOUT_MARKER), 'wb') as file:
... _ = file.write(b'lawn')
>>> auto_layout_select('blobs')
>>> auto_layout_select('blobs')
'lawn'
'lawn'
>>> shutil.rmtree('blobs')
>>> shutil.rmtree('blobs')
...
@@ -111,7 +113,8 @@ not hidden, we assume that it was created with an earlier version of
...
@@ -111,7 +113,8 @@ not hidden, we assume that it was created with an earlier version of
the blob implementation and uses our `lawn` layout:
the blob implementation and uses our `lawn` layout:
>>> os.mkdir('blobs')
>>> os.mkdir('blobs')
>>> open(os.path.join('blobs', '0x0101'), 'wb').write('foo')
>>> with open(os.path.join('blobs', '0x0101'), 'wb') as file:
... _ = file.write(b'foo')
>>> auto_layout_select('blobs')
>>> auto_layout_select('blobs')
'lawn'
'lawn'
>>> shutil.rmtree('blobs')
>>> shutil.rmtree('blobs')
...
@@ -119,7 +122,8 @@ the blob implementation and uses our `lawn` layout:
...
@@ -119,7 +122,8 @@ the blob implementation and uses our `lawn` layout:
5. If the directory contains only hidden files, use the bushy layout:
5. If the directory contains only hidden files, use the bushy layout:
>>> os.mkdir('blobs')
>>> os.mkdir('blobs')
>>> open(os.path.join('blobs', '.svn'), 'wb').write('blah')
>>> with open(os.path.join('blobs', '.svn'), 'wb') as file:
... _ = file.write(b'blah')
>>> auto_layout_select('blobs')
>>> auto_layout_select('blobs')
'bushy'
'bushy'
>>> shutil.rmtree('blobs')
>>> shutil.rmtree('blobs')
...
@@ -162,7 +166,8 @@ the marker will be used in the future:
...
@@ -162,7 +166,8 @@ the marker will be used in the future:
>>> base_storage = ZODB.FileStorage.FileStorage(datafs)
>>> base_storage = ZODB.FileStorage.FileStorage(datafs)
>>> os.mkdir(blobs)
>>> os.mkdir(blobs)
>>> open(os.path.join(blobs, 'foo'), 'wb').write('foo')
>>> with open(os.path.join(blobs, 'foo'), 'wb') as file:
... _ = file.write(b'foo')
>>> blob_storage = BlobStorage(blobs, base_storage)
>>> blob_storage = BlobStorage(blobs, base_storage)
>>> blob_storage.fshelper.layout_name
>>> blob_storage.fshelper.layout_name
'lawn'
'lawn'
...
@@ -202,12 +207,18 @@ Create a `lawn` directory structure and migrate it to the new `bushy` one:
...
@@ -202,12 +207,18 @@ Create a `lawn` directory structure and migrate it to the new `bushy` one:
>>> blob1 = old_fsh.getPathForOID(7039, create=True)
>>> blob1 = old_fsh.getPathForOID(7039, create=True)
>>> blob2 = old_fsh.getPathForOID(10, create=True)
>>> blob2 = old_fsh.getPathForOID(10, create=True)
>>> blob3 = old_fsh.getPathForOID(7034, create=True)
>>> blob3 = old_fsh.getPathForOID(7034, create=True)
>>> open(os.path.join(blob1, 'foo'), 'wb').write('foo')
>>> with open(os.path.join(blob1, 'foo'), 'wb') as file:
>>> open(os.path.join(blob1, 'foo2'), 'wb').write('bar')
... _ = file.write(b'foo')
>>> open(os.path.join(blob2, 'foo3'), 'wb').write('baz')
>>> with open(os.path.join(blob1, 'foo2'), 'wb') as file:
>>> open(os.path.join(blob2, 'foo4'), 'wb').write('qux')
... _ = file.write(b'bar')
>>> open(os.path.join(blob3, 'foo5'), 'wb').write('quux')
>>> with open(os.path.join(blob2, 'foo3'), 'wb') as file:
>>> open(os.path.join(blob3, 'foo6'), 'wb').write('corge')
... _ = file.write(b'baz')
>>> with open(os.path.join(blob2, 'foo4'), 'wb') as file:
... _ = file.write(b'qux')
>>> with open(os.path.join(blob3, 'foo5'), 'wb') as file:
... _ = file.write(b'quux')
>>> with open(os.path.join(blob3, 'foo6'), 'wb') as file:
... _ = file.write(b'corge')
Committed blobs have their permissions set to 000
Committed blobs have their permissions set to 000
...
@@ -237,16 +248,17 @@ with the same sizes and permissions:
...
@@ -237,16 +248,17 @@ with the same sizes and permissions:
>>> len(lawn_files) == len(bushy_files)
>>> len(lawn_files) == len(bushy_files)
True
True
>>> import six
>>> for file_name, lawn_path in sorted(lawn_files.items()):
>>> for file_name, lawn_path in sorted(lawn_files.items()):
... if file_name == '.layout':
... if file_name == '.layout':
... continue
... continue
... lawn_stat = os.stat(lawn_path)
... lawn_stat = os.stat(lawn_path)
... bushy_path = bushy_files[file_name]
... bushy_path = bushy_files[file_name]
... bushy_stat = os.stat(bushy_path)
... bushy_stat = os.stat(bushy_path)
...
print lawn_path, '-->', bushy_path
...
six.print_(lawn_path, '-->', bushy_path)
... if ((lawn_stat.st_mode, lawn_stat.st_size) !=
... if ((lawn_stat.st_mode, lawn_stat.st_size) !=
... (bushy_stat.st_mode, bushy_stat.st_size)):
... (bushy_stat.st_mode, bushy_stat.st_size)):
... print
'oops'
... print
('oops')
old/0x1b7f/foo --> bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo
old/0x1b7f/foo --> bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo
old/0x1b7f/foo2 --> bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo2
old/0x1b7f/foo2 --> bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo2
old/0x0a/foo3 --> bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x0a/foo3
old/0x0a/foo3 --> bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x0a/foo3
...
@@ -277,10 +289,10 @@ True
...
@@ -277,10 +289,10 @@ True
... lawn_stat = os.stat(lawn_path)
... lawn_stat = os.stat(lawn_path)
... bushy_path = bushy_files[file_name]
... bushy_path = bushy_files[file_name]
... bushy_stat = os.stat(bushy_path)
... bushy_stat = os.stat(bushy_path)
...
print bushy_path, '-->', lawn_path
...
six.print_(bushy_path, '-->', lawn_path)
... if ((lawn_stat.st_mode, lawn_stat.st_size) !=
... if ((lawn_stat.st_mode, lawn_stat.st_size) !=
... (bushy_stat.st_mode, bushy_stat.st_size)):
... (bushy_stat.st_mode, bushy_stat.st_size)):
... print
'oops'
... print
('oops')
bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo --> lawn/0x1b7f/foo
bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo --> lawn/0x1b7f/foo
bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo2 --> lawn/0x1b7f/foo2
bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x1b/0x7f/foo2 --> lawn/0x1b7f/foo2
bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x0a/foo3 --> lawn/0x0a/foo3
bushy/0x00/0x00/0x00/0x00/0x00/0x00/0x00/0x0a/foo3 --> lawn/0x0a/foo3
...
...
src/ZODB/tests/blobstorage_packing.txt
View file @
266cadf9
...
@@ -57,32 +57,37 @@ Put some revisions of a blob object in our database and on the filesystem:
...
@@ -57,32 +57,37 @@ Put some revisions of a blob object in our database and on the filesystem:
>>> nothing = transaction.begin()
>>> nothing = transaction.begin()
>>> times.append(new_time())
>>> times.append(new_time())
>>> blob = Blob()
>>> blob = Blob()
>>> blob.open('w').write('this is blob data 0')
>>> with blob.open('w') as file:
... _ = file.write(b'this is blob data 0')
>>> root['blob'] = blob
>>> root['blob'] = blob
>>> transaction.commit()
>>> transaction.commit()
>>> tids.append(blob_storage._tid)
>>> tids.append(blob_storage._tid)
>>> nothing = transaction.begin()
>>> nothing = transaction.begin()
>>> times.append(new_time())
>>> times.append(new_time())
>>> root['blob'].open('w').write('this is blob data 1')
>>> with root['blob'].open('w') as file:
... _ = file.write(b'this is blob data 1')
>>> transaction.commit()
>>> transaction.commit()
>>> tids.append(blob_storage._tid)
>>> tids.append(blob_storage._tid)
>>> nothing = transaction.begin()
>>> nothing = transaction.begin()
>>> times.append(new_time())
>>> times.append(new_time())
>>> root['blob'].open('w').write('this is blob data 2')
>>> with root['blob'].open('w') as file:
... _ = file.write(b'this is blob data 2')
>>> transaction.commit()
>>> transaction.commit()
>>> tids.append(blob_storage._tid)
>>> tids.append(blob_storage._tid)
>>> nothing = transaction.begin()
>>> nothing = transaction.begin()
>>> times.append(new_time())
>>> times.append(new_time())
>>> root['blob'].open('w').write('this is blob data 3')
>>> with root['blob'].open('w') as file:
... _ = file.write(b'this is blob data 3')
>>> transaction.commit()
>>> transaction.commit()
>>> tids.append(blob_storage._tid)
>>> tids.append(blob_storage._tid)
>>> nothing = transaction.begin()
>>> nothing = transaction.begin()
>>> times.append(new_time())
>>> times.append(new_time())
>>> root['blob'].open('w').write('this is blob data 4')
>>> with root['blob'].open('w') as file:
... _ = file.write(b'this is blob data 4')
>>> transaction.commit()
>>> transaction.commit()
>>> tids.append(blob_storage._tid)
>>> tids.append(blob_storage._tid)
...
@@ -142,9 +147,11 @@ is reset:
...
@@ -142,9 +147,11 @@ is reset:
We can also see, that the flag is set during the pack, by leveraging the
We can also see, that the flag is set during the pack, by leveraging the
knowledge that the underlying storage's pack method is also called:
knowledge that the underlying storage's pack method is also called:
>>> import six
>>> def dummy_pack(time, ref):
>>> def dummy_pack(time, ref):
... print "_blobs_pack_is_in_progress =",
... six.print_(
... print blob_storage._blobs_pack_is_in_progress
... "_blobs_pack_is_in_progress =",
... blob_storage._blobs_pack_is_in_progress)
... return base_pack(time, ref)
... return base_pack(time, ref)
>>> base_pack = base_storage.pack
>>> base_pack = base_storage.pack
>>> base_storage.pack = dummy_pack
>>> base_storage.pack = dummy_pack
...
...
src/ZODB/tests/dbopen.txt
View file @
266cadf9
...
@@ -30,7 +30,8 @@ Open one more, and we get a warning:
...
@@ -30,7 +30,8 @@ Open one more, and we get a warning:
>>> len(handler.records)
>>> len(handler.records)
1
1
>>> msg = handler.records[0]
>>> msg = handler.records[0]
>>> print msg.name, msg.levelname, msg.getMessage()
>>> import six
>>> six.print_(msg.name, msg.levelname, msg.getMessage())
ZODB.DB WARNING DB.open() has 8 open connections with a pool_size of 7
ZODB.DB WARNING DB.open() has 8 open connections with a pool_size of 7
Open 6 more, and we get 6 more warnings:
Open 6 more, and we get 6 more warnings:
...
@@ -41,7 +42,7 @@ Open 6 more, and we get 6 more warnings:
...
@@ -41,7 +42,7 @@ Open 6 more, and we get 6 more warnings:
>>> len(handler.records)
>>> len(handler.records)
7
7
>>> msg = handler.records[-1]
>>> msg = handler.records[-1]
>>>
print msg.name, msg.levelname, msg.getMessage(
)
>>>
six.print_(msg.name, msg.levelname, msg.getMessage()
)
ZODB.DB WARNING DB.open() has 14 open connections with a pool_size of 7
ZODB.DB WARNING DB.open() has 14 open connections with a pool_size of 7
Add another, so that it's more than twice the default, and the level
Add another, so that it's more than twice the default, and the level
...
@@ -53,7 +54,7 @@ rises to critical:
...
@@ -53,7 +54,7 @@ rises to critical:
>>> len(handler.records)
>>> len(handler.records)
8
8
>>> msg = handler.records[-1]
>>> msg = handler.records[-1]
>>>
print msg.name, msg.levelname, msg.getMessage(
)
>>>
six.print_(msg.name, msg.levelname, msg.getMessage()
)
ZODB.DB CRITICAL DB.open() has 15 open connections with a pool_size of 7
ZODB.DB CRITICAL DB.open() has 15 open connections with a pool_size of 7
While it's boring, it's important to verify that the same relationships
While it's boring, it's important to verify that the same relationships
...
@@ -74,7 +75,7 @@ A warning for opening one more:
...
@@ -74,7 +75,7 @@ A warning for opening one more:
>>> len(handler.records)
>>> len(handler.records)
1
1
>>> msg = handler.records[0]
>>> msg = handler.records[0]
>>>
print msg.name, msg.levelname, msg.getMessage(
)
>>>
six.print_(msg.name, msg.levelname, msg.getMessage()
)
ZODB.DB WARNING DB.open() has 3 open connections with a pool_size of 2
ZODB.DB WARNING DB.open() has 3 open connections with a pool_size of 2
More warnings through 4 connections:
More warnings through 4 connections:
...
@@ -85,7 +86,7 @@ More warnings through 4 connections:
...
@@ -85,7 +86,7 @@ More warnings through 4 connections:
>>> len(handler.records)
>>> len(handler.records)
2
2
>>> msg = handler.records[-1]
>>> msg = handler.records[-1]
>>>
print msg.name, msg.levelname, msg.getMessage(
)
>>>
six.print_(msg.name, msg.levelname, msg.getMessage()
)
ZODB.DB WARNING DB.open() has 4 open connections with a pool_size of 2
ZODB.DB WARNING DB.open() has 4 open connections with a pool_size of 2
And critical for going beyond that:
And critical for going beyond that:
...
@@ -96,7 +97,7 @@ And critical for going beyond that:
...
@@ -96,7 +97,7 @@ And critical for going beyond that:
>>> len(handler.records)
>>> len(handler.records)
3
3
>>> msg = handler.records[-1]
>>> msg = handler.records[-1]
>>>
print msg.name, msg.levelname, msg.getMessage(
)
>>>
six.print_(msg.name, msg.levelname, msg.getMessage()
)
ZODB.DB CRITICAL DB.open() has 5 open connections with a pool_size of 2
ZODB.DB CRITICAL DB.open() has 5 open connections with a pool_size of 2
We can change the pool size on the fly:
We can change the pool size on the fly:
...
@@ -110,7 +111,7 @@ We can change the pool size on the fly:
...
@@ -110,7 +111,7 @@ We can change the pool size on the fly:
>>> len(handler.records)
>>> len(handler.records)
1
1
>>> msg = handler.records[0]
>>> msg = handler.records[0]
>>>
print msg.name, msg.levelname, msg.getMessage(
)
>>>
six.print_(msg.name, msg.levelname, msg.getMessage()
)
ZODB.DB WARNING DB.open() has 7 open connections with a pool_size of 6
ZODB.DB WARNING DB.open() has 7 open connections with a pool_size of 6
Enough of that.
Enough of that.
...
...
src/ZODB/tests/multidb.txt
View file @
266cadf9
...
@@ -63,7 +63,7 @@ entries:
...
@@ -63,7 +63,7 @@ entries:
True
True
>>> len(db2.databases)
>>> len(db2.databases)
2
2
>>> names =
dbmap.keys(); names.sort(); print names
>>> names =
sorted(dbmap.keys()); print(names)
['notroot', 'root']
['notroot', 'root']
It's an error to try to insert a database with a name already in use:
It's an error to try to insert a database with a name already in use:
...
@@ -112,7 +112,7 @@ Now there are two connections in that collection:
...
@@ -112,7 +112,7 @@ Now there are two connections in that collection:
True
True
>>> len(cn2.connections)
>>> len(cn2.connections)
2
2
>>> names =
cn.connections.keys(); names.sort(); print names
>>> names =
sorted(cn.connections.keys()); print(names)
['notroot', 'root']
['notroot', 'root']
So long as this database group remains open, the same ``Connection`` objects
So long as this database group remains open, the same ``Connection`` objects
...
@@ -155,9 +155,9 @@ ZODB 3.6:
...
@@ -155,9 +155,9 @@ ZODB 3.6:
... </zodb>
... </zodb>
... """
... """
>>> db = databaseFromString(config)
>>> db = databaseFromString(config)
>>> print
db.database_name
>>> print
(db.database_name)
this_is_the_name
this_is_the_name
>>>
db.databases.keys(
)
>>>
sorted(db.databases.keys()
)
['this_is_the_name']
['this_is_the_name']
However, the ``.databases`` attribute cannot be configured from file. It
However, the ``.databases`` attribute cannot be configured from file. It
...
@@ -166,7 +166,12 @@ to test that here; this is ugly:
...
@@ -166,7 +166,12 @@ to test that here; this is ugly:
>>> from ZODB.config import getDbSchema
>>> from ZODB.config import getDbSchema
>>> import ZConfig
>>> import ZConfig
>>> from cStringIO import StringIO
>>> try:
... from cStringIO import StringIO
... except ImportError:
... # Py3
... from io import StringIO
Derive a new `config2` string from the `config` string, specifying a
Derive a new `config2` string from the `config` string, specifying a
different database_name:
different database_name:
...
@@ -182,12 +187,11 @@ Now get a `ZConfig` factory from `config2`:
...
@@ -182,12 +187,11 @@ Now get a `ZConfig` factory from `config2`:
The desired ``databases`` mapping can be passed to this factory:
The desired ``databases`` mapping can be passed to this factory:
>>> db2 = factory[0].open(databases=db.databases)
>>> db2 = factory[0].open(databases=db.databases)
>>> print
db2.database_name
# has the right name
>>> print
(db2.database_name)
# has the right name
another_name
another_name
>>> db.databases is db2.databases # shares .databases with `db`
>>> db.databases is db2.databases # shares .databases with `db`
True
True
>>> all = db2.databases.keys()
>>> all = sorted(db2.databases.keys())
>>> all.sort()
>>> all # and db.database_name & db2.database_name are the keys
>>> all # and db.database_name & db2.database_name are the keys
['another_name', 'this_is_the_name']
['another_name', 'this_is_the_name']
...
...
src/ZODB/tests/testBroken.py
View file @
266cadf9
...
@@ -23,7 +23,7 @@ if os.environ.get('USE_ZOPE_TESTING_DOCTEST'):
...
@@ -23,7 +23,7 @@ if os.environ.get('USE_ZOPE_TESTING_DOCTEST'):
from
zope.testing.doctest
import
DocTestSuite
from
zope.testing.doctest
import
DocTestSuite
else
:
else
:
from
doctest
import
DocTestSuite
from
doctest
import
DocTestSuite
from
ZODB.tests.util
import
DB
from
ZODB.tests.util
import
DB
,
checker
def
test_integration
():
def
test_integration
():
r"""Test the integration of broken object support with the databse:
r"""Test the integration of broken object support with the databse:
...
@@ -92,8 +92,8 @@ def test_integration():
...
@@ -92,8 +92,8 @@ def test_integration():
def
test_suite
():
def
test_suite
():
return
unittest
.
TestSuite
((
return
unittest
.
TestSuite
((
DocTestSuite
(
'ZODB.broken'
),
DocTestSuite
(
'ZODB.broken'
,
checker
=
checker
),
DocTestSuite
(),
DocTestSuite
(
checker
=
checker
),
))
))
if
__name__
==
'__main__'
:
unittest
.
main
()
if
__name__
==
'__main__'
:
unittest
.
main
()
src/ZODB/tests/testCache.py
View file @
266cadf9
...
@@ -33,6 +33,8 @@ import ZODB
...
@@ -33,6 +33,8 @@ import ZODB
import
ZODB.MappingStorage
import
ZODB.MappingStorage
import
ZODB.tests.util
import
ZODB.tests.util
PY2
=
sys
.
version_info
[
0
]
==
2
class
CacheTestBase
(
ZODB
.
tests
.
util
.
TestCase
):
class
CacheTestBase
(
ZODB
.
tests
.
util
.
TestCase
):
def
setUp
(
self
):
def
setUp
(
self
):
...
@@ -96,8 +98,8 @@ class DBMethods(CacheTestBase):
...
@@ -96,8 +98,8 @@ class DBMethods(CacheTestBase):
def
checkCacheDetail
(
self
):
def
checkCacheDetail
(
self
):
for
name
,
count
in
self
.
db
.
cacheDetail
():
for
name
,
count
in
self
.
db
.
cacheDetail
():
self
.
assert
_
(
isinstance
(
name
,
bytes
)
)
self
.
assert
Equal
(
isinstance
(
name
,
str
),
True
)
self
.
assert
_
(
isinstance
(
count
,
int
)
)
self
.
assert
Equal
(
isinstance
(
count
,
int
),
True
)
def
checkCacheExtremeDetail
(
self
):
def
checkCacheExtremeDetail
(
self
):
expected
=
[
'conn_no'
,
'id'
,
'oid'
,
'rc'
,
'klass'
,
'state'
]
expected
=
[
'conn_no'
,
'id'
,
'oid'
,
'rc'
,
'klass'
,
'state'
]
...
@@ -435,17 +437,19 @@ The cache is empty initially:
...
@@ -435,17 +437,19 @@ The cache is empty initially:
We force the root to be loaded and the cache grows:
We force the root to be loaded and the cache grows:
Py3: XXX: This needs more investigation in Connection.
>>> getattr(conn.root, 'z', None)
>>> getattr(conn.root, 'z', None)
>>> conn._cache.total_estimated_size
>>> conn._cache.total_estimated_size
== (64 if PY2 else 128)
64
True
We add some data and the cache grows:
We add some data and the cache grows:
>>> conn.root.z = ZODB.tests.util.P('x'*100)
>>> conn.root.z = ZODB.tests.util.P('x'*100)
>>> import transaction
>>> import transaction
>>> transaction.commit()
>>> transaction.commit()
>>> conn._cache.total_estimated_size
>>> conn._cache.total_estimated_size
== (320 if PY2 else 320+64)
320
True
Loading the objects in another connection gets the same sizes:
Loading the objects in another connection gets the same sizes:
...
@@ -453,11 +457,11 @@ Loading the objects in another connection gets the same sizes:
...
@@ -453,11 +457,11 @@ Loading the objects in another connection gets the same sizes:
>>> conn2._cache.total_estimated_size
>>> conn2._cache.total_estimated_size
0
0
>>> getattr(conn2.root, 'x', None)
>>> getattr(conn2.root, 'x', None)
>>> conn
2._cache.total_estimated_size
>>> conn
._cache.total_estimated_size == (64 if PY2 else 128)
128
True
>>> _ = conn2.root.z.name
>>> _ = conn2.root.z.name
>>> conn
2._cache.total_estimated_size
>>> conn
._cache.total_estimated_size == (320 if PY2 else 320+64)
320
True
If we deactivate, the size goes down:
If we deactivate, the size goes down:
...
...
src/ZODB/tests/testConfig.py
View file @
266cadf9
...
@@ -186,7 +186,9 @@ def multi_atabases():
...
@@ -186,7 +186,9 @@ def multi_atabases():
def
test_suite
():
def
test_suite
():
suite
=
unittest
.
TestSuite
()
suite
=
unittest
.
TestSuite
()
suite
.
addTest
(
doctest
.
DocTestSuite
(
suite
.
addTest
(
doctest
.
DocTestSuite
(
setUp
=
ZODB
.
tests
.
util
.
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
))
setUp
=
ZODB
.
tests
.
util
.
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
checker
=
ZODB
.
tests
.
util
.
checker
))
suite
.
addTest
(
unittest
.
makeSuite
(
ZODBConfigTest
))
suite
.
addTest
(
unittest
.
makeSuite
(
ZODBConfigTest
))
return
suite
return
suite
...
...
src/ZODB/tests/testDB.py
View file @
266cadf9
...
@@ -15,12 +15,23 @@
...
@@ -15,12 +15,23 @@
from
ZODB.tests.MinPO
import
MinPO
from
ZODB.tests.MinPO
import
MinPO
import
doctest
import
doctest
import
os
import
os
import
re
import
sys
import
sys
import
time
import
time
import
transaction
import
transaction
import
unittest
import
unittest
import
ZODB
import
ZODB
import
ZODB.tests.util
import
ZODB.tests.util
from
zope.testing
import
renormalizing
checker
=
renormalizing
.
RENormalizing
([
# Python 3 bytes add a "b".
(
re
.
compile
(
"b('.*?')"
),
r"\1"
),
# Python 3 adds module name to exceptions.
(
re
.
compile
(
"ZODB.POSException.ReadConflictError"
),
r"ReadConflictError"
),
])
# Return total number of connections across all pools in a db._pools.
# Return total number of connections across all pools in a db._pools.
def
nconn
(
pools
):
def
nconn
(
pools
):
...
@@ -196,7 +207,7 @@ def open_convenience():
...
@@ -196,7 +207,7 @@ def open_convenience():
DB arguments.
DB arguments.
>>> conn = ZODB.connection('data.fs', blob_dir='blobs')
>>> conn = ZODB.connection('data.fs', blob_dir='blobs')
>>> conn.root()['b'] = ZODB.blob.Blob('test')
>>> conn.root()['b'] = ZODB.blob.Blob(
b
'test')
>>> transaction.commit()
>>> transaction.commit()
>>> conn.close()
>>> conn.close()
...
@@ -348,5 +359,6 @@ def test_suite():
...
@@ -348,5 +359,6 @@ def test_suite():
s
=
unittest
.
makeSuite
(
DBTests
)
s
=
unittest
.
makeSuite
(
DBTests
)
s
.
addTest
(
doctest
.
DocTestSuite
(
s
.
addTest
(
doctest
.
DocTestSuite
(
setUp
=
ZODB
.
tests
.
util
.
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
setUp
=
ZODB
.
tests
.
util
.
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
checker
=
checker
))
))
return
s
return
s
src/ZODB/tests/testDemoStorage.py
View file @
266cadf9
...
@@ -38,11 +38,6 @@ import ZODB.tests.util
...
@@ -38,11 +38,6 @@ import ZODB.tests.util
import
ZODB.utils
import
ZODB.utils
from
zope.testing
import
renormalizing
from
zope.testing
import
renormalizing
checker
=
renormalizing
.
RENormalizing
([
# Python 3 adds module name to exceptions.
(
re
.
compile
(
"ZODB.POSException.POSKeyError"
),
r"POSKeyError"
),
])
class
DemoStorageTests
(
class
DemoStorageTests
(
StorageTestBase
.
StorageTestBase
,
StorageTestBase
.
StorageTestBase
,
...
@@ -251,11 +246,14 @@ def load_before_base_storage_current():
...
@@ -251,11 +246,14 @@ def load_before_base_storage_current():
def
test_suite
():
def
test_suite
():
suite
=
unittest
.
TestSuite
((
suite
=
unittest
.
TestSuite
((
doctest
.
DocTestSuite
(
doctest
.
DocTestSuite
(
setUp
=
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
checker
=
checker
setUp
=
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
checker
=
ZODB
.
tests
.
util
.
checker
),
),
doctest
.
DocFileSuite
(
doctest
.
DocFileSuite
(
'../DemoStorage.test'
,
'../DemoStorage.test'
,
setUp
=
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
setUp
=
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
checker
=
ZODB
.
tests
.
util
.
checker
,
),
),
))
))
suite
.
addTest
(
unittest
.
makeSuite
(
DemoStorageTests
,
'check'
))
suite
.
addTest
(
unittest
.
makeSuite
(
DemoStorageTests
,
'check'
))
...
...
src/ZODB/tests/testMVCCMappingStorage.py
View file @
266cadf9
...
@@ -160,13 +160,13 @@ class MVCCMappingStorageTests(
...
@@ -160,13 +160,13 @@ class MVCCMappingStorageTests(
# Add a fake transaction
# Add a fake transaction
transactions
=
self
.
_storage
.
_transactions
transactions
=
self
.
_storage
.
_transactions
self
.
assertEqual
(
1
,
len
(
transactions
))
self
.
assertEqual
(
1
,
len
(
transactions
))
fake_timestamp
=
'zzzzzzzy'
# the year 5735 ;-)
fake_timestamp
=
b
'zzzzzzzy'
# the year 5735 ;-)
transactions
[
fake_timestamp
]
=
transactions
.
values
()[
0
]
transactions
[
fake_timestamp
]
=
transactions
.
values
()[
0
]
# Verify the next transaction comes after the fake transaction
# Verify the next transaction comes after the fake transaction
t
=
transaction
.
Transaction
()
t
=
transaction
.
Transaction
()
self
.
_storage
.
tpc_begin
(
t
)
self
.
_storage
.
tpc_begin
(
t
)
self
.
assertEqual
(
self
.
_storage
.
_tid
,
'zzzzzzzz'
)
self
.
assertEqual
(
self
.
_storage
.
_tid
,
b
'zzzzzzzz'
)
def
create_blob_storage
(
name
,
blob_dir
):
def
create_blob_storage
(
name
,
blob_dir
):
s
=
MVCCMappingStorage
(
name
)
s
=
MVCCMappingStorage
(
name
)
...
...
src/ZODB/tests/testPersistentList.py
View file @
266cadf9
...
@@ -13,10 +13,12 @@
...
@@ -13,10 +13,12 @@
##############################################################################
##############################################################################
"""Test the list interface to PersistentList
"""Test the list interface to PersistentList
"""
"""
import
sys
import
unittest
import
unittest
from
persistent.list
import
PersistentList
from
persistent.list
import
PersistentList
PY2
=
sys
.
version_info
[
0
]
==
2
l0
=
[]
l0
=
[]
l1
=
[
0
]
l1
=
[
0
]
l2
=
[
0
,
1
]
l2
=
[
0
,
1
]
...
@@ -54,6 +56,8 @@ class TestPList(unittest.TestCase):
...
@@ -54,6 +56,8 @@ class TestPList(unittest.TestCase):
# Test __cmp__ and __len__
# Test __cmp__ and __len__
# Py3: No cmp() or __cmp__ anymore.
if
PY2
:
def
mycmp
(
a
,
b
):
def
mycmp
(
a
,
b
):
r
=
cmp
(
a
,
b
)
r
=
cmp
(
a
,
b
)
if
r
<
0
:
return
-
1
if
r
<
0
:
return
-
1
...
...
src/ZODB/tests/testPersistentMapping.py
View file @
266cadf9
...
@@ -40,6 +40,7 @@ except ImportError:
...
@@ -40,6 +40,7 @@ except ImportError:
# Py3
# Py3
import
io
as
cStringIO
import
io
as
cStringIO
PY2
=
sys
.
version_info
[
0
]
==
2
# This pickle contains a persistent mapping pickle created from the
# This pickle contains a persistent mapping pickle created from the
# old code.
# old code.
...
@@ -124,31 +125,26 @@ class PMTests(unittest.TestCase):
...
@@ -124,31 +125,26 @@ class PMTests(unittest.TestCase):
self
.
assertEqual
(
m
.
get
(
'fred'
),
None
)
self
.
assertEqual
(
m
.
get
(
'fred'
),
None
)
self
.
assertEqual
(
m
.
get
(
'fred'
,
42
),
42
)
self
.
assertEqual
(
m
.
get
(
'fred'
,
42
),
42
)
keys
=
m
.
keys
()
keys
=
sorted
(
m
.
keys
())
keys
.
sort
()
self
.
assertEqual
(
keys
,
[
'a'
,
'b'
,
'name'
,
'x'
])
self
.
assertEqual
(
keys
,
[
'a'
,
'b'
,
'name'
,
'x'
])
values
=
m
.
values
()
values
=
set
(
m
.
values
())
values
.
sort
()
self
.
assertEqual
(
values
,
set
([
1
,
2
,
3
,
'bob'
]))
self
.
assertEqual
(
values
,
[
1
,
2
,
3
,
'bob'
])
items
=
m
.
items
()
items
=
sorted
(
m
.
items
())
items
.
sort
()
self
.
assertEqual
(
items
,
self
.
assertEqual
(
items
,
[(
'a'
,
2
),
(
'b'
,
3
),
(
'name'
,
'bob'
),
(
'x'
,
1
)])
[(
'a'
,
2
),
(
'b'
,
3
),
(
'name'
,
'bob'
),
(
'x'
,
1
)])
keys
=
list
(
m
.
iterkeys
())
if
PY2
:
keys
.
sort
(
)
keys
=
sorted
(
m
.
iterkeys
()
)
self
.
assertEqual
(
keys
,
[
'a'
,
'b'
,
'name'
,
'x'
])
self
.
assertEqual
(
keys
,
[
'a'
,
'b'
,
'name'
,
'x'
])
values
=
list
(
m
.
itervalues
())
values
=
sorted
(
m
.
itervalues
())
values
.
sort
()
self
.
assertEqual
(
values
,
[
1
,
2
,
3
,
'bob'
])
self
.
assertEqual
(
values
,
[
1
,
2
,
3
,
'bob'
])
items
=
list
(
m
.
iteritems
())
items
=
sorted
(
m
.
iteritems
())
items
.
sort
()
self
.
assertEqual
(
self
.
assertEqual
(
items
,
items
,
[(
'a'
,
2
),
(
'b'
,
3
),
(
'name'
,
'bob'
),
(
'x'
,
1
)])
[(
'a'
,
2
),
(
'b'
,
3
),
(
'name'
,
'bob'
),
(
'x'
,
1
)])
# PersistentMapping didn't have an __iter__ method before ZODB 3.4.2.
# PersistentMapping didn't have an __iter__ method before ZODB 3.4.2.
# Check that it plays well now with the Python iteration protocol.
# Check that it plays well now with the Python iteration protocol.
...
...
src/ZODB/tests/testPersistentWeakref.py
View file @
266cadf9
...
@@ -36,7 +36,7 @@ def test_weakrefs_functional():
...
@@ -36,7 +36,7 @@ def test_weakrefs_functional():
>>> ref() is ob
>>> ref() is ob
True
True
The hash of the ref i
f
the same as the hash of the referenced object:
The hash of the ref i
s
the same as the hash of the referenced object:
>>> hash(ref) == hash(ob)
>>> hash(ref) == hash(ob)
True
True
...
...
src/ZODB/tests/testRecover.py
View file @
266cadf9
...
@@ -73,7 +73,7 @@ class RecoverTest(ZODB.tests.util.TestCase):
...
@@ -73,7 +73,7 @@ class RecoverTest(ZODB.tests.util.TestCase):
offset
=
random
.
randint
(
0
,
self
.
storage
.
_pos
-
size
)
offset
=
random
.
randint
(
0
,
self
.
storage
.
_pos
-
size
)
f
=
open
(
self
.
path
,
"a+b"
)
f
=
open
(
self
.
path
,
"a+b"
)
f
.
seek
(
offset
)
f
.
seek
(
offset
)
f
.
write
(
"
\
0
"
*
size
)
f
.
write
(
b
"
\
0
"
*
size
)
f
.
close
()
f
.
close
()
ITERATIONS
=
5
ITERATIONS
=
5
...
@@ -106,11 +106,11 @@ class RecoverTest(ZODB.tests.util.TestCase):
...
@@ -106,11 +106,11 @@ class RecoverTest(ZODB.tests.util.TestCase):
self
.
assert_
(
'
\
n
0 bytes removed during recovery'
in
output
,
output
)
self
.
assert_
(
'
\
n
0 bytes removed during recovery'
in
output
,
output
)
# Verify that the recovered database is identical to the original.
# Verify that the recovered database is identical to the original.
before
=
file
(
self
.
path
,
'rb'
)
before
=
open
(
self
.
path
,
'rb'
)
before_guts
=
before
.
read
()
before_guts
=
before
.
read
()
before
.
close
()
before
.
close
()
after
=
file
(
self
.
dest
,
'rb'
)
after
=
open
(
self
.
dest
,
'rb'
)
after_guts
=
after
.
read
()
after_guts
=
after
.
read
()
after
.
close
()
after
.
close
()
...
@@ -164,10 +164,10 @@ class RecoverTest(ZODB.tests.util.TestCase):
...
@@ -164,10 +164,10 @@ class RecoverTest(ZODB.tests.util.TestCase):
# Overwrite the entire header.
# Overwrite the entire header.
f
=
open
(
self
.
path
,
"a+b"
)
f
=
open
(
self
.
path
,
"a+b"
)
f
.
seek
(
pos1
-
50
)
f
.
seek
(
pos1
-
50
)
f
.
write
(
"
\
0
"
*
100
)
f
.
write
(
b
"
\
0
"
*
100
)
f
.
close
()
f
.
close
()
output
=
self
.
recover
()
output
=
self
.
recover
()
self
.
assert
_
(
'error'
in
output
,
output
)
self
.
assert
True
(
'error'
in
output
,
output
)
self
.
recovered
=
FileStorage
(
self
.
dest
)
self
.
recovered
=
FileStorage
(
self
.
dest
)
self
.
recovered
.
close
()
self
.
recovered
.
close
()
os
.
remove
(
self
.
path
)
os
.
remove
(
self
.
path
)
...
@@ -176,10 +176,10 @@ class RecoverTest(ZODB.tests.util.TestCase):
...
@@ -176,10 +176,10 @@ class RecoverTest(ZODB.tests.util.TestCase):
# Overwrite part of the header.
# Overwrite part of the header.
f
=
open
(
self
.
path
,
"a+b"
)
f
=
open
(
self
.
path
,
"a+b"
)
f
.
seek
(
pos2
+
10
)
f
.
seek
(
pos2
+
10
)
f
.
write
(
"
\
0
"
*
100
)
f
.
write
(
b
"
\
0
"
*
100
)
f
.
close
()
f
.
close
()
output
=
self
.
recover
()
output
=
self
.
recover
()
self
.
assert
_
(
'error'
in
output
,
output
)
self
.
assert
True
(
'error'
in
output
,
output
)
self
.
recovered
=
FileStorage
(
self
.
dest
)
self
.
recovered
=
FileStorage
(
self
.
dest
)
self
.
recovered
.
close
()
self
.
recovered
.
close
()
...
@@ -197,9 +197,9 @@ class RecoverTest(ZODB.tests.util.TestCase):
...
@@ -197,9 +197,9 @@ class RecoverTest(ZODB.tests.util.TestCase):
f
=
open
(
self
.
path
,
"r+b"
)
f
=
open
(
self
.
path
,
"r+b"
)
f
.
seek
(
pos
+
16
)
f
.
seek
(
pos
+
16
)
current_status
=
f
.
read
(
1
)
current_status
=
f
.
read
(
1
)
self
.
assertEqual
(
current_status
,
' '
)
self
.
assertEqual
(
current_status
,
b
' '
)
f
.
seek
(
pos
+
16
)
f
.
seek
(
pos
+
16
)
f
.
write
(
'c'
)
f
.
write
(
b
'c'
)
f
.
close
()
f
.
close
()
# Try to recover. The original bug was that this never completed --
# Try to recover. The original bug was that this never completed --
...
...
src/ZODB/tests/testSerialize.py
View file @
266cadf9
...
@@ -15,6 +15,7 @@ import doctest
...
@@ -15,6 +15,7 @@ import doctest
import
sys
import
sys
import
unittest
import
unittest
import
ZODB.tests.util
from
ZODB
import
serialize
from
ZODB
import
serialize
try
:
try
:
...
@@ -131,5 +132,6 @@ class SerializerTestCase(unittest.TestCase):
...
@@ -131,5 +132,6 @@ class SerializerTestCase(unittest.TestCase):
def
test_suite
():
def
test_suite
():
suite
=
unittest
.
makeSuite
(
SerializerTestCase
)
suite
=
unittest
.
makeSuite
(
SerializerTestCase
)
suite
.
addTest
(
doctest
.
DocTestSuite
(
"ZODB.serialize"
))
suite
.
addTest
(
doctest
.
DocTestSuite
(
"ZODB.serialize"
,
checker
=
ZODB
.
tests
.
util
.
checker
))
return
suite
return
suite
src/ZODB/tests/testUtils.py
View file @
266cadf9
...
@@ -53,12 +53,12 @@ class TestUtils(unittest.TestCase):
...
@@ -53,12 +53,12 @@ class TestUtils(unittest.TestCase):
self
.
assertEquals
(
num
,
n2
,
"u64() failed"
)
self
.
assertEquals
(
num
,
n2
,
"u64() failed"
)
def
checkKnownConstants
(
self
):
def
checkKnownConstants
(
self
):
self
.
assertEquals
(
"
\
000
\
000
\
000
\
000
\
000
\
000
\
000
\
001
"
,
p64
(
1
))
self
.
assertEquals
(
b
"
\
000
\
000
\
000
\
000
\
000
\
000
\
000
\
001
"
,
p64
(
1
))
self
.
assertEquals
(
"
\
000
\
000
\
000
\
001
\
000
\
000
\
000
\
000
"
,
p64
(
1
<<
32
))
self
.
assertEquals
(
b
"
\
000
\
000
\
000
\
001
\
000
\
000
\
000
\
000
"
,
p64
(
1
<<
32
))
self
.
assertEquals
(
u64
(
"
\
000
\
000
\
000
\
000
\
000
\
000
\
000
\
001
"
),
1
)
self
.
assertEquals
(
u64
(
b
"
\
000
\
000
\
000
\
000
\
000
\
000
\
000
\
001
"
),
1
)
self
.
assertEquals
(
U64
(
"
\
000
\
000
\
000
\
000
\
000
\
000
\
000
\
001
"
),
1
)
self
.
assertEquals
(
U64
(
b
"
\
000
\
000
\
000
\
000
\
000
\
000
\
000
\
001
"
),
1
)
self
.
assertEquals
(
u64
(
"
\
000
\
000
\
000
\
001
\
000
\
000
\
000
\
000
"
),
1
<<
32
)
self
.
assertEquals
(
u64
(
b
"
\
000
\
000
\
000
\
001
\
000
\
000
\
000
\
000
"
),
1
<<
32
)
self
.
assertEquals
(
U64
(
"
\
000
\
000
\
000
\
001
\
000
\
000
\
000
\
000
"
),
1
<<
32
)
self
.
assertEquals
(
U64
(
b
"
\
000
\
000
\
000
\
001
\
000
\
000
\
000
\
000
"
),
1
<<
32
)
def
checkPersistentIdHandlesDescriptor
(
self
):
def
checkPersistentIdHandlesDescriptor
(
self
):
from
ZODB.serialize
import
ObjectWriter
from
ZODB.serialize
import
ObjectWriter
...
@@ -88,11 +88,11 @@ class TestUtils(unittest.TestCase):
...
@@ -88,11 +88,11 @@ class TestUtils(unittest.TestCase):
# The pickle contains a GLOBAL ('c') opcode resolving to MinPO's
# The pickle contains a GLOBAL ('c') opcode resolving to MinPO's
# module and class.
# module and class.
self
.
assert_
(
'cZODB.tests.MinPO
\
n
MinPO
\
n
'
in
data
)
self
.
assert_
(
b
'cZODB.tests.MinPO
\
n
MinPO
\
n
'
in
data
)
# Fiddle the pickle so it points to something "impossible" instead.
# Fiddle the pickle so it points to something "impossible" instead.
data
=
data
.
replace
(
'cZODB.tests.MinPO
\
n
MinPO
\
n
'
,
data
=
data
.
replace
(
b
'cZODB.tests.MinPO
\
n
MinPO
\
n
'
,
'cpath.that.does.not.exist
\
n
likewise.the.class
\
n
'
)
b
'cpath.that.does.not.exist
\
n
likewise.the.class
\
n
'
)
# Pickle can't resolve that GLOBAL opcode -- gets ImportError.
# Pickle can't resolve that GLOBAL opcode -- gets ImportError.
self
.
assertRaises
(
ImportError
,
pickle
.
loads
,
data
)
self
.
assertRaises
(
ImportError
,
pickle
.
loads
,
data
)
...
@@ -101,8 +101,8 @@ class TestUtils(unittest.TestCase):
...
@@ -101,8 +101,8 @@ class TestUtils(unittest.TestCase):
raise
ConflictError
(
object
=
obj
,
data
=
data
)
raise
ConflictError
(
object
=
obj
,
data
=
data
)
except
ConflictError
as
detail
:
except
ConflictError
as
detail
:
# And verify that the msg names the impossible path.
# And verify that the msg names the impossible path.
self
.
assert
_
(
'path.that.does.not.exist.likewise.the.class'
in
self
.
assert
True
(
str
(
detail
))
'path.that.does.not.exist.likewise.the.class'
in
str
(
detail
))
else
:
else
:
self
.
fail
(
"expected ConflictError, but no exception raised"
)
self
.
fail
(
"expected ConflictError, but no exception raised"
)
...
...
src/ZODB/tests/test_fsdump.py
View file @
266cadf9
...
@@ -69,8 +69,10 @@ Clean up.
...
@@ -69,8 +69,10 @@ Clean up.
import
doctest
import
doctest
import
zope.testing.setupstack
import
zope.testing.setupstack
import
ZODB.tests.util
def
test_suite
():
def
test_suite
():
return
doctest
.
DocTestSuite
(
return
doctest
.
DocTestSuite
(
setUp
=
zope
.
testing
.
setupstack
.
setUpDirectory
,
setUp
=
zope
.
testing
.
setupstack
.
setUpDirectory
,
tearDown
=
zope
.
testing
.
setupstack
.
tearDown
)
tearDown
=
zope
.
testing
.
setupstack
.
tearDown
,
checker
=
ZODB
.
tests
.
util
.
checker
)
src/ZODB/tests/test_persistentclass.py
deleted
100644 → 0
View file @
de1ed537
##############################################################################
#
# Copyright (c) 2003 Zope Foundation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
from
doctest
import
DocTestSuite
import
unittest
def
test_new_ghost_w_persistent_class
():
"""
Peristent meta classes work with PickleCache.new_ghost:
>>> import ZODB.persistentclass
>>> class PC:
... __metaclass__ = ZODB.persistentclass.PersistentMetaClass
>>> PC._p_oid
>>> PC._p_jar
>>> PC._p_serial
>>> PC._p_changed
False
>>> import persistent
>>> jar = object()
>>> cache = persistent.PickleCache(jar, 10, 100)
>>> cache.new_ghost('1', PC)
>>> PC._p_oid
'1'
>>> PC._p_jar is jar
True
>>> PC._p_serial
>>> PC._p_changed
False
"""
def
test_suite
():
return
unittest
.
TestSuite
((
DocTestSuite
(),
))
src/ZODB/tests/testblob.py
View file @
266cadf9
...
@@ -42,11 +42,10 @@ import zope.testing.renormalizing
...
@@ -42,11 +42,10 @@ import zope.testing.renormalizing
try
:
try
:
from
StringIO
import
StringIO
from
StringIO
import
StringIO
as
BytesIO
except
ImportError
:
except
ImportError
:
# Py3
# Py3
from
io
import
StringIO
from
io
import
BytesIO
def
new_time
():
def
new_time
():
"""Create a _new_ time stamp.
"""Create a _new_ time stamp.
...
@@ -118,7 +117,7 @@ class BlobCloneTests(ZODB.tests.util.TestCase):
...
@@ -118,7 +117,7 @@ class BlobCloneTests(ZODB.tests.util.TestCase):
root
[
'blob'
]
=
Blob
()
root
[
'blob'
]
=
Blob
()
transaction
.
commit
()
transaction
.
commit
()
stream
=
String
IO
()
stream
=
Bytes
IO
()
p
=
Pickler
(
stream
,
1
)
p
=
Pickler
(
stream
,
1
)
p
.
dump
(
root
[
'blob'
])
p
.
dump
(
root
[
'blob'
])
u
=
Unpickler
(
stream
)
u
=
Unpickler
(
stream
)
...
@@ -756,13 +755,15 @@ def test_suite():
...
@@ -756,13 +755,15 @@ def test_suite():
setUp=setUp,
setUp=setUp,
tearDown=zope.testing.setupstack.tearDown,
tearDown=zope.testing.setupstack.tearDown,
optionflags=doctest.ELLIPSIS,
optionflags=doctest.ELLIPSIS,
checker=ZODB.tests.util.checker,
))
))
suite.addTest(doctest.DocFileSuite(
suite.addTest(doctest.DocFileSuite(
"blob_layout.txt",
"blob_layout.txt",
optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE,
optionflags=doctest.ELLIPSIS|doctest.NORMALIZE_WHITESPACE,
setUp=setUp,
setUp=setUp,
tearDown=zope.testing.setupstack.tearDown,
tearDown=zope.testing.setupstack.tearDown,
checker = zope.testing.renormalizing.RENormalizing([
checker = ZODB.tests.util.checker +
\
zope.testing.renormalizing.RENormalizing([
(re.compile(r'
\
%
(
sep
)
s
\
%
(
sep
)
s
' % dict(sep=os.path.sep)), '
/
'),
(re.compile(r'
\
%
(
sep
)
s
\
%
(
sep
)
s
' % dict(sep=os.path.sep)), '
/
'),
(re.compile(r'
\
%
(
sep
)
s
' % dict(sep=os.path.sep)), '
/
'),
(re.compile(r'
\
%
(
sep
)
s
' % dict(sep=os.path.sep)), '
/
'),
(re.compile(r'
\
S
+/
((
old
|
bushy
|
lawn
)
/
\
S
+/
foo
[
23456
]
?
)
'), r'
\
1
'),
(re.compile(r'
\
S
+/
((
old
|
bushy
|
lawn
)
/
\
S
+/
foo
[
23456
]
?
)
'), r'
\
1
'),
...
...
src/ZODB/tests/testconflictresolution.py
View file @
266cadf9
...
@@ -113,7 +113,6 @@ Of course, none of this applies if content doesn't support conflict resolution.
...
@@ -113,7 +113,6 @@ Of course, none of this applies if content doesn't support conflict resolution.
class
Resolveable
(
persistent
.
Persistent
):
class
Resolveable
(
persistent
.
Persistent
):
def
_p_resolveConflict
(
self
,
old
,
committed
,
new
):
def
_p_resolveConflict
(
self
,
old
,
committed
,
new
):
resolved
=
{}
resolved
=
{}
for
k
in
old
:
for
k
in
old
:
if
k
not
in
committed
:
if
k
not
in
committed
:
...
@@ -296,13 +295,14 @@ And load the pickle:
...
@@ -296,13 +295,14 @@ And load the pickle:
def
test_suite
():
def
test_suite
():
return
unittest
.
TestSuite
([
return
unittest
.
TestSuite
([
manuel
.
testing
.
TestSuite
(
manuel
.
testing
.
TestSuite
(
manuel
.
doctest
.
Manuel
()
manuel
.
doctest
.
Manuel
(
checker
=
ZODB
.
tests
.
util
.
checker
)
+
manuel
.
footnote
.
Manuel
()
+
manuel
.
footnote
.
Manuel
()
+
manuel
.
capture
.
Manuel
(),
+
manuel
.
capture
.
Manuel
(),
'../ConflictResolution.txt'
,
'../ConflictResolution.txt'
,
setUp
=
setUp
,
tearDown
=
tearDown
,
setUp
=
setUp
,
tearDown
=
tearDown
),
),
doctest
.
DocTestSuite
(
doctest
.
DocTestSuite
(
setUp
=
setUp
,
tearDown
=
tearDown
),
setUp
=
setUp
,
tearDown
=
tearDown
,
checker
=
ZODB
.
tests
.
util
.
checker
),
])
])
src/ZODB/tests/testcrossdatabasereferences.py
View file @
266cadf9
...
@@ -14,6 +14,7 @@
...
@@ -14,6 +14,7 @@
import
doctest
import
doctest
import
persistent
import
persistent
import
unittest
import
unittest
import
ZODB.tests.util
class
MyClass
(
persistent
.
Persistent
):
class
MyClass
(
persistent
.
Persistent
):
pass
pass
...
@@ -181,15 +182,19 @@ def tearDownDbs(test):
...
@@ -181,15 +182,19 @@ def tearDownDbs(test):
def
test_suite
():
def
test_suite
():
return
unittest
.
TestSuite
((
return
unittest
.
TestSuite
((
doctest
.
DocFileSuite
(
'../cross-database-references.txt'
,
doctest
.
DocFileSuite
(
'../cross-database-references.txt'
,
globs
=
dict
(
MyClass
=
MyClass
),
globs
=
dict
(
MyClass
=
MyClass
),
tearDown
=
tearDownDbs
,
tearDown
=
tearDownDbs
,
checker
=
ZODB
.
tests
.
util
.
checker
,
),
),
doctest
.
DocFileSuite
(
'../cross-database-references.txt'
,
doctest
.
DocFileSuite
(
'../cross-database-references.txt'
,
globs
=
dict
(
MyClass
=
MyClass_w_getnewargs
),
globs
=
dict
(
MyClass
=
MyClass_w_getnewargs
),
tearDown
=
tearDownDbs
,
tearDown
=
tearDownDbs
,
checker
=
ZODB
.
tests
.
util
.
checker
,
),
),
doctest
.
DocTestSuite
(),
doctest
.
DocTestSuite
(
checker
=
ZODB
.
tests
.
util
.
checker
),
))
))
if
__name__
==
'__main__'
:
if
__name__
==
'__main__'
:
...
...
src/ZODB/tests/testfsIndex.py
View file @
266cadf9
...
@@ -20,6 +20,11 @@ from ZODB.utils import p64, z64
...
@@ -20,6 +20,11 @@ from ZODB.utils import p64, z64
from
ZODB.tests.util
import
setUp
,
tearDown
from
ZODB.tests.util
import
setUp
,
tearDown
import
six
import
six
try
:
xrange
except
NameError
:
# Py3: No xrange.
xrange
=
range
class
Test
(
unittest
.
TestCase
):
class
Test
(
unittest
.
TestCase
):
...
@@ -143,7 +148,7 @@ class Test(unittest.TestCase):
...
@@ -143,7 +148,7 @@ class Test(unittest.TestCase):
# Now build up a tree with random values, and check maxKey at each
# Now build up a tree with random values, and check maxKey at each
# step.
# step.
correct_max
=
""
# smaller than anything we'll add
correct_max
=
b
""
# smaller than anything we'll add
for
i
in
range
(
1000
):
for
i
in
range
(
1000
):
key
=
p64
(
random
.
randrange
(
100000000
))
key
=
p64
(
random
.
randrange
(
100000000
))
index
[
key
]
=
i
index
[
key
]
=
i
...
@@ -152,10 +157,10 @@ class Test(unittest.TestCase):
...
@@ -152,10 +157,10 @@ class Test(unittest.TestCase):
self
.
assertEqual
(
index_max
,
correct_max
)
self
.
assertEqual
(
index_max
,
correct_max
)
index
.
clear
()
index
.
clear
()
a
=
'
\
000
\
000
\
000
\
000
\
000
\
001
\
000
\
000
'
a
=
b
'
\
000
\
000
\
000
\
000
\
000
\
001
\
000
\
000
'
b
=
'
\
000
\
000
\
000
\
000
\
000
\
002
\
000
\
000
'
b
=
b
'
\
000
\
000
\
000
\
000
\
000
\
002
\
000
\
000
'
c
=
'
\
000
\
000
\
000
\
000
\
000
\
003
\
000
\
000
'
c
=
b
'
\
000
\
000
\
000
\
000
\
000
\
003
\
000
\
000
'
d
=
'
\
000
\
000
\
000
\
000
\
000
\
004
\
000
\
000
'
d
=
b
'
\
000
\
000
\
000
\
000
\
000
\
004
\
000
\
000
'
index
[
a
]
=
1
index
[
a
]
=
1
index
[
c
]
=
2
index
[
c
]
=
2
self
.
assertEqual
(
index
.
maxKey
(
b
),
a
)
self
.
assertEqual
(
index
.
maxKey
(
b
),
a
)
...
@@ -171,7 +176,7 @@ class Test(unittest.TestCase):
...
@@ -171,7 +176,7 @@ class Test(unittest.TestCase):
# Now build up a tree with random values, and check minKey at each
# Now build up a tree with random values, and check minKey at each
# step.
# step.
correct_min
=
"
\
xff
"
*
8
# bigger than anything we'll add
correct_min
=
b
"
\
xff
"
*
8
# bigger than anything we'll add
for
i
in
range
(
1000
):
for
i
in
range
(
1000
):
key
=
p64
(
random
.
randrange
(
100000000
))
key
=
p64
(
random
.
randrange
(
100000000
))
index
[
key
]
=
i
index
[
key
]
=
i
...
@@ -180,10 +185,10 @@ class Test(unittest.TestCase):
...
@@ -180,10 +185,10 @@ class Test(unittest.TestCase):
self
.
assertEqual
(
index_min
,
correct_min
)
self
.
assertEqual
(
index_min
,
correct_min
)
index
.
clear
()
index
.
clear
()
a
=
'
\
000
\
000
\
000
\
000
\
000
\
001
\
000
\
000
'
a
=
b
'
\
000
\
000
\
000
\
000
\
000
\
001
\
000
\
000
'
b
=
'
\
000
\
000
\
000
\
000
\
000
\
002
\
000
\
000
'
b
=
b
'
\
000
\
000
\
000
\
000
\
000
\
002
\
000
\
000
'
c
=
'
\
000
\
000
\
000
\
000
\
000
\
003
\
000
\
000
'
c
=
b
'
\
000
\
000
\
000
\
000
\
000
\
003
\
000
\
000
'
d
=
'
\
000
\
000
\
000
\
000
\
000
\
004
\
000
\
000
'
d
=
b
'
\
000
\
000
\
000
\
000
\
000
\
004
\
000
\
000
'
index
[
a
]
=
1
index
[
a
]
=
1
index
[
c
]
=
2
index
[
c
]
=
2
self
.
assertEqual
(
index
.
minKey
(
b
),
c
)
self
.
assertEqual
(
index
.
minKey
(
b
),
c
)
...
...
src/ZODB/tests/testfsoids.py
View file @
266cadf9
...
@@ -168,6 +168,7 @@ Clean up.
...
@@ -168,6 +168,7 @@ Clean up.
"""
"""
import
doctest
import
doctest
import
ZODB.tests.util
def
test_suite
():
def
test_suite
():
return
doctest
.
DocTestSuite
()
return
doctest
.
DocTestSuite
(
checker
=
ZODB
.
tests
.
util
.
checker
)
src/ZODB/tests/testhistoricalconnections.py
View file @
266cadf9
...
@@ -18,7 +18,8 @@ import ZODB.tests.util
...
@@ -18,7 +18,8 @@ import ZODB.tests.util
def
test_suite
():
def
test_suite
():
return
manuel
.
testing
.
TestSuite
(
return
manuel
.
testing
.
TestSuite
(
manuel
.
doctest
.
Manuel
()
+
manuel
.
footnote
.
Manuel
(),
manuel
.
doctest
.
Manuel
(
checker
=
ZODB
.
tests
.
util
.
checker
)
+
manuel
.
footnote
.
Manuel
(),
'../historical_connections.txt'
,
'../historical_connections.txt'
,
setUp
=
ZODB
.
tests
.
util
.
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
setUp
=
ZODB
.
tests
.
util
.
setUp
,
tearDown
=
ZODB
.
tests
.
util
.
tearDown
,
)
)
src/ZODB/tests/testpersistentclass.py
View file @
266cadf9
...
@@ -22,8 +22,7 @@ def class_with_circular_ref_to_self():
...
@@ -22,8 +22,7 @@ def class_with_circular_ref_to_self():
"""
"""
It should be possible for a class to reger to itself.
It should be possible for a class to reger to itself.
>>> class C:
>>> C = ZODB.persistentclass.PersistentMetaClass('C', (object,), {})
... __metaclass__ = ZODB.persistentclass.PersistentMetaClass
>>> C.me = C
>>> C.me = C
>>> db = ZODB.tests.util.DB()
>>> db = ZODB.tests.util.DB()
...
@@ -39,6 +38,34 @@ It should be possible for a class to reger to itself.
...
@@ -39,6 +38,34 @@ It should be possible for a class to reger to itself.
"""
"""
def
test_new_ghost_w_persistent_class
():
"""
Peristent meta classes work with PickleCache.new_ghost:
>>> import ZODB.persistentclass
>>> PC = ZODB.persistentclass.PersistentMetaClass('PC', (object,), {})
>>> PC._p_oid
>>> PC._p_jar
>>> PC._p_serial
>>> PC._p_changed
False
>>> import persistent
>>> jar = object()
>>> cache = persistent.PickleCache(jar, 10, 100)
>>> cache.new_ghost('1', PC)
>>> PC._p_oid
'1'
>>> PC._p_jar is jar
True
>>> PC._p_serial
>>> PC._p_changed
False
"""
# XXX need to update files to get newer testing package
# XXX need to update files to get newer testing package
class
FakeModule
:
class
FakeModule
:
def
__init__
(
self
,
name
,
dict
):
def
__init__
(
self
,
name
,
dict
):
...
@@ -59,8 +86,10 @@ def tearDown(test):
...
@@ -59,8 +86,10 @@ def tearDown(test):
def
test_suite
():
def
test_suite
():
return
unittest
.
TestSuite
((
return
unittest
.
TestSuite
((
doctest
.
DocFileSuite
(
"../persistentclass.txt"
,
doctest
.
DocFileSuite
(
setUp
=
setUp
,
tearDown
=
tearDown
),
"../persistentclass.txt"
,
setUp
=
setUp
,
tearDown
=
tearDown
,
checker
=
ZODB
.
tests
.
util
.
checker
),
doctest
.
DocTestSuite
(
setUp
=
setUp
,
tearDown
=
tearDown
),
doctest
.
DocTestSuite
(
setUp
=
setUp
,
tearDown
=
tearDown
),
))
))
...
...
src/ZODB/tests/util.py
View file @
266cadf9
...
@@ -18,6 +18,7 @@ from ZODB.MappingStorage import DB
...
@@ -18,6 +18,7 @@ from ZODB.MappingStorage import DB
import
atexit
import
atexit
import
os
import
os
import
persistent
import
persistent
import
re
import
sys
import
sys
import
tempfile
import
tempfile
import
time
import
time
...
@@ -26,6 +27,36 @@ import unittest
...
@@ -26,6 +27,36 @@ import unittest
import
warnings
import
warnings
import
ZODB.utils
import
ZODB.utils
import
zope.testing.setupstack
import
zope.testing.setupstack
from
zope.testing
import
renormalizing
checker
=
renormalizing
.
RENormalizing
([
(
re
.
compile
(
"<(.*?) object at 0x[0-9a-f]*?>"
),
r"<\1 object at 0x000000000000>"
),
# Python 3 bytes add a "b".
(
re
.
compile
(
"b('.*?')"
),
r"\1"
),
(
re
.
compile
(
'b(".*?")'
),
r"\1"
),
# Python 3 adds module name to exceptions.
(
re
.
compile
(
"ZODB.interfaces.BlobError"
),
r"BlobError"
),
(
re
.
compile
(
"ZODB.blob.BlobStorageError"
),
r"BlobStorageError"
),
(
re
.
compile
(
"ZODB.broken.BrokenModified"
),
r"BrokenModified"
),
(
re
.
compile
(
"ZODB.POSException.POSKeyError"
),
r"POSKeyError"
),
(
re
.
compile
(
"ZODB.POSException.ConflictError"
),
r"ConflictError"
),
(
re
.
compile
(
"ZODB.POSException.ReadConflictError"
),
r"ReadConflictError"
),
(
re
.
compile
(
"ZODB.POSException.InvalidObjectReference"
),
r"InvalidObjectReference"
),
(
re
.
compile
(
"ZODB.POSException.ReadOnlyHistoryError"
),
r"ReadOnlyHistoryError"
),
(
re
.
compile
(
"ZConfig.ConfigurationSyntaxError"
),
r"ConfigurationSyntaxError"
),
])
def
setUp
(
test
,
name
=
'test'
):
def
setUp
(
test
,
name
=
'test'
):
transaction
.
abort
()
transaction
.
abort
()
...
@@ -125,9 +156,9 @@ def wait(func=None, timeout=30):
...
@@ -125,9 +156,9 @@ def wait(func=None, timeout=30):
raise
AssertionError
raise
AssertionError
def
store
(
storage
,
oid
,
value
=
'x'
,
serial
=
ZODB
.
utils
.
z64
):
def
store
(
storage
,
oid
,
value
=
'x'
,
serial
=
ZODB
.
utils
.
z64
):
if
not
isinstance
(
oid
,
str
):
if
not
isinstance
(
oid
,
bytes
):
oid
=
ZODB
.
utils
.
p64
(
oid
)
oid
=
ZODB
.
utils
.
p64
(
oid
)
if
not
isinstance
(
serial
,
str
):
if
not
isinstance
(
serial
,
bytes
):
serial
=
ZODB
.
utils
.
p64
(
serial
)
serial
=
ZODB
.
utils
.
p64
(
serial
)
t
=
transaction
.
get
()
t
=
transaction
.
get
()
storage
.
tpc_begin
(
t
)
storage
.
tpc_begin
(
t
)
...
...
src/ZODB/utils.py
View file @
266cadf9
...
@@ -27,10 +27,10 @@ except ImportError:
...
@@ -27,10 +27,10 @@ except ImportError:
import
pickle
import
pickle
try
:
try
:
from
cStringIO
import
StringIO
from
cStringIO
import
StringIO
as
BytesIO
except
ImportError
:
except
ImportError
:
# Py3
# Py3
from
io
import
String
IO
from
io
import
Bytes
IO
from
persistent.TimeStamp
import
TimeStamp
from
persistent.TimeStamp
import
TimeStamp
...
@@ -177,7 +177,7 @@ def repr_to_oid(repr):
...
@@ -177,7 +177,7 @@ def repr_to_oid(repr):
if
repr
.
startswith
(
"0x"
):
if
repr
.
startswith
(
"0x"
):
repr
=
repr
[
2
:]
repr
=
repr
[
2
:]
as_bin
=
unhexlify
(
repr
)
as_bin
=
unhexlify
(
repr
)
as_bin
=
"
\
x00
"
*
(
8
-
len
(
as_bin
))
+
as_bin
as_bin
=
b
"
\
x00
"
*
(
8
-
len
(
as_bin
))
+
as_bin
return
as_bin
return
as_bin
serial_repr
=
oid_repr
serial_repr
=
oid_repr
...
@@ -219,12 +219,14 @@ def positive_id(obj):
...
@@ -219,12 +219,14 @@ def positive_id(obj):
# for what serialize.py calls formats 5 and 6.
# for what serialize.py calls formats 5 and 6.
def
get_pickle_metadata
(
data
):
def
get_pickle_metadata
(
data
):
# Returns a 2-tuple of strings.
# ZODB's data records contain two pickles. The first is the class
# ZODB's data records contain two pickles. The first is the class
# of the object, the second is the object. We're only trying to
# of the object, the second is the object. We're only trying to
# pick apart the first here, to extract the module and class names.
# pick apart the first here, to extract the module and class names.
if
data
.
startswith
(
'(c'
):
# pickle MARK GLOBAL opcode sequence
if
data
.
startswith
(
b
'(c'
):
# pickle MARK GLOBAL opcode sequence
global_prefix
=
2
global_prefix
=
2
elif
data
.
startswith
(
'c'
):
# pickle GLOBAL opcode
elif
data
.
startswith
(
b
'c'
):
# pickle GLOBAL opcode
global_prefix
=
1
global_prefix
=
1
else
:
else
:
global_prefix
=
0
global_prefix
=
0
...
@@ -235,12 +237,12 @@ def get_pickle_metadata(data):
...
@@ -235,12 +237,12 @@ def get_pickle_metadata(data):
# load the class. Just break open the pickle and get the
# load the class. Just break open the pickle and get the
# module and class from it. The module and class names are given by
# module and class from it. The module and class names are given by
# newline-terminated strings following the GLOBAL opcode.
# newline-terminated strings following the GLOBAL opcode.
modname
,
classname
,
rest
=
data
.
split
(
'
\
n
'
,
2
)
modname
,
classname
,
rest
=
data
.
split
(
b
'
\
n
'
,
2
)
modname
=
modname
[
global_prefix
:]
# strip GLOBAL opcode
modname
=
modname
[
global_prefix
:]
# strip GLOBAL opcode
return
modname
,
classname
return
modname
.
decode
(),
classname
.
decode
()
# Else there are a bunch of other possible formats.
# Else there are a bunch of other possible formats.
f
=
String
IO
(
data
)
f
=
Bytes
IO
(
data
)
u
=
pickle
.
Unpickler
(
f
)
u
=
pickle
.
Unpickler
(
f
)
try
:
try
:
class_info
=
u
.
load
()
class_info
=
u
.
load
()
...
...
tox.ini
0 → 100644
View file @
266cadf9
[tox]
envlist
=
py26,py27,py33
[testenv]
commands
=
python
setup.py
test
-q
# without explicit deps, setup.py test will download a bunch of eggs into $PWD
deps
=
BTrees
ZConfig
manuel
persistent
six
transaction
zc.lockfile
zdaemon
zope.interface
zope.testing
[testenv:coverage]
basepython
=
python2.7
commands
=
# The installed version messes up nose's test discovery / coverage reporting
# So, we uninstall that from the environment, and then install the editable
# version, before running nosetests.
pip
uninstall
-y
ZODB
pip
install
-e
.
nosetests
--with-xunit
--with-xcoverage
deps
=
nose
coverage
nosexcover
BTrees
ZConfig
manuel
persistent
six
transaction
zc.lockfile
zdaemon
zope.interface
zope.testing
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment