[PATCH 8 of 8 RFC] vfs: wrap platform depend file APIs to detect direct invocation of them

FUJIWARA Katsunori foozy at lares.dti.ne.jp
Fri Jun 15 09:45:19 CDT 2012


# HG changeset patch
# User FUJIWARA Katsunori <foozy at lares.dti.ne.jp>
# Date 1339768794 -32400
# Node ID fa2b9241ef4a5c6ac35d8f470b1e724f937af422
# Parent  92f563247964eb16671f9868a3839d9eaad598a1
vfs: wrap platform depend file APIs to detect direct invocation of them

this patch shows the warning message to promote migration to using
them via vfs at exit(), if platform depend file APIs provided via
util.py are used,

[RFC points]

- where should we show the warning message ?

    this patch shows warning message every platforms, but should we
    show it only on Windows environment ?

- what about "ui" using in util.py in such case ?

    even though according checking code in tests, "ui" must not use in
    util.py, this patch uses "ui" object to show the warning message
    only if not "quiet".

    must not we use "ui" in such case ? if so, what should we do to
    show warning message ? just "print", or "stderr.write()" ?

diff -r 92f563247964 -r fa2b9241ef4a mercurial/dispatch.py
--- a/mercurial/dispatch.py	Fri Jun 15 22:59:54 2012 +0900
+++ b/mercurial/dispatch.py	Fri Jun 15 22:59:54 2012 +0900
@@ -583,6 +583,7 @@
     args = req.args
     ui = req.ui
     vfs = util.vfs()
+    atexit.register(util.atexit, ui)
 
     # read --config before doing anything else
     # (e.g. to change trust settings for reading .hg/hgrc)
diff -r 92f563247964 -r fa2b9241ef4a mercurial/util.py
--- a/mercurial/util.py	Fri Jun 15 22:59:54 2012 +0900
+++ b/mercurial/util.py	Fri Jun 15 22:59:54 2012 +0900
@@ -27,10 +27,36 @@
 platform.encodinglower = encoding.lower
 platform.encodingupper = encoding.upper
 
+_deprecated = 0
+
+def deprecatefunc(origfunc):
+    def wrap(*args, **kwargs):
+        # any extension uses deprecated function
+        global _deprecated
+        _deprecated += 1
+        return origfunc(*args, **kwargs)
+    wrap.origfunc = origfunc
+    return wrap
+
+def getdeprecatedfunc(deprecated):
+    origfunc = getattr(deprecated, 'origfunc', None)
+    if origfunc:
+        # invocation via vfs object, so skip increasing '_deprecated'
+        return origfunc
+    # any extension replaces deprecated function
+    global _deprecated
+    _deprecated += 1
+    return deprecated
+
+def atexit(uiobj):
+    if _deprecated and not uiobj.quiet:
+        uiobj.warn(_("warning: you may use some extension using"
+                  " deprecated file API of util module"))
+
 cachestat = platform.cachestat
-checkexec = platform.checkexec
-checklink = platform.checklink
-copymode = platform.copymode
+checkexec = deprecatefunc(platform.checkexec)
+checklink = deprecatefunc(platform.checklink)
+copymode = deprecatefunc(platform.copymode)
 executablepath = platform.executablepath
 expandglobs = platform.expandglobs
 explainexit = platform.explainexit
@@ -40,39 +66,39 @@
 groupmembers = platform.groupmembers
 groupname = platform.groupname
 hidewindow = platform.hidewindow
-isexec = platform.isexec
+isexec = deprecatefunc(platform.isexec)
 isowner = platform.isowner
 localpath = platform.localpath
 lookupreg = platform.lookupreg
-makedir = platform.makedir
-nlinks = platform.nlinks
+makedir = deprecatefunc(platform.makedir)
+nlinks = deprecatefunc(platform.nlinks)
 normpath = platform.normpath
 normcase = platform.normcase
 nulldev = platform.nulldev
 openhardlinks = platform.openhardlinks
-oslink = platform.oslink
+oslink = deprecatefunc(platform.oslink)
 parsepatchoutput = platform.parsepatchoutput
 pconvert = platform.pconvert
 popen = platform.popen
-posixfile = platform.posixfile
+posixfile = deprecatefunc(platform.posixfile)
 quotecommand = platform.quotecommand
-realpath = platform.realpath
-rename = platform.rename
-samedevice = platform.samedevice
-samefile = platform.samefile
+realpath = deprecatefunc(platform.realpath)
+rename = deprecatefunc(platform.rename)
+samedevice = deprecatefunc(platform.samedevice)
+samefile = deprecatefunc(platform.samefile)
 samestat = platform.samestat
 setbinary = platform.setbinary
-setflags = platform.setflags
+setflags = deprecatefunc(platform.setflags)
 setsignalhandler = platform.setsignalhandler
 shellquote = platform.shellquote
 spawndetached = platform.spawndetached
 sshargs = platform.sshargs
-statfiles = platform.statfiles
+statfiles = deprecatefunc(platform.statfiles)
 termwidth = platform.termwidth
 testpid = platform.testpid
 umask = platform.umask
-unlink = platform.unlink
-unlinkpath = platform.unlinkpath
+unlink = deprecatefunc(platform.unlink)
+unlinkpath = deprecatefunc(platform.unlinkpath)
 username = platform.username
 
 # Python compatibility
@@ -1878,37 +1904,37 @@
     def cachestat(self, *args, **kwargs):
         return cachestat(*args, **kwargs)
     def checkexec(self, *args, **kwargs):
-        return checkexec(*args, **kwargs)
+        return getdeprecatedfunc(checkexec)(*args, **kwargs)
     def checklink(self, *args, **kwargs):
-        return checklink(*args, **kwargs)
+        return getdeprecatedfunc(checklink)(*args, **kwargs)
     def copymode(self, *args, **kwargs):
-        return copymode(*args, **kwargs)
+        return getdeprecatedfunc(copymode)(*args, **kwargs)
     def isexec(self, *args, **kwargs):
-        return isexec(*args, **kwargs)
+        return getdeprecatedfunc(isexec)(*args, **kwargs)
     def makedir(self, *args, **kwargs):
-        return makedir(*args, **kwargs)
+        return getdeprecatedfunc(makedir)(*args, **kwargs)
     def nlinks(self, *args, **kwargs):
-        return nlinks(*args, **kwargs)
+        return getdeprecatedfunc(nlinks)(*args, **kwargs)
     def oslink(self, *args, **kwargs):
-        return oslink(*args, **kwargs)
+        return getdeprecatedfunc(oslink)(*args, **kwargs)
     def posixfile(self, *args, **kwargs):
-        return posixfile(*args, **kwargs)
+        return getdeprecatedfunc(posixfile)(*args, **kwargs)
     def realpath2(self, *args, **kwargs):
-        return realpath(*args, **kwargs)
+        return getdeprecatedfunc(realpath)(*args, **kwargs)
     def rename2(self, *args, **kwargs):
-        return rename(*args, **kwargs)
+        return getdeprecatedfunc(rename)(*args, **kwargs)
     def samedevice(self, *args, **kwargs):
-        return samedevice(*args, **kwargs)
+        return getdeprecatedfunc(samedevice)(*args, **kwargs)
     def samefile(self, *args, **kwargs):
-        return samefile(*args, **kwargs)
+        return getdeprecatedfunc(samefile)(*args, **kwargs)
     def setflags(self, *args, **kwargs):
-        return setflags(*args, **kwargs)
+        return getdeprecatedfunc(setflags)(*args, **kwargs)
     def statfiles(self, *args, **kwargs):
-        return statfiles(*args, **kwargs)
+        return getdeprecatedfunc(statfiles)(*args, **kwargs)
     def unlink2(self, *args, **kwargs):
-        return unlink(*args, **kwargs)
+        return getdeprecatedfunc(unlink)(*args, **kwargs)
     def unlinkpath(self, *args, **kwargs):
-        return unlinkpath(*args, **kwargs)
+        return getdeprecatedfunc(unlinkpath)(*args, **kwargs)
 
 _bvfs = _vfs()
 
diff -r 92f563247964 -r fa2b9241ef4a tests/test-issue1802.t
--- a/tests/test-issue1802.t	Fri Jun 15 22:59:54 2012 +0900
+++ b/tests/test-issue1802.t	Fri Jun 15 22:59:54 2012 +0900
@@ -9,8 +9,8 @@
   > def checkexec(orig, path):
   >     return False
   > def extsetup(ui):
-  >     extensions.wrapfunction(util, 'setflags', setflags)
-  >     extensions.wrapfunction(util, 'checkexec', checkexec)
+  >     extensions.wrapfunction(util._bvfs, 'setflags', setflags)
+  >     extensions.wrapfunction(util._bvfs, 'checkexec', checkexec)
   > EOF
 
   $ hg init unix-repo
diff -r 92f563247964 -r fa2b9241ef4a tests/test-largefiles-small-disk.t
--- a/tests/test-largefiles-small-disk.t	Fri Jun 15 22:59:54 2012 +0900
+++ b/tests/test-largefiles-small-disk.t	Fri Jun 15 22:59:54 2012 +0900
@@ -2,23 +2,25 @@
 
   $ cat > criple.py <<EOF
   > import os, errno, shutil
-  > from mercurial import util
+  > from mercurial import extensions, util
   > #
   > # this makes the original largefiles code abort:
-  > def copyfileobj(fsrc, fdst, length=16*1024):
+  > def copyfileobj(orig, fsrc, fdst, length=16*1024):
   >     fdst.write(fsrc.read(4))
   >     raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
-  > shutil.copyfileobj = copyfileobj
   > #
   > # this makes the rewritten code abort:
-  > def filechunkiter(f, size=65536, limit=None):
+  > def filechunkiter(orig, f, size=65536, limit=None):
   >     yield f.read(4)
   >     raise IOError(errno.ENOSPC, os.strerror(errno.ENOSPC))
-  > util.filechunkiter = filechunkiter
   > #
-  > def oslink(src, dest):
+  > def oslink(orig, src, dest):
   >     raise OSError("no hardlinks, try copying instead")
-  > util.oslink = oslink
+  > 
+  > def extsetup(ui):
+  >     extensions.wrapfunction(shutil, 'copyfileobj', copyfileobj)
+  >     extensions.wrapfunction(util, 'filechunkiter', filechunkiter)
+  >     extensions.wrapfunction(util._bvfs, 'oslink', oslink)
   > EOF
 
   $ echo "[extensions]" >> $HGRCPATH
diff -r 92f563247964 -r fa2b9241ef4a tests/test-symlink-placeholder.t
--- a/tests/test-symlink-placeholder.t	Fri Jun 15 22:59:54 2012 +0900
+++ b/tests/test-symlink-placeholder.t	Fri Jun 15 22:59:54 2012 +0900
@@ -9,8 +9,8 @@
   > def checklink(orig, path):
   >     return False
   > def extsetup(ui):
-  >     extensions.wrapfunction(util, 'setflags', setflags)
-  >     extensions.wrapfunction(util, 'checklink', checklink)
+  >     extensions.wrapfunction(util._bvfs, 'setflags', setflags)
+  >     extensions.wrapfunction(util._bvfs, 'checklink', checklink)
   > EOF
 
   $ hg init unix-repo


More information about the Mercurial-devel mailing list