Ticket #993 (closed defect: fixed)

Opened 2 years ago

Last modified 10 months ago

Partially initialized Items cannot be repr()'d

Reported by: exarkun Assigned to: exarkun
Priority: highest Milestone:
Component: Axiom Severity: normal
Keywords: Cc:
Author: Branch:

Description

Minimal reproduction:

>>> from axiom import item, attributes
>>> class Y(item.Item):
...     y = attributes.text()
...
>>> from epsilon import spewer
>>> s = spewer.Spewer()
>>> s.toggle(); X(); s.toggle()
Traceback (most recent call last):
  File "/home/exarkun/Projects/Divmod/trunk/Axiom/axiom/item.py", line 331, in __repr__
    V = atr.reprFor(self)
  File "/home/exarkun/Projects/Divmod/trunk/Axiom/axiom/attributes.py", line 287, in reprFor
    return repr(self.__get__(oself))
  File "/home/exarkun/Projects/Divmod/trunk/Axiom/axiom/attributes.py", line 365, in __get__
    st = getattr(oself, 'store')  File "/home/exarkun/Projects/Divmod/trunk/Axiom/axiom/item.py", line 292, in get
    return self.__store
  File "/home/exarkun/Projects/Divmod/trunk/Axiom/axiom/slotmachine.py", line 22, in __get__
    raise AttributeError("%r object did not have attribute %r" %(oself.__class__.__name__, self.name))
AttributeError: 'X' object did not have attribute '_Item__store'

Spewer is crazy, so I wouldn't say this is a bug in Item. However, it would be nice if __repr__ worked in all states, so that we could use the Spewer more effectively.

Attachments

patch-993.diff (1.2 kB) - added by konrads on 05/13/07 14:10:38.

Change History

06/01/06 04:15:46 changed by glyph

  • priority changed from normal to low.

Not ship critical.

04/10/07 08:15:51 changed by konrads

Here's the simple patch.

--- attributes.py       (revision 12038)
+++ attributes.py       (working copy)
@@ -420,7 +420,8 @@
             return self

         pyval = getattr(oself, self.underlying, _NEEDS_FETCH)
-        st = getattr(oself, 'store')
+                               #  st was not used anywhere anyway
+                               #  st = getattr(oself, 'store')
         if pyval is _NEEDS_FETCH:
             dbval = getattr(oself, self.dbunderlying, _NEEDS_FETCH)
             if dbval is _NEEDS_FETCH:

04/10/07 08:32:18 changed by konrads

UnitTest :

Index: test_item.py
===================================================================
--- test_item.py        (revision 12038)
+++ test_item.py        (working copy)
@@ -302,6 +302,17 @@
                           1234)
         self.assertEquals(st.getItemByID(oldStoreID, default=1234),
                           1234)
+    def testItemWithNoStoreReps(self):
+       """
+          Bug #993, Item with no store defined would break on repr
+       """
+       class Y(item.Item):
+         y = text()
+       from epsilon import spewer
+       s = spewer.Spewer()
+       s.toggle()
+       Y()
+       s.toggle()

04/13/07 10:30:41 changed by mithrandi

  • keywords set to review.
  • priority changed from low to highest.

04/15/07 05:10:18 changed by glyph

  • keywords deleted.
  • owner changed from glyph to konrads.

Thanks for the patch!

Review comments:

  • I think the test belongs in test_reprs.
  • new tests are named as test_xxxYyy, not testXxxYyy.
  • invoking the spewer here seems like overkill. Isn't there a simpler way to invoke the repr at the appropriate time?
  • The test should be asserting something, not simply running some code and hoping that no exception is raised.
  • The indentation on the test docstring is off. The docstring should be indented to the same place that the quotes on the line above are.
  • the deleted line should just be deleted, not commented out. It doesn't help anyone reading the code later.
  • The test docstring should explain what it's verifying, not describing the bug that existed before the test was written. We don't generally link to the bug number, although perhaps that is useful information.

04/18/07 09:43:41 changed by konrads

I think I addressed all comments. I didn't know what to test for so, I tested that repr returns a string.

Index: test/test_reprs.py
===================================================================
--- test/test_reprs.py  (revision 12038)
+++ test/test_reprs.py  (working copy)
@@ -61,3 +61,12 @@
                             ReprTesterItemClass.txtattr.descending)))
         self.assertIn(repr(ReprTesterItemClass.intattr.ascending), R)
         self.assertIn(repr(ReprTesterItemClass.txtattr.descending), R)
+
+    def test_itemWithNoStoreReps(self):
+       """
+       Verify, that items that are instantiated without a C{axiom.store.Store) 
+       __repr__ correctly
+       """
+       class Y(Item):
+         y = text()
+       self.assertEquals(type(Y().__repr__()),str)
Index: attributes.py
===================================================================
--- attributes.py       (revision 12038)
+++ attributes.py       (working copy)
@@ -420,7 +420,6 @@
             return self

         pyval = getattr(oself, self.underlying, _NEEDS_FETCH)
-        st = getattr(oself, 'store')
         if pyval is _NEEDS_FETCH:
             dbval = getattr(oself, self.dbunderlying, _NEEDS_FETCH)
             if dbval is _NEEDS_FETCH:

05/13/07 14:10:38 changed by konrads

  • attachment patch-993.diff added.

05/13/07 14:11:27 changed by konrads

I attached a better test case and petition for closure of this ticket

05/13/07 15:01:53 changed by mithrandi

  • keywords set to review.
  • owner changed from konrads to glyph.

05/14/07 14:39:55 changed by glyph

  • keywords deleted.

Still some problems. The biggest one is:

  • The test passes in trunk without the non-test part of the patch applied, so it doesn't test anything useful.

Smaller issues while you are fixing that though:

  • The use of regular expressions is superfluous and misleading. startswith would work better.
  • "reps" is slang for repetitions in exercise. Perhaps you meant to end the test's name with "reprs".
  • There's trailing whitespace in the new test. If you use emacs, check out the "show-trailing-whitespace" option and the "trailing-whitespace" face. If you use vim, have a look at the "listchars" option.

My emacs config:

(custom-set-variables ... '(show-trailing-whitespace t) ... )

My vim config:

set list
set listchars=tab:>-,trail:ยท

05/14/07 14:54:58 changed by glyph

  • owner changed from glyph to konrads.

05/27/07 05:32:53 changed by konrads

I can't repeat the error without epsilon.spewer active. So, I am inclined to put the spewer back in the tests.

10/01/07 16:10:00 changed by exarkun

  • owner changed from konrads to exarkun.
  • status changed from new to assigned.

Wow. Item.__repr__ is an abomination. Now that I see the full scope of this, I can't help but try to fix it.

10/01/07 16:33:20 changed by exarkun

  • keywords set to review.
  • owner changed from exarkun to moe.
  • status changed from assigned to new.

Tested and fixed in item-repr-993

10/03/07 11:44:30 changed by moe

  • keywords deleted.
  • owner changed from moe to exarkun.

Haha. Looks good, though a docstring for test_item.ItemTestCase would be nice.

10/09/07 10:07:47 changed by exarkun

  • status changed from new to closed.
  • resolution set to fixed.

(In [13809]) Merge item-repr-993

Author: exarkun Reviewer: moea Fixes #993

Add tests for several cases of Item.repr, remove the special handling of exceptions raised by attribute.reprFor, and remove the unused item.store lookup in SQLAttribute.get.

jethro@divmod.org