comparison mercurial/windows.py @ 39820:68ea1f8dcb84

py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows This file object is used in the vfs layer, so there are many errors like this: ... File "mercurial\localrepo.py", line 2569, in savecommitmessage return self.pathto(fp.name[len(self.root) + 1:]) TypeError: 'int' object is not subscriptable It looks like the 'name' value is actually the fileno() value, and the documentation says the name parameter to PyFile_FromFd() is ignored. [1] I tried just assigning the attribute after osutil.posixfile() returns, but that crashes saying that it's read-only. [1] https://docs.python.org/3.6/c-api/file.html
author Matt Harbison <matt_harbison@yahoo.com>
date Fri, 21 Sep 2018 20:03:07 -0400
parents 255d1885c7f8
children 2209e72f9fcb
comparison
equal deleted inserted replaced
39819:fb628c048d64 39820:68ea1f8dcb84
121 self._noopseek() 121 self._noopseek()
122 122
123 object.__setattr__(self, r'_lastop', self.OPREAD) 123 object.__setattr__(self, r'_lastop', self.OPREAD)
124 return self._fp.readlines(*args, **kwargs) 124 return self._fp.readlines(*args, **kwargs)
125 125
126 class fdproxy(object):
127 """Wraps osutil.posixfile() to override the name attribute to reflect the
128 underlying file name.
129 """
130 def __init__(self, name, fp):
131 self.name = name
132 self._fp = fp
133
134 def __enter__(self):
135 return self._fp.__enter__()
136
137 def __exit__(self, exc_type, exc_value, traceback):
138 self._fp.__exit__(exc_type, exc_value, traceback)
139
140 def __iter__(self):
141 return iter(self._fp)
142
143 def __getattr__(self, name):
144 return getattr(self._fp, name)
145
126 def posixfile(name, mode='r', buffering=-1): 146 def posixfile(name, mode='r', buffering=-1):
127 '''Open a file with even more POSIX-like semantics''' 147 '''Open a file with even more POSIX-like semantics'''
128 try: 148 try:
129 fp = osutil.posixfile(name, mode, buffering) # may raise WindowsError 149 fp = osutil.posixfile(name, mode, buffering) # may raise WindowsError
150
151 # PyFile_FromFd() ignores the name, and seems to report fp.name as the
152 # underlying file descriptor.
153 if pycompat.ispy3:
154 fp = fdproxy(name, fp)
130 155
131 # The position when opening in append mode is implementation defined, so 156 # The position when opening in append mode is implementation defined, so
132 # make it consistent with other platforms, which position at EOF. 157 # make it consistent with other platforms, which position at EOF.
133 if 'a' in mode: 158 if 'a' in mode:
134 fp.seek(0, os.SEEK_END) 159 fp.seek(0, os.SEEK_END)