summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJulian Andres Klode <jak@debian.org>2009-04-20 19:26:05 +0200
committerJulian Andres Klode <jak@debian.org>2009-04-20 19:26:05 +0200
commitbd47802c98f30f67b323b0796ff5d79a5e308c08 (patch)
treeabdd00ae5efdbacc6e150012a9bd489c445d0a4e
parent071b059f8ccb35eaeb6c9457244f783ad69ba957 (diff)
downloadpython-apt-bd47802c98f30f67b323b0796ff5d79a5e308c08.tar.gz
* utils/migrate-0.8.py: Helper to check Python code for deprecated functions, attributes, etc.
Has to be run from the python-apt source tree, but can be used for all Python code using python-apt. The output may not be completely correct, but false positives are better than not checking the code.
-rw-r--r--debian/changelog3
-rwxr-xr-xutils/migrate-0.8.py194
2 files changed, 197 insertions, 0 deletions
diff --git a/debian/changelog b/debian/changelog
index 30d54a29..f2d57afa 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -3,6 +3,9 @@ python-apt (0.7.91) UNRELEASED; urgency=low
* Rename all methods,functions,attributes to conform to PEP 8 (Closes: #481061)
* Where possible, derive apt.package.Record from collections.Mapping.
* ActionGroups can be used as a context manager for the 'with' statement.
+ * utils/migrate-0.8.py: Helper to check Python code for deprecated functions,
+ attributes,etc. Has to be run from the python-apt source tree, but can be
+ used for all Python code using python-apt.
-- Julian Andres Klode <jak@debian.org> Fri, 17 Apr 2009 17:48:27 +0200
diff --git a/utils/migrate-0.8.py b/utils/migrate-0.8.py
new file mode 100755
index 00000000..b3f143b0
--- /dev/null
+++ b/utils/migrate-0.8.py
@@ -0,0 +1,194 @@
+#!/usr/bin/python2.6
+#
+# migrate-0.8.py - Find use of deprecated methods/attributes in the code.
+#
+# Copyright (C) 2009 Julian Andres Klode <jak@debian.org>
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License as
+# published by the Free Software Foundation; either version 2 of the
+# License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
+# USA
+"""migrate-0.8.py - Find all occurences of funcs./attrs. deprecated in 0.8.
+
+Usage: python2.6 migrate-0.8.py [options] <file/directory>...
+
+This reads the list of all functions and attributes available only in
+COMPAT_0_7 builds and checks for occurences in the given Python modules. Has
+to be run from the python-apt source code directory.
+
+Requires python2.6 to be installed.
+
+Parameters:
+ -h Display this help
+ -c Colorize the matching parts in the output.
+"""
+import _ast
+import ast
+import glob
+import linecache
+import os
+import re
+import sys
+import types
+from collections import defaultdict
+from textwrap import fill
+
+color=False
+if sys.argv[1] in ('-c', '--color', '--colour'):
+ color=True
+ del sys.argv[1]
+
+if '-h' in sys.argv or '--help' in sys.argv or not sys.argv[1:]:
+ print __doc__.strip()
+ sys.exit(0)
+
+if os.path.dirname(__file__).endswith('utils'):
+ sys.path.insert(0, os.path.dirname(os.path.dirname(__file__)))
+
+
+def do_color(string, words):
+ """Colorize (red) the given words in the given string."""
+ if not color:
+ return string
+ for word in words:
+ string = re.sub('([^_]*)(%s)([^_]*)' % word, "\\1\033[31m\033[1m" +
+ r"\2" + "\033[0m\\3", string)
+ return string
+
+
+def find_deprecated_cpp():
+ """Find all the deprecated functions and attributes."""
+ is_open=False
+ all_old = set()
+ for fname in glob.glob('python/*.cc'):
+ lines = list(open(fname, 'r'))
+ while lines:
+ line = lines.pop(0)
+ while lines and not ('static PyMethodDef' in line or
+ 'static PyGetSetDef' in line):
+ line = lines.pop(0)
+ if not lines:
+ break
+
+ while lines and not ';' in line:
+ while lines and not 'COMPAT_0_7' in line:
+ line = lines.pop(0)
+ if lines:
+ line = lines.pop(0)
+ while lines and not '#endif' in line:
+ all_old.add(line.split(",")[0].strip().strip('{"'))
+ line = lines.pop(0)
+ return all_old
+
+
+def find_deprecated_py():
+ """Same as find_deprecated_cpp(), but for apt and aptsources.
+
+ We import apt_pkg, set _COMPAT_0_7 to 0, import apt and aptsources and
+ create a list of all attributes.
+
+ No we remove the imported modules, reimport them (with _COMPAT_0_7=1),
+ and see which functions have been removed.
+ """
+
+ modules = ('apt', 'apt.package', 'apt.cdrom', 'apt.cache', 'apt.debfile',
+ 'apt.progress', 'aptsources.distinfo', 'aptsources.distro',
+ 'aptsources.sourceslist')
+
+ import apt_pkg
+ apt_pkg._COMPAT_0_7 = 0
+
+ empty = set(sys.modules)
+ new, deprecated = set(), set()
+
+ for mname in sorted(modules):
+ module = __import__(mname)
+
+ for clsname in dir(module):
+ cls = getattr(module, clsname)
+ if not isinstance(cls, types.TypeType):
+ new.add(clsname)
+ continue
+ new.update(dir(cls))
+
+ for mname in sys.modules.keys():
+ if not mname in empty:
+ del sys.modules[mname]
+
+ apt_pkg._COMPAT_0_7 = 1
+
+ for mname in sorted(modules):
+ module = __import__(mname)
+ for clsname in dir(module):
+ cls = getattr(module, clsname)
+ if not isinstance(cls, types.TypeType):
+ deprecated.add(clsname)
+ continue
+ deprecated.update(dir(cls))
+
+
+ for mname in sys.modules.keys():
+ if not mname in empty:
+ del sys.modules[mname]
+
+ return deprecated.difference(new)
+
+
+def find_occurences(all_old, files):
+ """Find all ocurrences in the given Python files."""
+ for fname in files:
+ if fname.endswith('setup3.py') or not fname.endswith('.py'):
+ continue
+
+ words = defaultdict(lambda: set())
+ for i in ast.walk(ast.parse(open(fname).read())):
+
+ if isinstance(i, _ast.ImportFrom):
+ for alias in i.names:
+ if alias.name in all_old:
+ words[i.lineno].add(alias.name)
+ if isinstance(i, _ast.Name) and i.id in all_old:
+ words[i.lineno].add(i.id)
+
+ if isinstance(i, _ast.Attribute) and i.attr in all_old:
+ words[i.lineno].add(i.attr)
+
+ for lineno in sorted(words):
+ line = do_color(linecache.getline(fname, lineno).rstrip('\n'),
+ words[lineno])
+ print '%s:%s:%s' % (fname, lineno, line)
+
+# Now, let's find them in the code.
+
+print __doc__.split("\n")[0]
+print
+if color:
+ print fill('Information: The color is not always correct, because we '
+ 'simply highlight the matched words (like grep).', 79)
+ print
+
+all_old = find_deprecated_cpp() | find_deprecated_py()
+
+
+files = set()
+for path in sys.argv[1:]:
+ if not os.path.exists(path):
+ raise ValueError('Path does not exist: %s' % path)
+ if os.path.isfile(path):
+ files.add(path)
+ else:
+ for root, dirs, files_ in os.walk(path):
+ for fname in files_:
+ files.add(os.path.normpath(os.path.join(root, fname)))
+
+find_occurences(all_old, sorted(files))