diff options
| author | Julian Andres Klode <jak@debian.org> | 2009-04-20 19:26:05 +0200 |
|---|---|---|
| committer | Julian Andres Klode <jak@debian.org> | 2009-04-20 19:26:05 +0200 |
| commit | bd47802c98f30f67b323b0796ff5d79a5e308c08 (patch) | |
| tree | abdd00ae5efdbacc6e150012a9bd489c445d0a4e | |
| parent | 071b059f8ccb35eaeb6c9457244f783ad69ba957 (diff) | |
| download | python-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/changelog | 3 | ||||
| -rwxr-xr-x | utils/migrate-0.8.py | 194 |
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)) |
