Commit daf82646 authored by Kirill Smelkov's avatar Kirill Smelkov

Make lint happy

Sorry, but some of flake8 complaints are really stupid...
parent e8010aa6
......@@ -256,7 +256,6 @@ class DemoStorage(ConflictResolvingStorage):
# regular data record
return data, serial, next_serial
def loadBlob(self, oid, serial):
try:
return self.changes.loadBlob(oid, serial)
......
......@@ -599,7 +599,7 @@ class FileStorage(
elif h.back:
# backpointer
data, _, _, _ = self._loadBack_impl(oid, h.back,
fail=False, _file=_file)
fail=False, _file=_file)
return data, h.tid
else:
# deletion
......
......@@ -889,25 +889,28 @@ class IPrefetchStorage(IStorage):
more than once.
"""
class IStorageLoadBeforeEx(Interface):
def loadBeforeEx(oid, before): # -> (data, serial)
def loadBeforeEx(oid, before): # -> (data, serial)
"""Load object data as observed before given database state.
loadBeforeEx returns data for object with given object ID as observed by
most recent database transaction with ID < before. Two values are returned:
loadBeforeEx returns data for object with given object ID as observed
by most recent database transaction with ID < before. Two values are
returned:
- The data record,
- The transaction ID of the data record.
If the object does not exist, or is deleted as of requested database state,
loadBeforeEx returns data=None, and serial indicates transaction ID of the
most recent deletion done in transaction with ID < before, or null tid if
there is no such deletion.
If the object does not exist, or is deleted as of requested database
state, loadBeforeEx returns data=None, and serial indicates transaction
ID of the most recent deletion done in transaction with ID < before, or
null tid if there is no such deletion.
Note: no POSKeyError is raised even if object id is not in the storage.
"""
class IMultiCommitStorage(IStorage):
"""A multi-commit storage can commit multiple transactions at once.
......
......@@ -10,7 +10,8 @@ also simplifies the implementation of the DB and Connection classes.
import zope.interface
from . import interfaces, serialize, POSException
from .utils import p64, u64, z64, maxtid, Lock, loadBeforeEx, oid_repr, tid_repr
from .utils import p64, u64, z64, maxtid, Lock, loadBeforeEx, oid_repr, \
tid_repr
class Base(object):
......@@ -158,11 +159,12 @@ class MVCCAdapterInstance(Base):
data, serial = loadBeforeEx(self._storage, oid, self._start)
if data is None:
# raise POSKeyError if object does not exist at all
# TODO raise POSKeyError always and switch to raising ReadOnlyError only when
# actually detecting that load is being affected by simultaneous pack (see below).
# TODO raise POSKeyError always and switch to raising ReadOnlyError
# only when actually detecting that load is being affected by
# simultaneous pack (see below).
if serial == z64:
# XXX second call to loadBeforeEx - it will become unneeded once we
# switch to raising POSKeyError.
# XXX second call to loadBeforeEx - it will become unneeded
# once we switch to raising POSKeyError.
_, serial_exists = loadBeforeEx(self._storage, oid, maxtid)
if serial_exists == z64:
# object does not exist at all
......
......@@ -39,7 +39,8 @@ class HexStorage(object):
setattr(self, name, v)
zope.interface.directlyProvides(self, zope.interface.providedBy(base))
if hasattr(base, 'loadBeforeEx') and 'loadBeforeEx' not in self.copied_methods:
if hasattr(base, 'loadBeforeEx') and \
'loadBeforeEx' not in self.copied_methods:
def loadBeforeEx(oid, before):
data, serial = self.base.loadBeforeEx(oid, before)
if data is not None:
......
......@@ -270,7 +270,10 @@ def load_before_base_storage_current():
>>> base.close()
"""
# additional DemoStorage tests that do not fit into common DemoStorageTests setup.
# additional DemoStorage tests that do not fit into common DemoStorageTests
# setup.
class DemoStorageTests2(ZODB.tests.util.TestCase):
def checkLoadAfterDelete(self):
"""Verify that DemoStorage correctly handles load requests for objects
......@@ -283,11 +286,11 @@ class DemoStorageTests2(ZODB.tests.util.TestCase):
TransactionMetaData = ZODB.Connection.TransactionMetaData
# mkbase prepares base part of the storage.
def mkbase(): # -> zbase
def mkbase(): # -> zbase
zbase = FileStorage("base.fs")
db = DB(zbase)
conn = db.open()
root = conn.root()
db = DB(zbase)
conn = db.open()
root = conn.root()
root['obj'] = obj = MinPO(0)
transaction.commit()
......@@ -303,18 +306,19 @@ class DemoStorageTests2(ZODB.tests.util.TestCase):
return zbase
# prepare base + overlay
zbase = mkbase()
zbase = mkbase()
zoverlay = FileStorage("overlay.fs")
zdemo = DemoStorage(base=zbase, changes=zoverlay)
zdemo = DemoStorage(base=zbase, changes=zoverlay)
# overlay: modify obj and root
db = DB(zdemo)
db = DB(zdemo)
conn = db.open()
root = conn.root()
obj = root['obj']
oid = obj._p_oid
obj.value += 1
# modify root as well so that there is root revision saved in overlay that points to obj
# modify root as well so that there is root revision saved in overlay
# that points to obj
root['x'] = 1
transaction.commit()
atLive = obj._p_serial
......@@ -327,13 +331,14 @@ class DemoStorageTests2(ZODB.tests.util.TestCase):
# unmount DemoStorage
conn.close()
db.close()
zdemo.close() # closes zbase and zoverlay as well
zdemo.close() # closes zbase and zoverlay as well
del zbase, zoverlay
# simulate GC on base+overlay
zoverlay = FileStorage("overlay.fs")
txn = transaction.get()
txn_meta = TransactionMetaData(txn.user, txn.description, txn.extension)
txn_meta = TransactionMetaData(txn.user, txn.description,
txn.extension)
zoverlay.tpc_begin(txn_meta)
zoverlay.deleteObject(oid, atLive, txn_meta)
zoverlay.tpc_vote(txn_meta)
......@@ -342,7 +347,7 @@ class DemoStorageTests2(ZODB.tests.util.TestCase):
# remount base+overlay
zbase = FileStorage("base.fs", read_only=True)
zdemo = ZODB.DemoStorage.DemoStorage(base=zbase, changes=zoverlay)
db = DB(zdemo)
db = DB(zdemo)
# verify:
# load(obj, atLive) -> 2
......@@ -362,7 +367,7 @@ class DemoStorageTests2(ZODB.tests.util.TestCase):
# end
db.close()
zdemo.close() # closes zbase and zoverlay as well
zdemo.close() # closes zbase and zoverlay as well
def test_suite():
......
......@@ -405,7 +405,9 @@ def load_current(storage, oid, version=''):
return data, serial
_loadBeforeExWarned = set() # of storage class
_loadBeforeExWarned = set() # of storage class
def loadBeforeEx(storage, oid, before):
"""loadBeforeEx provides IStorageLoadBeforeEx semantic for all storages.
......@@ -430,16 +432,21 @@ def loadBeforeEx(storage, oid, before):
# DemoStorage (https://github.com/zopefoundation/ZODB/issues/318), so
# emit corresponding warning.
if type(storage) not in _loadBeforeExWarned:
# there is potential race around _loadBeforeExWarned access, but due to the
# GIL this race cannot result in that set corruption, and can only lead
# to us emitting the warning twice instead of just once.
# -> do not spend CPU on lock and just ignore it.
# there is potential race around _loadBeforeExWarned access, but
# due to the GIL this race cannot result in that set corruption,
# and can only lead to us emitting the warning twice instead of
# just once. -> do not spend CPU on lock and just ignore it.
warnings.warn(
"FIXME %s does not provide loadBeforeEx - emulating it via loadBefore, but ...\n"
"FIXME %s does not provide loadBeforeEx - emulating it via "
"loadBefore, but ...\n"
"\t... 1) access is be potentially slower, and\n"
"\t... 2) not full semantic of loadBeforeEx could be provided.\n"
"\t... this can lead to data corruption in the presence of delete records.\n"
"\t... -> please see https://github.com/zopefoundation/ZODB/issues/318 for details." %
"\t... 2) not full semantic of loadBeforeEx could be "
"provided.\n"
"\t... this can lead to data corruption in the presence "
"of delete records.\n"
"\t... -> please see "
"https://github.com/zopefoundation/ZODB/issues/318 for "
"details." %
type(storage), PendingDeprecationWarning)
_loadBeforeExWarned.add(type(storage))
return (None, z64)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment