jamadden: Another option, instead of having the C code round each time it retrieves `TimeStamp_sec`, would be to have both versions do the rounding before creating the raw value. That loses precision in the raw value, though, potentially leading to more collisions.
jamadden: Argh. Apparently MSVC 9 doesn’t have the standard `round` function, at least not by default. 
mgedmin: >  I see you already have a unit test for this case (6.5), and I wonder why it passes?

That's because I'm an idiot who forgot that it's not `round(...)` that applies here but `round(..., 6)`.
jamadden: > I think that C and Python versions should be consistent between themselves, but I don't think round(..., 6) is appropriate.

That's essentially what happens in the raw bytes format, and why a trip through `raw()` and back previously appeared to lose that precision in the Python version. The C version is always derived from the raw version, which is why it showed that loss immediately. I did have an implementation of the Python version that was basically `self._elements = parseRaw(makeRaw(*elements))` but that seemed needlessly expensive, though that may be premature optimization. Would you prefer that? Or can you suggest a different approach?
mgedmin: > That's essentially what happens in the raw bytes format

Ah, does the raw bytes version store an integer number of microseconds?  I should've refreshed my memory before attempting to review code.

> self._elements = parseRaw(makeRaw(*elements))

I do actually prefer that (with a comment explaining that this is done to discard extra precision that wouldn't be preserved in the raw format).

(TBH the thing I would prefer _most_ is for somebody smarter than me to review this PR.)
jamadden: > 

It does, yes. 

Python:
```python
def _makeRaw(year, month, day, hour, minute, second):
    a = (((year - 1900) * 12 + month - 1) * 31 + day - 1)
    a = (a * 24 + hour) * 60 + minute
    b = int(second / _SCONV) # Don't round() this; the C version does simple truncation
    return struct.pack('>II', a, b)
```

C:
```C
PyObject *
TimeStamp_FromDate(int year, int month, int day, int hour, int min,
           double sec)
{
    TimeStamp *ts = NULL;
    //...
    /// ts->data is unsigned char[]
    sec /= SCONV;
    v = (unsigned int)sec;
    ts->data[4] = v / 16777216;
    ts->data[5] = (v % 16777216) / 65536;
    ts->data[6] = (v % 65536) / 256;
    ts->data[7] = v % 256;
    //...
}
```

> I do actually prefer that (with a comment explaining that this is done to discard extra precision that wouldn't be preserved in the raw format).

I can go back to that in the constructor. That's slightly closer parity with C. But I think I would still need a `round()` call in the `seconds()` accessor: [the C version needed that](https://github.com/zopefoundation/persistent/pull/83/files#diff-6a6e068aef7fec9e0c363cbce457b2a9R212).  The problem, I think, is that the storage format is lossy, and without the `round()` sometimes the results don't make sense (they're not clearly derived from the input).
jamadden: >  But I think I would still need a round() call in the seconds() accessor: the C version needed that.

No, the C version needed that precisely because the constructor doesn't round-trip through raw().

FWIW, this is a place where the compiler flag `-ffast-math` breaks things. The tests weren't passing for me this morning (specifically, 6.5555 was producing 6.555499999999999 in the C version), and it turned out to be because I compiled with `-ffast-math`.
jamadden: >> But I think I would still need a round() call in the seconds() accessor: the C version needed that.

> No, the C version needed that precisely because the constructor doesn't round-trip through raw().

Once again, I am wrong. The C version always constructs the double value from its raw bytes, which don't change across trips through raw():
```C
    unsigned int v;
    double sec;

    v = (self->data[4] * 16777216 + self->data[5] * 65536
     + self->data[6] * 256 + self->data[7]);
    sec = SCONV * (double)v;
```

The Python version explicitly calls `round()`  when it parses raw bytes, so that's why the C version needs to do so as well. They either both need to or both shouldn't. If they both *do not* call `round` at all, then there is a single test failure in the Python implementation: `TimeStamp(2011, 2, 16, 14, 37, 22.80544).timeTime()` produces 1297867042.805439 instead of 1297867042.80544. That can be fixed with a change to `_makeUTC`.
jamadden: ping :) 
diff --git a/CHANGES.rst b/CHANGES.rst
index 956c0a5..469c538 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -4,12 +4,6 @@
 4.3.1 (unreleased)
 ------------------
 
-- Change the default representation of ``Persistent`` objects to
-  include the representation of their OID and jar, if set. Also add
-  the ability for subclasses to implement ``_p_repr()`` instead of
-  overriding ``__repr__`` for better exception handling. See `issue 11
-  <https://github.com/zopefoundation/persistent/issues/11>`_.
-
 - Reach and maintain 100% test coverage.
 
 - Simplify ``__init__.py``, including removal of an attempted legacy
@@ -37,6 +31,15 @@
 - Remove some internal compatibility shims that are no longer
   necessary. See `PR 82 <https://github.com/zopefoundation/persistent/pull/82>`_.
 
+- Make the return value of ``TimeStamp.second()`` consistent across C
+  and Python implementations when the ``TimeStamp`` was created from 6
+  arguments with floating point seconds. Also make it match across
+  trips through ``TimeStamp.raw()``. Previously, the C version could
+  initially have erroneous rounding and too much false precision,
+  while the Python version could have too much precision. The raw/repr
+  values have not changed. See `issue 41
+  <https://github.com/zopefoundation/persistent/issues/41>`_.
+
 4.3.0 (2018-07-30)
 ------------------
 
diff --git a/docs/using.rst b/docs/using.rst
index 417b25e..5803d7e 100644
--- a/docs/using.rst
+++ b/docs/using.rst
@@ -1,10 +1,9 @@
-=============================================
- Using :mod:`persistent` in your application
-=============================================
+Using :mod:`persistent` in your application
+===========================================
 
 
 Inheriting from :class:`persistent.Persistent`
-==============================================
+----------------------------------------------
 
 The basic mechanism for making your application's objects persistent
 is mix-in interitance.  Instances whose classes derive from
@@ -15,7 +14,7 @@ they have been changed.
 
 
 Relationship to a Data Manager and its Cache
-============================================
+--------------------------------------------
 
 Except immediately after their creation, persistent objects are normally
 associated with a :term:`data manager` (also referred to as a :term:`jar`).
@@ -64,7 +63,7 @@ The examples below use a stub data manager class, and its stub cache class:
 
 
 Persistent objects without a Data Manager
-=========================================
+-----------------------------------------
 
 Before aersistent instance has been associtated with a a data manager (
 i.e., its ``_p_jar`` is still ``None``).
@@ -167,7 +166,7 @@ Try all sorts of different ways to change the object's state:
 
 
 Associating an Object with a Data Manager
-=========================================
+-----------------------------------------
 
 Once associated with a data manager, a persistent object's behavior changes:
 
@@ -220,7 +219,7 @@ control the state as described below, or use a
 :class:`~.PersistentList` or :class:`~.PersistentMapping`.
 
 Explicitly controlling ``_p_state``
-===================================
+-----------------------------------
 
 Persistent objects expose three methods for moving an object into and out
 of the "ghost" state::  :meth:`persistent.Persistent._p_activate`,
@@ -329,7 +328,7 @@ which is exactly the same as calling ``_p_activate``:
 
 
 The pickling protocol
-=====================
+---------------------
 
 Because persistent objects need to control how they are pickled and
 unpickled, the :class:`persistent.Persistent` base class overrides
@@ -383,7 +382,7 @@ The ``_p_serial`` attribute is not affected by calling setstate.
 
 
 Estimated Object Size
-=====================
+---------------------
 
 We can store a size estimation in ``_p_estimated_size``. Its default is 0.
 The size estimation can be used by a cache associated with the data manager
@@ -413,7 +412,7 @@ Of course, the estimated size must not be negative.
 
 
 Overriding the attribute protocol
-=================================
+---------------------------------
 
 Subclasses which override the attribute-management methods provided by
 :class:`persistent.Persistent`, but must obey some constraints:
@@ -449,24 +448,3 @@ Subclasses which override the attribute-management methods provided by
 :meth:`__getattr__`
   For the ``__getattr__`` method, the behavior is like that for regular Python
   classes and for earlier versions of ZODB 3.
-
-
-Implementing ``_p_repr``
-========================
-
-Subclasses can implement ``_p_repr`` to provide a custom
-representation. If this method raises an exception, the default
-representation will be used. The benefit of implementing ``_p_repr``
-instead of overriding ``__repr__`` is that it provides safer handling
-for objects that can't be activated because their persistent data is
-missing or their jar is closed.
-
-.. doctest::
-
-   >>> class P(Persistent):
-   ...    def _p_repr(self):
-   ...        return "Custom repr"
-
-   >>> p = P()
-   >>> print(repr(p))
-   Custom repr
diff --git a/persistent/cPersistence.c b/persistent/cPersistence.c
index 9e0f3ae..131dd71 100644
--- a/persistent/cPersistence.c
+++ b/persistent/cPersistence.c
@@ -1372,101 +1372,6 @@ Per_set_sticky(cPersistentObject *self, PyObject* value)
     return 0;
 }
 
-static PyObject*
-repr_format_exception(char* format)
-{
-    /* If an exception we should catch occurred, return a new
-       string of its repr. Otherwise, return NULL. */
-    PyObject *exc_t;
-    PyObject *exc_v;
-    PyObject *exc_tb;
-    PyObject *result = NULL;
-
-    if (PyErr_Occurred() && PyErr_ExceptionMatches(PyExc_Exception))
-    {
-        PyErr_Fetch(&exc_t, &exc_v, &exc_tb);
-        PyErr_NormalizeException(&exc_t, &exc_v, &exc_tb);
-        PyErr_Clear();
-
-        result = PyUnicode_FromFormat(format, exc_v);
-        Py_DECREF(exc_t);
-        Py_DECREF(exc_v);
-        Py_DECREF(exc_tb);
-    }
-    return result;
-}
-
-static PyObject*
-repr_helper(PyObject *o, char* format)
-{
-    /* Returns a new reference, or NULL on error */
-    PyObject *result;
-
-    if (o)
-    {
-        result = PyUnicode_FromFormat(format, o);
-        if (!result)
-            result = repr_format_exception(format);
-    }
-    else
-    {
-        result = PyUnicode_FromString("");
-    }
-
-    return result;
-
-}
-
-static PyObject*
-Per_repr(cPersistentObject *self)
-{
-    PyObject *prepr = NULL;
-    PyObject *prepr_exc_str = NULL;
-
-    PyObject *oid_str = NULL;
-    PyObject *jar_str = NULL;
-    PyObject *result = NULL;
-
-    prepr = PyObject_GetAttrString((PyObject*)Py_TYPE(self), "_p_repr");
-    if (prepr)
-    {
-        result = PyObject_CallFunctionObjArgs(prepr, self, NULL);
-        if (result)
-            goto cleanup;
-        else
-        {
-            prepr_exc_str = repr_format_exception(" _p_repr %R");
-            if (!prepr_exc_str)
-                goto cleanup;
-        }
-    }
-    else
-    {
-        PyErr_Clear();
-        prepr_exc_str = PyUnicode_FromString("");
-    }
-
-    oid_str = repr_helper(self->oid, " oid %R");
-    if (!oid_str)
-        goto cleanup;
-
-    jar_str = repr_helper(self->jar, " in %R");
-    if (!jar_str)
-        goto cleanup;
-
-    result = PyUnicode_FromFormat("<%s object at %p%S%S%S>",
-                                  Py_TYPE(self)->tp_name, self,
-                                  oid_str, jar_str, prepr_exc_str);
-
-cleanup:
-    Py_XDECREF(prepr);
-    Py_XDECREF(prepr_exc_str);
-    Py_XDECREF(oid_str);
-    Py_XDECREF(jar_str);
-
-    return result;
-}
-
 static PyGetSetDef Per_getsets[] = {
   {"_p_changed", (getter)Per_get_changed, (setter)Per_set_changed},
   {"_p_jar", (getter)Per_get_jar, (setter)Per_set_jar},
@@ -1549,7 +1454,7 @@ static PyTypeObject Pertype = {
   0,                                /* tp_getattr */
   0,                                /* tp_setattr */
   0,                                /* tp_compare */
-  (reprfunc)Per_repr,               /* tp_repr */
+  0,                                /* tp_repr */
   0,                                /* tp_as_number */
   0,                                /* tp_as_sequence */
   0,                                /* tp_as_mapping */
diff --git a/persistent/interfaces.py b/persistent/interfaces.py
index 61ed594..69b7bad 100644
--- a/persistent/interfaces.py
+++ b/persistent/interfaces.py
@@ -166,14 +166,6 @@ class IPersistent(Interface):
     these objects are invalidated, they immediately reload their state
     from their data manager, and are then in the saved state.
 
-    reprs
-
-    By default, persistent objects include the reprs of their
-    _p_oid and _p_jar, if any, in their repr. If a subclass implements
-    the optional method ``_p_repr``, it will be called and its results returned
-    instead of the default repr; if this method raises an exception, that
-    exception will be caught and its repr included in the default repr.
-
     """
 
     _p_jar = Attribute(
@@ -322,10 +314,10 @@ class IPersistent(Interface):
 
     def _p_getattr(name):
         """Test whether the base class must handle the name
-
+   
         The method unghostifies the object, if necessary.
         The method records the object access, if necessary.
-
+ 
         This method should be called by subclass __getattribute__
         implementations before doing anything else. If the method
         returns True, then __getattribute__ implementations must delegate
@@ -479,7 +471,7 @@ class IPickleCache(Interface):
         """ Perform an incremental garbage collection sweep.
 
         o Reduce number of non-ghosts to 'cache_size', if possible.
-
+        
         o Ghostify in LRU order.
 
         o Skip dirty or sticky objects.
@@ -513,7 +505,7 @@ class IPickleCache(Interface):
 
         If the object's '_p_jar' is not None, raise.
 
-        If 'oid' is already in the cache, raise.
+        If 'oid' is already in the cache, raise. 
         """
 
     def reify(to_reify):
@@ -544,7 +536,7 @@ class IPickleCache(Interface):
         o Any OID corresponding to a p-class will cause the corresponding
             p-class to be removed from the cache.
 
-        o For all other OIDs, ghostify the corrsponding object and
+        o For all other OIDs, ghostify the corrsponding object and 
             remove it from the ring.
         """
 
diff --git a/persistent/persistence.py b/persistent/persistence.py
index 8d72ce1..7bf0508 100644
--- a/persistent/persistence.py
+++ b/persistent/persistence.py
@@ -11,7 +11,7 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
-
+import sys
 
 from zope.interface import implementer
 
@@ -20,13 +20,14 @@ from persistent.interfaces import GHOST
 from persistent.interfaces import UPTODATE
 from persistent.interfaces import CHANGED
 from persistent.interfaces import STICKY
-
+from persistent.interfaces import OID_TYPE
 from persistent.interfaces import SERIAL_TYPE
 from persistent.timestamp import TimeStamp
 from persistent.timestamp import _ZERO
 from persistent._compat import copy_reg
 from persistent._compat import intern
 
+from . import ring
 
 _INITIAL_SERIAL = _ZERO
 
@@ -557,39 +558,6 @@ class Persistent(object):
         if cache is not None:
             return cache.get(oid) is self
 
-    def __repr__(self):
-        p_repr_str = ''
-        p_repr = getattr(type(self), '_p_repr', None)
-        if p_repr is not None:
-            try:
-                return p_repr(self)
-            except Exception as e:
-                p_repr_str = ' _p_repr %r' % (e,)
-
-        oid = _OGA(self, '_Persistent__oid')
-        jar = _OGA(self, '_Persistent__jar')
-
-        oid_str = ''
-        jar_str = ''
-
-        if oid is not None:
-            try:
-                oid_str = ' oid %r' % (oid,)
-            except Exception as e:
-                oid_str = ' oid %r' % (e,)
-
-        if jar is not None:
-            try:
-                jar_str = ' in %r' % (jar,)
-            except Exception as e:
-                jar_str = ' in %r' % (e,)
-
-        return '<%s.%s object at 0x%x%s%s%s>' % (
-            type(self).__module__, type(self).__name__, id(self),
-            oid_str, jar_str, p_repr_str
-        )
-
-
 def _estimated_size_in_24_bits(value):
     if value > 1073741696:
         return 16777215
diff --git a/persistent/timestamp.py b/persistent/timestamp.py
index 5da8535..a031a72 100644
--- a/persistent/timestamp.py
+++ b/persistent/timestamp.py
@@ -53,6 +53,7 @@ class _UTC(datetime.tzinfo):
         return dt
 
 def _makeUTC(y, mo, d, h, mi, s):
+    s = round(s, 6) # microsecond precision, to match the C implementation
     usec, sec = math.modf(s)
     sec = int(sec)
     usec = int(usec * 1e6)
@@ -75,7 +76,7 @@ def _parseRaw(octets):
     day = a // (60 * 24) % 31 + 1
     month = a // (60 * 24 * 31) % 12 + 1
     year = a // (60 * 24 * 31 * 12) + 1900
-    second = round(b * _SCONV, 6) #microsecond precision
+    second = b * _SCONV
     return (year, month, day, hour, minute, second)
 
 
@@ -83,6 +84,7 @@ class pyTimeStamp(object):
     __slots__ = ('_raw', '_elements')
 
     def __init__(self, *args):
+        self._elements = None
         if len(args) == 1:
             raw = args[0]
             if not isinstance(raw, _RAWTYPE):
@@ -90,14 +92,18 @@ class pyTimeStamp(object):
             if len(raw) != 8:
                 raise TypeError('Raw must be 8 octets')
             self._raw = raw
-            self._elements = _parseRaw(raw)
         elif len(args) == 6:
             self._raw = _makeRaw(*args)
-            self._elements = args
+            # Note that we don't preserve the incoming arguments in self._elements,
+            # we derive them from the raw value. This is because the incoming
+            # seconds value could have more precision than would survive
+            # in the raw data, so we must be consistent.
         else:
             raise TypeError('Pass either a single 8-octet arg '
                             'or 5 integers and a float')
 
+        self._elements = _parseRaw(self._raw)
+
     def raw(self):
         return self._raw
 

pyTimeStamp and TimeStamp have different sub-second precision
I don't think this is correct:

```
>>> from persistent.timestamp import TimeStamp, pyTimeStamp
>>> ts1 = TimeStamp(2001, 2, 3, 4, 5, 6.123456789)
>>> ts2 = pyTimeStamp(2001, 2, 3, 4, 5, 6.123456789)
>>> ts1 == ts2
True
>>> ts1.second() == ts2.second()
False
>>> ts1.second()
6.1234567780047655
>>> ts2.second()
6.123456789
```

diff --git a/persistent/tests/test_persistence.py b/persistent/tests/test_persistence.py
index 9ded7e2..3ce52e7 100644
--- a/persistent/tests/test_persistence.py
+++ b/persistent/tests/test_persistence.py
@@ -11,31 +11,24 @@
 # FOR A PARTICULAR PURPOSE.
 #
 ##############################################################################
+import os
+import unittest
 
 import platform
-import re
 import sys
-import unittest
 
-import persistent
 from persistent._compat import copy_reg
 
+py_impl = getattr(platform, 'python_implementation', lambda: None)
+_is_pypy3 = py_impl() == 'PyPy' and sys.version_info[0] > 2
+_is_jython = py_impl() == 'Jython'
 
-_is_pypy3 = platform.python_implementation() == 'PyPy' and sys.version_info[0] > 2
-_is_jython = platform.python_implementation() == 'Jython'
-
-# pylint:disable=R0904,W0212,E1101
+#pylint: disable=R0904,W0212,E1101
 # pylint:disable=attribute-defined-outside-init,too-many-lines
-# pylint:disable=blacklisted-name,useless-object-inheritance
+# pylint:disable=blacklisted-name
 # Hundreds of unused jar and OID vars make this useless
 # pylint:disable=unused-variable
 
-def skipIfNoCExtension(o):
-    return unittest.skipIf(
-        persistent._cPersistence is None,
-        "The C extension is not available")(o)
-
-
 class _Persistent_Base(object):
 
     # py2/3 compat
@@ -1622,7 +1615,7 @@ class _Persistent_Base(object):
             def __setattr__(self, name, value):
                 raise AssertionError("Should not be called")
         inst = subclass()
-        self.assertEqual(object.__getattribute__(inst, '_v_setattr_called'), False)
+        self.assertEqual(object.__getattribute__(inst,'_v_setattr_called'), False)
 
     def test_can_set__p_attrs_if_subclass_denies_setattr(self):
         # ZODB defines a PersistentBroken subclass that only lets us
@@ -1671,7 +1664,7 @@ class _Persistent_Base(object):
         self.assertEqual(candidate._p_state, UPTODATE)
         cache.new_ghost(KEY, candidate)
 
-        self.assertIs(cache.get(KEY), candidate)
+        self.assertTrue(cache.get(KEY) is candidate)
         self.assertEqual(candidate._p_oid, KEY)
         self.assertEqual(candidate._p_state, GHOST)
         self.assertEqual(candidate.set_by_new, 1)
@@ -1692,192 +1685,11 @@ class _Persistent_Base(object):
         self.assertEqual(candidate._p_state, UPTODATE)
         cache.new_ghost(KEY, candidate)
 
-        self.assertIs(cache.get(KEY), candidate)
+        self.assertTrue(cache.get(KEY) is candidate)
         self.assertEqual(candidate._p_oid, KEY)
         self.assertEqual(candidate._p_state, GHOST)
         self.assertEqual(candidate.set_by_new, 1)
 
-    def _normalize_repr(self, r):
-        # Pure-python vs C
-        r = r.replace('persistent.persistence.Persistent', 'persistent.Persistent')
-        r = r.replace("persistent.tests.test_persistence.", '')
-        # addresses
-        r = re.sub(r'0x[0-9a-fA-F]*', '0xdeadbeef', r)
-        # Python 3.7 removed the trailing , in exception reprs
-        r = r.replace("',)", "')")
-        # Python 2 doesn't have a leading b prefix for byte literals
-        r = r.replace("oid '", "oid b'")
-        return r
-
-    def _normalized_repr(self, o):
-        return self._normalize_repr(repr(o))
-
-    def test_repr_no_oid_no_jar(self):
-        p = self._makeOne()
-        result = self._normalized_repr(p)
-        self.assertEqual(result, '<persistent.Persistent object at 0xdeadbeef>')
-
-    def test_repr_no_oid_in_jar(self):
-        p = self._makeOne()
-
-        class Jar(object):
-            def __repr__(self):
-                return '<SomeJar>'
-
-        p._p_jar = Jar()
-
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<persistent.Persistent object at 0xdeadbeef in <SomeJar>>")
-
-    def test_repr_oid_no_jar(self):
-        p = self._makeOne()
-        p._p_oid = b'12345678'
-
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<persistent.Persistent object at 0xdeadbeef oid b'12345678'>")
-
-    def test_repr_no_oid_repr_jar_raises_exception(self):
-        p = self._makeOne()
-
-        class Jar(object):
-            def __repr__(self):
-                raise Exception('jar repr failed')
-
-        p._p_jar = Jar()
-
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<persistent.Persistent object at 0xdeadbeef in Exception('jar repr failed')>")
-
-
-    def test_repr_oid_raises_exception_no_jar(self):
-        p = self._makeOne()
-
-        class BadOID(bytes):
-            def __repr__(self):
-                raise Exception("oid repr failed")
-        p._p_oid = BadOID(b'12345678')
-
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<persistent.Persistent object at 0xdeadbeef oid Exception('oid repr failed')>")
-
-
-    def test_repr_oid_and_jar_raise_exception(self):
-        p = self._makeOne()
-
-        class BadOID(bytes):
-            def __repr__(self):
-                raise Exception("oid repr failed")
-        p._p_oid = BadOID(b'12345678')
-
-        class Jar(object):
-            def __repr__(self):
-                raise Exception('jar repr failed')
-
-        p._p_jar = Jar()
-
-
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<persistent.Persistent object at 0xdeadbeef oid Exception('oid repr failed')"
-            " in Exception('jar repr failed')>")
-
-    def test_repr_no_oid_repr_jar_raises_baseexception(self):
-        p = self._makeOne()
-
-        class Jar(object):
-            def __repr__(self):
-                raise BaseException('jar repr failed')
-
-        p._p_jar = Jar()
-        with self.assertRaisesRegex(BaseException, 'jar repr failed'):
-            repr(p)
-
-    def test_repr_oid_raises_baseexception_no_jar(self):
-        p = self._makeOne()
-
-        class BadOID(bytes):
-            def __repr__(self):
-                raise BaseException("oid repr failed")
-        p._p_oid = BadOID(b'12345678')
-
-        with self.assertRaisesRegex(BaseException, 'oid repr failed'):
-            repr(p)
-
-    def test_repr_oid_and_jar(self):
-        p = self._makeOne()
-        p._p_oid = b'12345678'
-
-        class Jar(object):
-            def __repr__(self):
-                return '<SomeJar>'
-
-        p._p_jar = Jar()
-
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<persistent.Persistent object at 0xdeadbeef oid b'12345678' in <SomeJar>>")
-
-    def test__p_repr(self):
-        class P(self._getTargetClass()):
-            def _p_repr(self):
-                return "Override"
-        p = P()
-        self.assertEqual("Override", repr(p))
-
-    def test__p_repr_exception(self):
-        class P(self._getTargetClass()):
-            def _p_repr(self):
-                raise Exception("_p_repr failed")
-        p = P()
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<P object at 0xdeadbeef"
-            " _p_repr Exception('_p_repr failed')>")
-
-        p._p_oid = b'12345678'
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<P object at 0xdeadbeef oid b'12345678'"
-            " _p_repr Exception('_p_repr failed')>")
-
-        class Jar(object):
-            def __repr__(self):
-                return '<SomeJar>'
-
-        p._p_jar = Jar()
-        result = self._normalized_repr(p)
-        self.assertEqual(
-            result,
-            "<P object at 0xdeadbeef oid b'12345678'"
-            " in <SomeJar> _p_repr Exception('_p_repr failed')>")
-
-    def test__p_repr_in_instance_ignored(self):
-        class P(self._getTargetClass()):
-            pass
-        p = P()
-        p._p_repr = lambda: "Instance"
-        result = self._normalized_repr(p)
-        self.assertEqual(result, '<P object at 0xdeadbeef>')
-
-    def test__p_repr_baseexception(self):
-        class P(self._getTargetClass()):
-            def _p_repr(self):
-                raise BaseException("_p_repr failed")
-        p = P()
-        with self.assertRaisesRegex(BaseException, '_p_repr failed'):
-            repr(p)
 
 class PyPersistentTests(unittest.TestCase, _Persistent_Base):
 
@@ -1989,39 +1801,47 @@ class PyPersistentTests(unittest.TestCase, _Persistent_Base):
         inst._Persistent__flags = None
         inst._p_accessed()
 
+_add_to_suite = [PyPersistentTests]
 
-@skipIfNoCExtension
-class CPersistentTests(unittest.TestCase, _Persistent_Base):
+if not os.environ.get('PURE_PYTHON'):
+    try:
+        from persistent import cPersistence
+    except ImportError: # pragma: no cover
+        pass
+    else:
+        class CPersistentTests(unittest.TestCase, _Persistent_Base):
 
-    def _getTargetClass(self):
-        from persistent.cPersistence import Persistent
-        return Persistent
+            def _getTargetClass(self):
+                from persistent.cPersistence import Persistent
+                return Persistent
 
-    def _checkMRU(self, jar, value):
-        pass # Figure this out later
+            def _checkMRU(self, jar, value):
+                pass # Figure this out later
 
-    def _clearMRU(self, jar):
-        pass # Figure this out later
+            def _clearMRU(self, jar):
+                pass # Figure this out later
 
-    def _makeCache(self, jar):
-        from persistent.cPickleCache import PickleCache
-        return PickleCache(jar)
+            def _makeCache(self, jar):
+                from persistent.cPickleCache import PickleCache
+                return PickleCache(jar)
+
+        _add_to_suite.append(CPersistentTests)
 
+        class Test_simple_new(unittest.TestCase):
 
-@skipIfNoCExtension
-class Test_simple_new(unittest.TestCase):
+            def _callFUT(self, x):
+                from persistent.cPersistence import simple_new
+                return simple_new(x)
 
-    def _callFUT(self, x):
-        from persistent.cPersistence import simple_new
-        return simple_new(x)
+            def test_w_non_type(self):
+                self.assertRaises(TypeError, self._callFUT, '')
 
-    def test_w_non_type(self):
-        self.assertRaises(TypeError, self._callFUT, '')
+            def test_w_type(self):
+                TO_CREATE = [type, list, tuple, object, dict]
+                for typ in TO_CREATE:
+                    self.assertTrue(isinstance(self._callFUT(typ), typ))
 
-    def test_w_type(self):
-        TO_CREATE = [type, list, tuple, object, dict]
-        for typ in TO_CREATE:
-            self.assertTrue(isinstance(self._callFUT(typ), typ))
+        _add_to_suite.append(Test_simple_new)
 
 def test_suite():
-    return unittest.defaultTestLoader.loadTestsFromName(__name__)
+    return unittest.TestSuite([unittest.makeSuite(x) for x in _add_to_suite])
diff --git a/persistent/tests/test_timestamp.py b/persistent/tests/test_timestamp.py
index cc1253c..ff8b6a9 100644
--- a/persistent/tests/test_timestamp.py
+++ b/persistent/tests/test_timestamp.py
@@ -17,6 +17,8 @@ import sys
 MAX_32_BITS = 2 ** 31 - 1
 MAX_64_BITS = 2 ** 63 - 1
 
+import persistent.timestamp
+
 class Test__UTC(unittest.TestCase):
 
     def _getTargetClass(self):
@@ -202,7 +204,8 @@ class TimeStampTests(pyTimeStampTests):
         from persistent.timestamp import TimeStamp
         return TimeStamp
 
-
+@unittest.skipIf(persistent.timestamp.CTimeStamp is None,
+                 "CTimeStamp not available")
 class PyAndCComparisonTests(unittest.TestCase):
     """
     Compares C and Python implementations.
@@ -254,7 +257,6 @@ class PyAndCComparisonTests(unittest.TestCase):
 
     def test_equal(self):
         c, py = self._make_C_and_Py(*self.now_ts_args)
-
         self.assertEqual(c, py)
 
     def test_hash_equal(self):
@@ -396,22 +398,32 @@ class PyAndCComparisonTests(unittest.TestCase):
         self.assertTrue(big_c != small_py)
         self.assertTrue(small_py != big_c)
 
+    def test_seconds_precision(self, seconds=6.123456789):
+        # https://github.com/zopefoundation/persistent/issues/41
+        args = (2001, 2, 3, 4, 5, seconds)
+        c = self._makeC(*args)
+        py = self._makePy(*args)
 
-def test_suite():
-    suite = [
-        unittest.makeSuite(Test__UTC),
-        unittest.makeSuite(pyTimeStampTests),
-        unittest.makeSuite(TimeStampTests),
-    ]
+        self.assertEqual(c, py)
+        self.assertEqual(c.second(), py.second())
+
+        py2 = self._makePy(c.raw())
+        self.assertEqual(py2, c)
+
+        c2 = self._makeC(c.raw())
+        self.assertEqual(c2, c)
+
+    def test_seconds_precision_half(self):
+        # make sure our rounding matches
+        self.test_seconds_precision(seconds=6.5)
+        self.test_seconds_precision(seconds=6.55)
+        self.test_seconds_precision(seconds=6.555)
+        self.test_seconds_precision(seconds=6.5555)
+        self.test_seconds_precision(seconds=6.55555)
+        self.test_seconds_precision(seconds=6.555555)
+        self.test_seconds_precision(seconds=6.5555555)
+        self.test_seconds_precision(seconds=6.55555555)
+        self.test_seconds_precision(seconds=6.555555555)
 
-    try:
-        from persistent.timestamp import pyTimeStamp
-        from persistent.timestamp import TimeStamp
-    except ImportError: # pragma: no cover
-        pass
-    else:
-        if pyTimeStamp != TimeStamp:
-            # We have both implementations available
-            suite.append(unittest.makeSuite(PyAndCComparisonTests))
-
-    return unittest.TestSuite(suite)
+def test_suite():
+    return unittest.defaultTestLoader.loadTestsFromName(__name__)

pip install -e .[test]
parse_log_pytest
requirements.txt
cffi zope.testrunner pytest
apt-get update apt-get install -y gcc
3.7
requirements/base.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
certifi @ file:///croot/certifi_1671487769961/work/certifi
cffi==1.15.1
exceptiongroup==1.2.2
importlib-metadata==6.7.0
iniconfig==2.0.0
manuel==1.13.0
packaging==24.0
-e git+https://github.com/zopefoundation/persistent.git@aa6048a342d91656f3d1be6ff04bd1815e191a04#egg=persistent
pluggy==1.2.0
pycparser==2.21
pytest==7.4.4
tomli==2.0.1
typing_extensions==4.7.1
zipp==3.15.0
zope.exceptions==5.1
zope.interface==6.4.post2
zope.testrunner==6.5

name: persistent
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - certifi=2022.12.7=py37h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=1.1.1w=h7f8727e_0
  - pip=22.3.1=py37h06a4308_0
  - python=3.7.16=h7a1cb2a_0
  - readline=8.2=h5eee18b_0
  - setuptools=65.6.3=py37h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - wheel=0.38.4=py37h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - cffi==1.15.1
      - exceptiongroup==1.2.2
      - importlib-metadata==6.7.0
      - iniconfig==2.0.0
      - manuel==1.13.0
      - packaging==24.0
      - pluggy==1.2.0
      - pycparser==2.21
      - pytest==7.4.4
      - tomli==2.0.1
      - typing-extensions==4.7.1
      - zipp==3.15.0
      - zope-exceptions==5.1
      - zope-interface==6.4.post2
      - zope-testrunner==6.5
prefix: /opt/conda/envs/persistent

persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_seconds_precision persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_seconds_precision_half
persistent/tests/test_persistence.py::PyPersistentTests::test___delattr___p__names persistent/tests/test_persistence.py::PyPersistentTests::test___delattr__normal_name_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test___delattr__normal_name_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test___delattr__normal_name_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test___delattr__normal_name_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute___non_cooperative persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute___p__names persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute__normal_name_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute__normal_name_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute__normal_name_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute__normal_name_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test___getattribute__special_name persistent/tests/test_persistence.py::PyPersistentTests::test___getstate__ persistent/tests/test_persistence.py::PyPersistentTests::test___getstate___derived_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test___getstate___derived_w_slots persistent/tests/test_persistence.py::PyPersistentTests::test___getstate___derived_w_slots_in_base_and_derived persistent/tests/test_persistence.py::PyPersistentTests::test___getstate___derived_w_slots_in_base_but_not_derived persistent/tests/test_persistence.py::PyPersistentTests::test___reduce__ persistent/tests/test_persistence.py::PyPersistentTests::test___reduce__w_subclass_having_getnewargs persistent/tests/test_persistence.py::PyPersistentTests::test___reduce__w_subclass_having_getnewargs_and_getstate persistent/tests/test_persistence.py::PyPersistentTests::test___reduce__w_subclass_having_getstate persistent/tests/test_persistence.py::PyPersistentTests::test___setattr___p__names persistent/tests/test_persistence.py::PyPersistentTests::test___setattr___v__name persistent/tests/test_persistence.py::PyPersistentTests::test___setattr__normal_name_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test___setattr__normal_name_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test___setattr__normal_name_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test___setattr__normal_name_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___derived_w_slots persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___derived_w_slots_in_base_but_not_derived persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___derived_w_slots_in_base_classes persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___doesnt_fail_on_non_dict persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___doesnt_fail_on_non_string_keys persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___empty persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___interns_dict_keys persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___nonempty persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___nonempty_derived_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test___setstate___nonempty_derived_w_dict_w_two_keys persistent/tests/test_persistence.py::PyPersistentTests::test__ancient_dict_layout_bug persistent/tests/test_persistence.py::PyPersistentTests::test__p_activate_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test__p_activate_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test__p_activate_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test__p_activate_leaves_object_in_saved_even_if_object_mutated_self persistent/tests/test_persistence.py::PyPersistentTests::test__p_activate_only_sets_state_once persistent/tests/test_persistence.py::PyPersistentTests::test__p_activate_w_broken_jar persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_changed_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_saved_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_from_unsaved_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_deactivate_when_sticky persistent/tests/test_persistence.py::PyPersistentTests::test__p_delattr_w__p__names persistent/tests/test_persistence.py::PyPersistentTests::test__p_delattr_w_normal_name persistent/tests/test_persistence.py::PyPersistentTests::test__p_getattr_w__p__names persistent/tests/test_persistence.py::PyPersistentTests::test__p_getattr_w_normal_name persistent/tests/test_persistence.py::PyPersistentTests::test__p_getattr_w_special_names persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_changed_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_changed_w_slots persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_changed_w_slots_compat persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_saved_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_sticky persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_sticky_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test__p_invalidate_from_unsaved_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test__p_mtime_activates_object persistent/tests/test_persistence.py::PyPersistentTests::test__p_mtime_no_serial persistent/tests/test_persistence.py::PyPersistentTests::test__p_mtime_w_serial persistent/tests/test_persistence.py::PyPersistentTests::test__p_setattr_w__p__name persistent/tests/test_persistence.py::PyPersistentTests::test__p_setattr_w_normal_name persistent/tests/test_persistence.py::PyPersistentTests::test__p_state_changed persistent/tests/test_persistence.py::PyPersistentTests::test__p_state_changed_sticky persistent/tests/test_persistence.py::PyPersistentTests::test__p_state_ghost persistent/tests/test_persistence.py::PyPersistentTests::test__p_state_saved persistent/tests/test_persistence.py::PyPersistentTests::test__p_state_saved_sticky persistent/tests/test_persistence.py::PyPersistentTests::test__p_state_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test__p_status_changed persistent/tests/test_persistence.py::PyPersistentTests::test__p_status_changed_sticky persistent/tests/test_persistence.py::PyPersistentTests::test__p_status_ghost persistent/tests/test_persistence.py::PyPersistentTests::test__p_status_saved persistent/tests/test_persistence.py::PyPersistentTests::test__p_status_saved_sticky persistent/tests/test_persistence.py::PyPersistentTests::test__p_status_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test_accessed_invalidated_with_jar_and_oid_but_no_cache persistent/tests/test_persistence.py::PyPersistentTests::test_accessed_with_jar_and_oid_but_not_in_cache persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_false_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_false_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_false_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_false_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_none_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_none_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_none_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_none_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_none_when_sticky persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_true_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_true_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_true_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_changed_true_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_estimated_size_bigger persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_estimated_size_just_over_threshold persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_estimated_size_negative persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_estimated_size_small persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_estimated_size_wrong_type persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_jar_not_in_cache_allowed persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_jar_w_new_jar persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_jar_w_valid_jar persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_oid_not_in_cache_allowed persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_oid_w_None_wo_jar persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_oid_w_invalid_oid persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_oid_w_new_oid_w_jar persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_oid_w_new_oid_wo_jar persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_oid_w_valid_oid persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_serial_too_long persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_serial_too_short persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_serial_w_None persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_serial_w_invalid_type persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_serial_w_valid_serial persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_sticky_false_non_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_sticky_false_when_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_sticky_true_non_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_assign_p_sticky_true_when_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_can_set__p_attrs_if_subclass_denies_setattr persistent/tests/test_persistence.py::PyPersistentTests::test_class_conforms_to_IPersistent persistent/tests/test_persistence.py::PyPersistentTests::test_ctor persistent/tests/test_persistence.py::PyPersistentTests::test_del_jar_like_ZODB_abort persistent/tests/test_persistence.py::PyPersistentTests::test_del_jar_no_jar persistent/tests/test_persistence.py::PyPersistentTests::test_del_jar_of_inactive_object_that_has_no_state persistent/tests/test_persistence.py::PyPersistentTests::test_del_jar_while_in_cache persistent/tests/test_persistence.py::PyPersistentTests::test_del_oid_like_ZODB_abort persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_changed_from_changed persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_changed_from_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_changed_from_saved persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_changed_from_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_changed_from_unsaved_w_dict persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_changed_when_sticky persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_oid_of_subclass_calling_p_delattr persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_oid_w_jar persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_oid_wo_jar persistent/tests/test_persistence.py::PyPersistentTests::test_delete_p_serial persistent/tests/test_persistence.py::PyPersistentTests::test_instance_conforms_to_IPersistent persistent/tests/test_persistence.py::PyPersistentTests::test_new_ghost_success_not_already_ghost_dict persistent/tests/test_persistence.py::PyPersistentTests::test_new_ghost_success_not_already_ghost_slot persistent/tests/test_persistence.py::PyPersistentTests::test_p_accessed_with_jar_with_oid_as_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_p_accessed_with_jar_without_oid persistent/tests/test_persistence.py::PyPersistentTests::test_p_activate_with_jar_without_oid persistent/tests/test_persistence.py::PyPersistentTests::test_p_invalidate_calls_p_deactivate persistent/tests/test_persistence.py::PyPersistentTests::test_p_invalidate_with_slots_broken_jar persistent/tests/test_persistence.py::PyPersistentTests::test_pickle_roundtrip_simple persistent/tests/test_persistence.py::PyPersistentTests::test_pickle_roundtrip_w_getnewargs_and_getstate persistent/tests/test_persistence.py::PyPersistentTests::test_pickle_roundtrip_w_slots_and_empty_dict persistent/tests/test_persistence.py::PyPersistentTests::test_pickle_roundtrip_w_slots_and_filled_dict persistent/tests/test_persistence.py::PyPersistentTests::test_pickle_roundtrip_w_slots_filled_slot persistent/tests/test_persistence.py::PyPersistentTests::test_pickle_roundtrip_w_slots_missing_slot persistent/tests/test_persistence.py::PyPersistentTests::test_query_p_changed_changed persistent/tests/test_persistence.py::PyPersistentTests::test_query_p_changed_ghost persistent/tests/test_persistence.py::PyPersistentTests::test_query_p_changed_saved persistent/tests/test_persistence.py::PyPersistentTests::test_query_p_changed_unsaved persistent/tests/test_persistence.py::PyPersistentTests::test_query_p_estimated_size_del persistent/tests/test_persistence.py::PyPersistentTests::test_query_p_estimated_size_new persistent/tests/test_persistence.py::PyPersistentTests::test_set__p_changed_w_broken_jar persistent/tests/test_persistence.py::PyPersistentTests::test_setattr_in_subclass_is_not_called_creating_an_instance persistent/tests/test_persistence.py::PyPersistentTests::test_w_alternate_metaclass persistent/tests/test_persistence.py::PyPersistentTests::test_w_diamond_inheritance persistent/tests/test_persistence.py::CPersistentTests::test___delattr___p__names persistent/tests/test_persistence.py::CPersistentTests::test___delattr__normal_name_from_changed persistent/tests/test_persistence.py::CPersistentTests::test___delattr__normal_name_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test___delattr__normal_name_from_saved persistent/tests/test_persistence.py::CPersistentTests::test___delattr__normal_name_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test___getattribute___non_cooperative persistent/tests/test_persistence.py::CPersistentTests::test___getattribute___p__names persistent/tests/test_persistence.py::CPersistentTests::test___getattribute__normal_name_from_changed persistent/tests/test_persistence.py::CPersistentTests::test___getattribute__normal_name_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test___getattribute__normal_name_from_saved persistent/tests/test_persistence.py::CPersistentTests::test___getattribute__normal_name_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test___getattribute__special_name persistent/tests/test_persistence.py::CPersistentTests::test___getstate__ persistent/tests/test_persistence.py::CPersistentTests::test___getstate___derived_w_dict persistent/tests/test_persistence.py::CPersistentTests::test___getstate___derived_w_slots persistent/tests/test_persistence.py::CPersistentTests::test___getstate___derived_w_slots_in_base_and_derived persistent/tests/test_persistence.py::CPersistentTests::test___getstate___derived_w_slots_in_base_but_not_derived persistent/tests/test_persistence.py::CPersistentTests::test___reduce__ persistent/tests/test_persistence.py::CPersistentTests::test___reduce__w_subclass_having_getnewargs persistent/tests/test_persistence.py::CPersistentTests::test___reduce__w_subclass_having_getnewargs_and_getstate persistent/tests/test_persistence.py::CPersistentTests::test___reduce__w_subclass_having_getstate persistent/tests/test_persistence.py::CPersistentTests::test___setattr___p__names persistent/tests/test_persistence.py::CPersistentTests::test___setattr___v__name persistent/tests/test_persistence.py::CPersistentTests::test___setattr__normal_name_from_changed persistent/tests/test_persistence.py::CPersistentTests::test___setattr__normal_name_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test___setattr__normal_name_from_saved persistent/tests/test_persistence.py::CPersistentTests::test___setattr__normal_name_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test___setstate___derived_w_slots persistent/tests/test_persistence.py::CPersistentTests::test___setstate___derived_w_slots_in_base_but_not_derived persistent/tests/test_persistence.py::CPersistentTests::test___setstate___derived_w_slots_in_base_classes persistent/tests/test_persistence.py::CPersistentTests::test___setstate___doesnt_fail_on_non_dict persistent/tests/test_persistence.py::CPersistentTests::test___setstate___doesnt_fail_on_non_string_keys persistent/tests/test_persistence.py::CPersistentTests::test___setstate___empty persistent/tests/test_persistence.py::CPersistentTests::test___setstate___interns_dict_keys persistent/tests/test_persistence.py::CPersistentTests::test___setstate___nonempty persistent/tests/test_persistence.py::CPersistentTests::test___setstate___nonempty_derived_w_dict persistent/tests/test_persistence.py::CPersistentTests::test___setstate___nonempty_derived_w_dict_w_two_keys persistent/tests/test_persistence.py::CPersistentTests::test__ancient_dict_layout_bug persistent/tests/test_persistence.py::CPersistentTests::test__p_activate_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test__p_activate_from_saved persistent/tests/test_persistence.py::CPersistentTests::test__p_activate_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test__p_activate_leaves_object_in_saved_even_if_object_mutated_self persistent/tests/test_persistence.py::CPersistentTests::test__p_activate_only_sets_state_once persistent/tests/test_persistence.py::CPersistentTests::test__p_activate_w_broken_jar persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_changed persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_changed_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_saved persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_saved_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_from_unsaved_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_deactivate_when_sticky persistent/tests/test_persistence.py::CPersistentTests::test__p_delattr_w__p__names persistent/tests/test_persistence.py::CPersistentTests::test__p_delattr_w_normal_name persistent/tests/test_persistence.py::CPersistentTests::test__p_getattr_w__p__names persistent/tests/test_persistence.py::CPersistentTests::test__p_getattr_w_normal_name persistent/tests/test_persistence.py::CPersistentTests::test__p_getattr_w_special_names persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_changed persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_changed_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_changed_w_slots persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_changed_w_slots_compat persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_saved persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_saved_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_sticky persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_sticky_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test__p_invalidate_from_unsaved_w_dict persistent/tests/test_persistence.py::CPersistentTests::test__p_mtime_activates_object persistent/tests/test_persistence.py::CPersistentTests::test__p_mtime_no_serial persistent/tests/test_persistence.py::CPersistentTests::test__p_mtime_w_serial persistent/tests/test_persistence.py::CPersistentTests::test__p_setattr_w__p__name persistent/tests/test_persistence.py::CPersistentTests::test__p_setattr_w_normal_name persistent/tests/test_persistence.py::CPersistentTests::test__p_state_changed persistent/tests/test_persistence.py::CPersistentTests::test__p_state_changed_sticky persistent/tests/test_persistence.py::CPersistentTests::test__p_state_ghost persistent/tests/test_persistence.py::CPersistentTests::test__p_state_saved persistent/tests/test_persistence.py::CPersistentTests::test__p_state_saved_sticky persistent/tests/test_persistence.py::CPersistentTests::test__p_state_unsaved persistent/tests/test_persistence.py::CPersistentTests::test__p_status_changed persistent/tests/test_persistence.py::CPersistentTests::test__p_status_changed_sticky persistent/tests/test_persistence.py::CPersistentTests::test__p_status_ghost persistent/tests/test_persistence.py::CPersistentTests::test__p_status_saved persistent/tests/test_persistence.py::CPersistentTests::test__p_status_saved_sticky persistent/tests/test_persistence.py::CPersistentTests::test__p_status_unsaved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_false_from_changed persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_false_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_false_from_saved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_false_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_none_from_changed persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_none_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_none_from_saved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_none_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_none_when_sticky persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_true_from_changed persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_true_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_true_from_saved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_changed_true_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_estimated_size_bigger persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_estimated_size_just_over_threshold persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_estimated_size_negative persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_estimated_size_small persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_estimated_size_wrong_type persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_jar_not_in_cache_allowed persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_jar_w_new_jar persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_jar_w_valid_jar persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_oid_not_in_cache_allowed persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_oid_w_None_wo_jar persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_oid_w_invalid_oid persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_oid_w_new_oid_w_jar persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_oid_w_new_oid_wo_jar persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_oid_w_valid_oid persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_serial_too_long persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_serial_too_short persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_serial_w_None persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_serial_w_invalid_type persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_serial_w_valid_serial persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_sticky_false_non_ghost persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_sticky_false_when_ghost persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_sticky_true_non_ghost persistent/tests/test_persistence.py::CPersistentTests::test_assign_p_sticky_true_when_ghost persistent/tests/test_persistence.py::CPersistentTests::test_can_set__p_attrs_if_subclass_denies_setattr persistent/tests/test_persistence.py::CPersistentTests::test_class_conforms_to_IPersistent persistent/tests/test_persistence.py::CPersistentTests::test_ctor persistent/tests/test_persistence.py::CPersistentTests::test_del_jar_like_ZODB_abort persistent/tests/test_persistence.py::CPersistentTests::test_del_jar_no_jar persistent/tests/test_persistence.py::CPersistentTests::test_del_jar_of_inactive_object_that_has_no_state persistent/tests/test_persistence.py::CPersistentTests::test_del_jar_while_in_cache persistent/tests/test_persistence.py::CPersistentTests::test_del_oid_like_ZODB_abort persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_changed_from_changed persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_changed_from_ghost persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_changed_from_saved persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_changed_from_unsaved persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_changed_from_unsaved_w_dict persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_changed_when_sticky persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_oid_of_subclass_calling_p_delattr persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_oid_w_jar persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_oid_wo_jar persistent/tests/test_persistence.py::CPersistentTests::test_delete_p_serial persistent/tests/test_persistence.py::CPersistentTests::test_instance_conforms_to_IPersistent persistent/tests/test_persistence.py::CPersistentTests::test_new_ghost_success_not_already_ghost_dict persistent/tests/test_persistence.py::CPersistentTests::test_new_ghost_success_not_already_ghost_slot persistent/tests/test_persistence.py::CPersistentTests::test_p_invalidate_calls_p_deactivate persistent/tests/test_persistence.py::CPersistentTests::test_p_invalidate_with_slots_broken_jar persistent/tests/test_persistence.py::CPersistentTests::test_pickle_roundtrip_simple persistent/tests/test_persistence.py::CPersistentTests::test_pickle_roundtrip_w_getnewargs_and_getstate persistent/tests/test_persistence.py::CPersistentTests::test_pickle_roundtrip_w_slots_and_empty_dict persistent/tests/test_persistence.py::CPersistentTests::test_pickle_roundtrip_w_slots_and_filled_dict persistent/tests/test_persistence.py::CPersistentTests::test_pickle_roundtrip_w_slots_filled_slot persistent/tests/test_persistence.py::CPersistentTests::test_pickle_roundtrip_w_slots_missing_slot persistent/tests/test_persistence.py::CPersistentTests::test_query_p_changed_changed persistent/tests/test_persistence.py::CPersistentTests::test_query_p_changed_ghost persistent/tests/test_persistence.py::CPersistentTests::test_query_p_changed_saved persistent/tests/test_persistence.py::CPersistentTests::test_query_p_changed_unsaved persistent/tests/test_persistence.py::CPersistentTests::test_query_p_estimated_size_del persistent/tests/test_persistence.py::CPersistentTests::test_query_p_estimated_size_new persistent/tests/test_persistence.py::CPersistentTests::test_set__p_changed_w_broken_jar persistent/tests/test_persistence.py::CPersistentTests::test_setattr_in_subclass_is_not_called_creating_an_instance persistent/tests/test_persistence.py::CPersistentTests::test_w_alternate_metaclass persistent/tests/test_persistence.py::CPersistentTests::test_w_diamond_inheritance persistent/tests/test_persistence.py::Test_simple_new::test_w_non_type persistent/tests/test_persistence.py::Test_simple_new::test_w_type persistent/tests/test_persistence.py::test_suite persistent/tests/test_timestamp.py::Test__UTC::test_dst persistent/tests/test_timestamp.py::Test__UTC::test_fromutc persistent/tests/test_timestamp.py::Test__UTC::test_tzname persistent/tests/test_timestamp.py::Test__UTC::test_utcoffset persistent/tests/test_timestamp.py::pyTimeStampTests::test_comparisons_to_non_timestamps persistent/tests/test_timestamp.py::pyTimeStampTests::test_ctor_from_elements persistent/tests/test_timestamp.py::pyTimeStampTests::test_ctor_from_invalid_strings persistent/tests/test_timestamp.py::pyTimeStampTests::test_ctor_from_string persistent/tests/test_timestamp.py::pyTimeStampTests::test_ctor_from_string_non_zero persistent/tests/test_timestamp.py::pyTimeStampTests::test_ctor_invalid_arglist persistent/tests/test_timestamp.py::pyTimeStampTests::test_laterThan_invalid persistent/tests/test_timestamp.py::pyTimeStampTests::test_laterThan_self_is_earlier persistent/tests/test_timestamp.py::pyTimeStampTests::test_laterThan_self_is_later persistent/tests/test_timestamp.py::pyTimeStampTests::test_repr persistent/tests/test_timestamp.py::TimeStampTests::test_comparisons_to_non_timestamps persistent/tests/test_timestamp.py::TimeStampTests::test_ctor_from_elements persistent/tests/test_timestamp.py::TimeStampTests::test_ctor_from_invalid_strings persistent/tests/test_timestamp.py::TimeStampTests::test_ctor_from_string persistent/tests/test_timestamp.py::TimeStampTests::test_ctor_from_string_non_zero persistent/tests/test_timestamp.py::TimeStampTests::test_ctor_invalid_arglist persistent/tests/test_timestamp.py::TimeStampTests::test_laterThan_invalid persistent/tests/test_timestamp.py::TimeStampTests::test_laterThan_self_is_earlier persistent/tests/test_timestamp.py::TimeStampTests::test_laterThan_self_is_later persistent/tests/test_timestamp.py::TimeStampTests::test_repr persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_equal persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_hash_equal persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_hash_equal_constants persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_ordering persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_py_hash_32_64_bit persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_raw_equal persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_reprs_equal persistent/tests/test_timestamp.py::PyAndCComparisonTests::test_strs_equal persistent/tests/test_timestamp.py::test_suite
persistent/timestamp.py persistent/interfaces.py docs/using.rst CHANGES.rst persistent/cPersistence.c persistent/persistence.py
persistent/timestamp.py persistent/interfaces.py docs/using.rst CHANGES.rst persistent/cPersistence.c persistent/persistence.py