140140 '|'
141141 '(libc(_\w+)?\.so(?:\.(\d[0-9.]*))?)' )
142142
143- def libc_ver (executable = sys .executable ,lib = '' ,version = '' ,
144-
145- chunksize = 2048 ):
143+ def libc_ver (executable = sys .executable ,lib = '' ,version = '' , chunksize = 2048 ):
146144
147145 """ Tries to determine the libc version that the file executable
148146 (which defaults to the Python interpreter) is linked against.
@@ -157,40 +155,42 @@ def libc_ver(executable=sys.executable,lib='',version='',
157155 The file is read and scanned in chunks of chunksize bytes.
158156
159157 """
158+ from distutils .version import LooseVersion as V
160159 if hasattr (os .path , 'realpath' ):
161160 # Python 2.2 introduced os.path.realpath(); it is used
162161 # here to work around problems with Cygwin not being
163162 # able to open symlinks for reading
164163 executable = os .path .realpath (executable )
165- f = open (executable ,'rb' )
166- binary = f .read (chunksize )
167- pos = 0
168- while 1 :
169- m = _libc_search .search (binary ,pos )
170- if not m :
171- binary = f .read (chunksize )
172- if not binary :
173- break
174- pos = 0
175- continue
176- libcinit ,glibc ,glibcversion ,so ,threads ,soversion = m .groups ()
177- if libcinit and not lib :
178- lib = 'libc'
179- elif glibc :
180- if lib != 'glibc' :
181- lib = 'glibc'
182- version = glibcversion
183- elif glibcversion > version :
184- version = glibcversion
185- elif so :
186- if lib != 'glibc' :
164+ with open (executable , 'rb' ) as f :
165+ binary = f .read (chunksize )
166+ pos = 0
167+ while pos < len (binary ):
168+ m = _libc_search .search (binary ,pos )
169+ if not m or m .end () == len (binary ):
170+ chunk = f .read (chunksize )
171+ if chunk :
172+ binary = binary [max (pos , len (binary ) - 1000 ):] + chunk
173+ pos = 0
174+ continue
175+ if not m :
176+ break
177+ libcinit ,glibc ,glibcversion ,so ,threads ,soversion = m .groups ()
178+ if libcinit and not lib :
187179 lib = 'libc'
188- if soversion and soversion > version :
189- version = soversion
190- if threads and version [- len (threads ):] != threads :
191- version = version + threads
192- pos = m .end ()
193- f .close ()
180+ elif glibc :
181+ if lib != 'glibc' :
182+ lib = 'glibc'
183+ version = glibcversion
184+ elif V (glibcversion ) > V (version ):
185+ version = glibcversion
186+ elif so :
187+ if lib != 'glibc' :
188+ lib = 'libc'
189+ if soversion and (not version or V (soversion ) > V (version )):
190+ version = soversion
191+ if threads and version [- len (threads ):] != threads :
192+ version = version + threads
193+ pos = m .end ()
194194 return lib ,version
195195
196196def _dist_try_harder (distname ,version ,id ):
@@ -451,6 +451,7 @@ def popen(cmd, mode='r', bufsize=None):
451451 else :
452452 return popen (cmd ,mode ,bufsize )
453453
454+
454455def _norm_version (version , build = '' ):
455456
456457 """ Normalize the version and build strings and return a single
0 commit comments