/usr/share/pyshared/zope/keyreference/persistent.py is in python-zope.keyreference 3.6.4-0ubuntu1.
This file is owned by root:root, with mode 0o644.
The actual contents of the file can be viewed below.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | ##############################################################################
#
# Copyright (c) 2001, 2002 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.
#
##############################################################################
"""KeyReference for persistent objects.
Provides an IKeyReference adapter for persistent objects.
"""
from ZODB.interfaces import IConnection
from ZODB.ConflictResolution import PersistentReference
import zope.interface
import zope.keyreference.interfaces
class KeyReferenceToPersistent(object):
"""An IKeyReference for persistent objects which is comparable.
These references compare by database name and _p_oids of the objects they
reference.
"""
zope.interface.implements(zope.keyreference.interfaces.IKeyReference)
key_type_id = 'zope.app.keyreference.persistent'
def __init__(self, object):
if not getattr(object, '_p_oid', None):
connection = IConnection(object, None)
if connection is None:
raise zope.keyreference.interfaces.NotYet(object)
connection.add(object)
self.object = object
def __call__(self):
return self.object
def __hash__(self):
if isinstance(self.object, PersistentReference):
# we are doing conflict resolution.
database_name = self.object.database_name
if database_name is None:
# we can't hash
raise ValueError('database name unavailable at this time')
oid = self.object.oid
else:
database_name = self.object._p_jar.db().database_name
oid = self.object._p_oid
return hash((database_name, oid))
def __cmp__(self, other):
if self.key_type_id == other.key_type_id:
# While it makes subclassing this class inconvenient,
# comparing the object's type is faster than doing an
# isinstance check. The intent of using type instead
# of isinstance is to avoid loading state just to
# determine if we're in conflict resolution.
if type(self.object) is PersistentReference:
# We are doing conflict resolution.
assert isinstance(other.object, PersistentReference), (
'other object claims to be '
'zope.app.keyreference.persistent but, during conflict '
'resolution, object is not a PersistentReference')
self_name = self.object.database_name
other_name = other.object.database_name
if (self_name is None) ^ (other_name is None):
# one of the two database_names are None during conflict
# resolution. At this time the database_name is
# inaccessible, not unset (it is the same database as the
# object being resolved). If they were both None, we
# would know they are from the same database, so we can
# compare the oids. If neither were None, we would be
# able to reliably compare. However, in this case,
# one is None and the other is not, so we can't know how
# they would sort outside of conflict resolution. Give
# up.
raise ValueError('cannot sort reliably')
self_oid = self.object.oid
other_oid = other.object.oid
else:
self_name = self.object._p_jar.db().database_name
self_oid = self.object._p_oid
other_name = other.object._p_jar.db().database_name
other_oid = other.object._p_oid
return cmp((self_name, self_oid), (other_name, other_oid))
return cmp(self.key_type_id, other.key_type_id)
@zope.interface.implementer(IConnection)
def connectionOfPersistent(ob):
"""An adapter which gets a ZODB connection of a persistent object.
We are assuming the object has a parent if it has been created in
this transaction.
Raises ValueError if it is impossible to get a connection.
"""
cur = ob
while not getattr(cur, '_p_jar', None):
cur = getattr(cur, '__parent__', None)
if cur is None:
return None
return cur._p_jar
# BBB: If zope.app.keyreference is not installed, we still want
# old key references to be available. So fake a module to make
# them unpickleable.
try:
import zope.app.keyreference
except ImportError:
import sys
from types import ModuleType as module
z_a_k = module('zope.app.keyreference')
sys.modules['zope.app.keyreference'] = z_a_k
z_a_k_p = module('zope.app.keyreference.persistent')
z_a_k_p.KeyReferenceToPersistent = KeyReferenceToPersistent
sys.modules['zope.app.keyreference.persistent'] = z_a_k_p
|