changeset 43589:7f4d58c21aec

largefiles: avoid dynamically subclassing context instances E.g. copies.pathcopies() compares context objects for equality and basectx.__eq__ compares the type. But since largefiles was dynamically creating classes, they would all be unequal. That led pathcopies(), after some changes I made, to not short-circuit to get copy info only from the dirstate. This patch fixes that short-circuiting (and other places where context are being compared for equality). Differential Revision: https://phab.mercurial-scm.org/D7143
author Martin von Zweigbergk <martinvonz@google.com>
date Sat, 19 Oct 2019 00:15:41 -0700
parents d77e8800790b
children 95d0532ad171
files hgext/largefiles/reposetup.py
diffstat 1 files changed, 36 insertions(+), 34 deletions(-) [+]
line wrap: on
line diff
--- a/hgext/largefiles/reposetup.py	Fri Oct 18 22:08:20 2019 -0700
+++ b/hgext/largefiles/reposetup.py	Sat Oct 19 00:15:41 2019 -0700
@@ -15,6 +15,7 @@
 
 from mercurial import (
     error,
+    extensions,
     localrepo,
     match as matchmod,
     scmutil,
@@ -47,45 +48,46 @@
             ctx = super(lfilesrepo, self).__getitem__(changeid)
             if self.lfstatus:
 
-                class lfilesctx(ctx.__class__):
-                    def files(self):
-                        filenames = super(lfilesctx, self).files()
-                        return [lfutil.splitstandin(f) or f for f in filenames]
+                def files(orig):
+                    filenames = orig()
+                    return [lfutil.splitstandin(f) or f for f in filenames]
 
-                    def manifest(self):
-                        man1 = super(lfilesctx, self).manifest()
+                extensions.wrapfunction(ctx, 'files', files)
+
+                def manifest(orig):
+                    man1 = orig()
 
-                        class lfilesmanifest(man1.__class__):
-                            def __contains__(self, filename):
-                                orig = super(lfilesmanifest, self).__contains__
-                                return orig(filename) or orig(
-                                    lfutil.standin(filename)
-                                )
+                    class lfilesmanifest(man1.__class__):
+                        def __contains__(self, filename):
+                            orig = super(lfilesmanifest, self).__contains__
+                            return orig(filename) or orig(
+                                lfutil.standin(filename)
+                            )
 
-                        man1.__class__ = lfilesmanifest
-                        return man1
+                    man1.__class__ = lfilesmanifest
+                    return man1
 
-                    def filectx(self, path, fileid=None, filelog=None):
-                        orig = super(lfilesctx, self).filectx
-                        try:
-                            if filelog is not None:
-                                result = orig(path, fileid, filelog)
-                            else:
-                                result = orig(path, fileid)
-                        except error.LookupError:
-                            # Adding a null character will cause Mercurial to
-                            # identify this as a binary file.
-                            if filelog is not None:
-                                result = orig(
-                                    lfutil.standin(path), fileid, filelog
-                                )
-                            else:
-                                result = orig(lfutil.standin(path), fileid)
-                            olddata = result.data
-                            result.data = lambda: olddata() + b'\0'
-                        return result
+                extensions.wrapfunction(ctx, 'manifest', manifest)
 
-                ctx.__class__ = lfilesctx
+                def filectx(orig, path, fileid=None, filelog=None):
+                    try:
+                        if filelog is not None:
+                            result = orig(path, fileid, filelog)
+                        else:
+                            result = orig(path, fileid)
+                    except error.LookupError:
+                        # Adding a null character will cause Mercurial to
+                        # identify this as a binary file.
+                        if filelog is not None:
+                            result = orig(lfutil.standin(path), fileid, filelog)
+                        else:
+                            result = orig(lfutil.standin(path), fileid)
+                        olddata = result.data
+                        result.data = lambda: olddata() + b'\0'
+                    return result
+
+                extensions.wrapfunction(ctx, 'filectx', filectx)
+
             return ctx
 
         # Figure out the status of big files and insert them into the