[PATCH] largefiles: improve repo wrapping detection

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Tue Apr 9 12:36:27 CDT 2013


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1365528455 -32400
# Node ID 89f37fa1de2fe25f6359043e89adbffbd58274e4
# Parent  bd6aed2ad5eed666319bc3bdad1c1e37582cf4b1
largefiles: improve repo wrapping detection

Before this patch, repo wrapping detection in "reposetup()" of
largefiles can detect only limited repo wrapping: replacing target
functions by another one named as "wrap".

So, it can't detect repo wrapping even in recommended style: replacing
"__class__" of repo by derived class.

This patch can detect repo wrapping in both styles below:

  - replacing "__class__" of repo by derived class (recommended style):

        class derived(repo.__class__):
            def push(self, *args, **kwargs):
                return super(derived, self).push(*args, **kwargs)
        repo.__class__ = derived

  - replacing function of repo by another one (not recommended style):

        orgpush = repo.push
        def push(*args, **kwargs):
            return orgpush(*args, **kwargs)
        repo.push = push

diff --git a/hgext/largefiles/reposetup.py b/hgext/largefiles/reposetup.py
--- a/hgext/largefiles/reposetup.py
+++ b/hgext/largefiles/reposetup.py
@@ -27,10 +27,11 @@
     if not repo.local():
         return proto.wirereposetup(ui, repo)
 
+    origclass = localrepo.localrepository
+    repoclass = repo.__class__
     for name in ('status', 'commitctx', 'commit', 'push'):
-        method = getattr(repo, name)
-        if (isinstance(method, types.FunctionType) and
-            method.func_name == 'wrap'):
+        if (getattr(origclass, name) != getattr(repoclass, name) or
+            isinstance(getattr(repo, name), types.FunctionType)):
             ui.warn(_('largefiles: repo method %r appears to have already been'
                     ' wrapped by another extension: '
                     'largefiles may behave incorrectly\n')
diff --git a/tests/test-largefiles.t b/tests/test-largefiles.t
--- a/tests/test-largefiles.t
+++ b/tests/test-largefiles.t
@@ -180,6 +180,34 @@
   $ cat sub/large4
   large22
 
+Test repo method wrapping detection
+
+  $ cat > $TESTTMP/wrapping1.py <<EOF
+  > from hgext import largefiles
+  > def reposetup(ui, repo):
+  >     class derived(repo.__class__):
+  >         def push(self, *args, **kwargs):
+  >             return super(derived, self).push(*args, **kwargs)
+  >     repo.__class__ = derived
+  >     largefiles.reposetup(ui, repo)
+  > uisetup = largefiles.uisetup
+  > EOF
+  $ hg --config extensions.largefiles=$TESTTMP/wrapping1.py status
+  largefiles: repo method 'push' appears to have already been wrapped by another extension: largefiles may behave incorrectly
+
+  $ cat > $TESTTMP/wrapping2.py <<EOF
+  > from hgext import largefiles
+  > def reposetup(ui, repo):
+  >     orgpush = repo.push
+  >     def push(*args, **kwargs):
+  >         return orgpush(*args, **kwargs)
+  >     repo.push = push
+  >     largefiles.reposetup(ui, repo)
+  > uisetup = largefiles.uisetup
+  > EOF
+  $ hg --config extensions.largefiles=$TESTTMP/wrapping2.py status
+  largefiles: repo method 'push' appears to have already been wrapped by another extension: largefiles may behave incorrectly
+
 Test copies and moves from a directory other than root (issue3516)
 
   $ cd ..


More information about the Mercurial-devel mailing list