From aa8fa5485c9a1b52314dffb09d12833cff460111 Mon Sep 17 00:00:00 2001 From: Vincent Jacques Date: Fri, 29 Jun 2012 18:10:37 +0100 Subject: [PATCH] Refactor PaginatedLists (legacy and modern) to restore test coverage --- github/Legacy.py | 56 ++++++---------------------------- github/PaginatedList.py | 66 +++++++++++++++++++++++------------------ 2 files changed, 46 insertions(+), 76 deletions(-) diff --git a/github/Legacy.py b/github/Legacy.py index f9a915ff..4c175d50 100644 --- a/github/Legacy.py +++ b/github/Legacy.py @@ -11,8 +11,11 @@ # You should have received a copy of the GNU Lesser General Public License along with PyGithub. If not, see . -class PaginatedList: +from PaginatedList import PaginatedListBase + +class PaginatedList( PaginatedListBase ): def __init__( self, url, args, requester, key, convert, contentClass ): + PaginatedListBase.__init__( self, list() ) self.__url = url self.__args = args self.__requester = requester @@ -23,35 +26,10 @@ class PaginatedList: self.__continue = True self.__elements = list() - class __Slice: - def __init__( self, theList, theSlice ): - self.__list = theList - self.__start = theSlice.start or 0 - self.__stop = theSlice.stop - self.__step = theSlice.step or 1 + def _couldGrow( self ): + return self.__continue - def __iter__( self ): - index = self.__start - while not self.__finished( index ) : - if self.__list._isBiggerThan( index ): - yield self.__list[ index ] - index += self.__step - else: - return - - def __finished( self, index ): - return self.__stop is not None and index >= self.__stop - - def __iter__( self ): - for element in self.__elements: - yield element - while self.__continue: - newElements = self.__fetchNextPage() - self.__continue = len( newElements ) > 0 - for element in newElements: - yield element - - def __fetchNextPage( self ): + def _fetchNextPage( self ): if self.__nextPage != 1: self.__args[ "start_page" ] = self.__nextPage self.__nextPage += 1 @@ -61,27 +39,11 @@ class PaginatedList: self.__args, None ) - newElements = [ + self.__continue = len( data[ self.__key ] ) > 0 + return [ self.__contentClass( self.__requester, self.__convert( element ), completed = False ) for element in data[ self.__key ] ] - self.__elements += newElements - return newElements - - def __getitem__( self, index ): - assert isinstance( index, ( int, slice ) ) - if isinstance( index, int ): - self.__fetchToIndex( index ) - return self.__elements[ index ] - else: - return self.__Slice( self, index ) - - def _isBiggerThan( self, index ): - return len( self.__elements ) > index or self.__continue - - def __fetchToIndex( self, index ): - while len( self.__elements ) <= index and self.__continue: - self.__fetchNextPage() def convertUser( attributes ): login = attributes[ "login" ] diff --git a/github/PaginatedList.py b/github/PaginatedList.py index a43396aa..1dd46ba5 100644 --- a/github/PaginatedList.py +++ b/github/PaginatedList.py @@ -13,22 +13,39 @@ import GithubObject -class PaginatedList: - def __init__( self, contentClass, requester, headers, data ): - self.__requester = requester - self.__contentClass = contentClass - self.__elements = [] - self.__appendData( headers, data ) +class PaginatedListBase: + def __init__( self, firstElements ): + self.__elements = firstElements + + def __getitem__( self, index ): + assert isinstance( index, ( int, slice ) ) + if isinstance( index, int ): + self.__fetchToIndex( index ) + return self.__elements[ index ] + else: + return self._Slice( self, index ) def __iter__( self ): for element in self.__elements: yield element - while self.__nextUrl is not None: - newElements = self.__fetchNextPage() + while self._couldGrow(): + newElements = self.__grow() for element in newElements: yield element - class __Slice: + def _isBiggerThan( self, index ): + return len( self.__elements ) > index or self._couldGrow() + + def __fetchToIndex( self, index ): + while len( self.__elements ) <= index and self._couldGrow(): + self.__grow() + + def __grow( self ): + newElements = self._fetchNextPage() + self.__elements += newElements + return newElements + + class _Slice: def __init__( self, theList, theSlice ): self.__list = theList self.__start = theSlice.start or 0 @@ -47,39 +64,30 @@ class PaginatedList: def __finished( self, index ): return self.__stop is not None and index >= self.__stop - def __getitem__( self, index ): - assert isinstance( index, ( int, slice ) ) - if isinstance( index, int ): - self.__fetchToIndex( index ) - return self.__elements[ index ] - else: - return self.__Slice( self, index ) +class PaginatedList( PaginatedListBase ): + def __init__( self, contentClass, requester, headers, data ): + self.__requester = requester + self.__contentClass = contentClass + PaginatedListBase.__init__( self, self.__extractNewElements( headers, data ) ) - def _isBiggerThan( self, index ): - return len( self.__elements ) > index or self.__nextUrl is not None + def _couldGrow( self ): + return self.__nextUrl is not None - def __fetchToIndex( self, index ): - while len( self.__elements ) <= index and self.__nextUrl is not None: - self.__fetchNextPage() - - def __fetchNextPage( self ): + def _fetchNextPage( self ): headers, data = self.__requester.requestAndCheck( "GET", self.__nextUrl, None, None ) - return self.__appendData( headers, data ) + return self.__extractNewElements( headers, data ) - def __appendData( self, headers, data ): + def __extractNewElements( self, headers, data ): links = self.__parseLinkHeader( headers ) if len( data ) > 0 and "next" in links: self.__nextUrl = links[ "next" ] else: self.__nextUrl = None - newElements = [ + return [ self.__contentClass( self.__requester, element, completed = False ) for element in data ] - self.__elements += newElements - - return newElements def __parseLinkHeader( self, headers ): links = {}