[PATCH 2 of 8] py3: proxy posixfile objects to re-add a useful 'name' attribute on Windows
Matt Harbison
mharbison72 at gmail.com
Sat Sep 22 15:28:38 UTC 2018
# HG changeset patch
# User Matt Harbison <matt_harbison at yahoo.com>
# Date 1537574587 14400
# Fri Sep 21 20:03:07 2018 -0400
# Node ID 0d1b3d5a92e159506c823be481cf9f57e45ec03d
# Parent 758cf8cdf994942174238c28c8f06ece63dae2b5
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. I don't know nearly enough python to know
if this handles all of the cases that it needs to, or if this is even sane. The
context manager functions and __iter__() were things that crashed when missing,
for instance. But it works well enough to fix a whole bunch of stacktraces.
[1] https://docs.python.org/3.6/c-api/file.html
diff --git a/mercurial/windows.py b/mercurial/windows.py
--- a/mercurial/windows.py
+++ b/mercurial/windows.py
@@ -128,6 +128,28 @@ def posixfile(name, mode='r', buffering=
try:
fp = osutil.posixfile(name, mode, buffering) # may raise WindowsError
+ # PyFile_FromFd() ignores the name, and seems to report fp.name as the
+ # underlying file descriptor.
+ if pycompat.ispy3:
+ class fdproxy(object):
+ def __init__(self, name, fp):
+ self.name = name
+ self._fp = fp
+
+ def __enter__(self):
+ return self._fp.__enter__()
+
+ def __exit__(self, exc_type, exc_value, traceback):
+ self._fp.__exit__(exc_type, exc_value, traceback)
+
+ def __iter__(self):
+ return iter(self._fp)
+
+ def __getattr__(self, name):
+ return getattr(self._fp, name)
+
+ fp = fdproxy(name, fp)
+
# The position when opening in append mode is implementation defined, so
# make it consistent with other platforms, which position at EOF.
if 'a' in mode:
More information about the Mercurial-devel
mailing list