Mercurial > hg
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) |