[Zope-Coders] new getattr behaviour in Python 2.2b1 breaks traversal code

Steve Alexander steve@cat-box.net
Sun, 11 Nov 2001 15:41:41 +0000


This is a multi-part message in MIME format.
--------------090701080100040700090203
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Steve Alexander wrote:

> I've just been caught out by a change between Python 2.1 and Python 2.2b1.
> 
> This is a bad change which will mean changing various parts of Zope and 
> Zope products, if it remains in Python 2.2 final.


This isn't as bad as I'd thought. I just checked, and in the current 
Zope code it is only HTTPRequest that uses the __getattr__=__getitem__ 
idiom.

This is quite easy to fix in HTTPRequest.
See the attached patch.

Is the current Python 2.2 behaviour going to stay around for 2.2 final? 
In which case, I suggest applying this patch to the Zope core.

--
Steve Alexander
Software Engineer
Cat-Box limited

--------------090701080100040700090203
Content-Type: text/plain;
 name="diff.txt"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="diff.txt"

*** HTTPRequest.py.original
--- HTTPRequest.py
***************
*** 816,821 ****
--- 816,822 ----
  
      def __getitem__(self,key,
                      default=_marker, # Any special internal marker will do
+                     NotFoundError=KeyError,
                      URLmatch=re.compile('URL(PATH)?([0-9]+)$').match,
                      BASEmatch=re.compile('BASE(PATH)?([0-9]+)$').match,
                      ):
***************
*** 839,845 ****
                  path = self._script + self._steps
                  n = len(path) - int(n)
                  if n < 0:
!                     raise KeyError, key
                  if pathonly:
                      path = [''] + path[:n]
                  else:
--- 840,846 ----
                  path = self._script + self._steps
                  n = len(path) - int(n)
                  if n < 0:
!                     raise NotFoundError, key
                  if pathonly:
                      path = [''] + path[:n]
                  else:
***************
*** 865,871 ****
                  if n:
                      n = n - 1
                      if len(path) < n:
!                         raise KeyError, key
  
                      v = self._script + path[:n]
                  else:
--- 866,872 ----
                  if n:
                      n = n - 1
                      if len(path) < n:
!                         raise NotFoundError, key
  
                      v = self._script + path[:n]
                  else:
***************
*** 894,902 ****
          v=self.common.get(key, default)
          if v is not _marker: return v
  
!         raise KeyError, key
  
!     __getattr__=__getitem__
  
      def get(self, key, default=None):
          return self.__getitem__(key, default)
--- 895,904 ----
          v=self.common.get(key, default)
          if v is not _marker: return v
  
!         raise NotFoundError, key
  
!     def __getattr__(self, key):
!         return self.__getitem__(key, NotFoundError=AttributeError)
  
      def get(self, key, default=None):
          return self.__getitem__(key, default)

--------------090701080100040700090203--