Port to python3, keep compatibility symlink for lsb_release.py
authorAlexandre Detiste <alexandre.detiste@gmail.com>
Thu, 28 May 2015 19:32:51 +0000 (21:32 +0200)
committerDidier Raboud <odyx@debian.org>
Tue, 14 Jul 2015 09:47:47 +0000 (11:47 +0200)
Closes: #719063
13 files changed:
debian/control
debian/lsb-release.links [new file with mode: 0644]
debian/rules
initdutils.py
install_initd
lsb_release
lsb_release.py
lsbinstall
remove_initd
test/apt-cache
test/dpkg-query
test/test_initdutils.py
test/test_lsb_release.py

index ba4c83a6ef49bc7740a6ecb99b2eaf698451cf77..95e76b89f31ba1066da6433027300bedb2ec27b2 100644 (file)
@@ -6,8 +6,9 @@ Uploaders: Didier Raboud <odyx@debian.org>, Jeff Licquia <licquia@debian.org>
 Build-Depends: debhelper (>> 9.0),
  po-debconf (>= 0.5.0),
  dpkg-dev (>= 1.10),
- python-all-dev (>= 2.6.6-6~),
-X-Python-Version: >= 2.6
+ python3-all-dev,
+ dh-python,
+X-Python3-Version: >= 3.4
 Standards-Version: 3.9.4
 Homepage: http://www.linuxfoundation.org/collaborate/workgroups/lsb
 Vcs-Git: git://anonscm.debian.org/collab-maint/lsb.git
@@ -47,7 +48,7 @@ Depends: lsb-release (>= ${source:Version}),
  psmisc,
  rsync,
  alien (>= 8.36),
- ${python:Depends},
+ ${python3:Depends},
  ${misc:Depends},
  ${depends},
  lsb-base (>= ${source:Version}),
@@ -317,7 +318,7 @@ Package: lsb-release
 Architecture: all
 Priority: optional
 Multi-Arch: foreign
-Depends: ${python:Depends},
+Depends: ${python3:Depends},
  ${misc:Depends}
 Recommends: apt
 Suggests: lsb
diff --git a/debian/lsb-release.links b/debian/lsb-release.links
new file mode 100644 (file)
index 0000000..a71099b
--- /dev/null
@@ -0,0 +1,2 @@
+usr/share/pyshared/lsb_release.py usr/lib/python2.7/dist-packages/lsb_release.py
+usr/share/pyshared/lsb_release.py usr/lib/python3/dist-packages/lsb_release.py
index 6bc0f05f60752814450ea90eaf7080f546489763..8f7d87db1178c4a54bda534e5f3179ce6c7baedd 100755 (executable)
@@ -2,11 +2,10 @@
 
 derives_from_ubuntu := $(shell (dpkg-vendor --derives-from Ubuntu && echo "yes") || echo "no")
 
-PY2VERSIONS=$(shell pyversions -vr)
 PY3VERSIONS=$(shell [ -x /usr/bin/py3versions ] && py3versions -vr)
 
 %:
-       dh $@ --with python2
+       dh $@ --with python3
 
 # These are used for cross-compiling and for saving the configure script
 # from having to guess our platform (since we know it already)
@@ -47,19 +46,21 @@ override_dh_clean:
        dh_clean
        rm -f *.py[co]
        rm -f debian/lsb-base.maintscript
+       rm -rf __pycache__
+       rm -rf test/__pycache__
 
-override_dh_auto_test: $(PY2VERSIONS:%=test-python%) $(PY3VERSIONS:%=test-python%)
-
-test-python2.6:
-       # Tests are not backported to python2.6, sorry.
+override_dh_auto_test: $(PY3VERSIONS:%=test-python%)
 
 test-python%:
        PATH=test/:$${PATH} PYTHONPATH=. python$* test/test_lsb_release.py -vv
        PYTHONPATH=. python$* test/test_initdutils.py -vv
+       rm -rf __pycache__
+       rm -rf test/__pycache__
+       rm -f test/debian_version_*
 
-override_dh_python2:
-       dh_python2
-       dh_python2 /usr/lib/lsb
+override_dh_python3:
+       dh_python3
+       dh_python3 /usr/lib/lsb
 
 override_dh_install:
        dh_install
index 420fc861489e45d6d5c40ef5e8fc5d969856a496..f2e90a8f75546b259ecc36e4e4b8cf71a0d0b736 100644 (file)
@@ -3,10 +3,7 @@
 import re, sys, os
 import pickle
 
-try:
-    from io import StringIO
-except ImportError:
-    from cStringIO import StringIO
+from io import StringIO
 
 class RFC822Parser(dict):
     "A dictionary-like object."
@@ -78,13 +75,13 @@ def scan_initfile(initfile):
 
     inheaders = RFC822Parser(strob=headerlines)
     headers = {}
-    for header, body in inheaders.iteritems():
+    for header, body in inheaders.items():
         # Ignore empty headers
         if not body.strip():
             continue
         
         if header in ('Default-Start', 'Default-Stop'):
-            headers[header] = map(int, body.split())
+            headers[header] = list(map(int, body.split()))
         elif header in ('Required-Start', 'Required-Stop', 'Provides',
                         'Should-Start', 'Should-Stop'):
             headers[header] = body.split()
@@ -107,19 +104,19 @@ def save_facilities(facilities):
         if facility.startswith('$'): continue
         for (scriptname, pri) in entries.items():
             start, stop = pri
-            print >> fh, "%(scriptname)s %(facility)s %(start)d %(stop)d" % locals()
+            print("%(scriptname)s %(facility)s %(start)d %(stop)d" % locals(), file=fh)
     fh.close()
 
 def load_facilities():
     facilities = {}
     if os.path.exists(FACILITIES):
-        for line in open(FACILITIES).xreadlines():
+        for line in open(FACILITIES):
             try:
                 scriptname, name, start, stop = line.strip().split()
                 facilities.setdefault(name, {})[scriptname] = (int(start),
                                                                int(stop))
             except ValueError as x:
-                print >> sys.stderr, 'Invalid facility line', line
+                print('Invalid facility line', line, file=sys.stderr)
 
     return facilities
 
@@ -128,7 +125,7 @@ def load_depends():
 
     if os.path.exists(DEPENDS):
         independs = RFC822Parser(fileob=open(DEPENDS))
-        for initfile, facilities in independs.iteritems():
+        for initfile, facilities in independs.items():
             depends[initfile] = facilities.split()
     return depends
 
@@ -141,8 +138,8 @@ def save_depends(depends):
         return
     
     fh = open(DEPENDS, 'w')
-    for initfile, facilities in depends.iteritems():
-        print >> fh, '%s: %s' % (initfile, ' '.join(facilities))
+    for initfile, facilities in depends.items():
+        print('%s: %s' % (initfile, ' '.join(facilities)), file=fh)
     fh.close()
 
 # filemap entries are mappings, { (package, filename) : instloc }
@@ -173,4 +170,4 @@ def save_lsbinstall_info(filemap):
     fh.close()
 
 if __name__ == '__main__':
-    print (scan_initfile('init-fragment'))
+    print(scan_initfile('init-fragment'))
index 4ec8452ff2754872089b4a2ec3b11459b4abb5a2..fdf2ff57e9f22c944d06b8a66be66920f914b657 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import sys, re, os, initdutils
 
@@ -12,7 +12,7 @@ if len(sys.argv) > 1:
     else:
         initfile = os.path.join('/etc/init.d', initfile)
 else:
-    print >> sys.stderr, 'Usage: %s /etc/init.d/<init-script>' % sys.argv[0]
+    print('Usage: %s /etc/init.d/<init-script>' % sys.argv[0], file=sys.stderr)
     sys.exit(1)
 
 # Default priorities
@@ -51,10 +51,10 @@ if reqstart or shouldstart:
     startpri = 5
     for facility in reqstart:
         if facility not in facilities:
-            print >> sys.stderr, 'Missing required start facility', facility
+            print('Missing required start facility', facility, file=sys.stderr)
             sys.exit(1)
         else:
-            for script, pri in facilities[facility].iteritems():
+            for script, pri in facilities[facility].items():
                 if script != initfile:
                     start, stop = pri
                     startpri = max(startpri, start+1)
@@ -63,9 +63,9 @@ if reqstart or shouldstart:
     
     for facility in shouldstart:
         if facility not in facilities:
-            print >> sys.stderr, 'Missing should-start facility', facility, '(ignored)'
+            print('Missing should-start facility', facility, '(ignored)', file=sys.stderr)
         else:
-            for script, pri in facilities[facility].iteritems():
+            for script, pri in facilities[facility].items():
                 if script != initfile:
                     start, stop = pri
                     startpri = max(startpri, start+1)
@@ -77,10 +77,10 @@ if reqstop or shouldstop:
     stoppri = 95
     for facility in reqstop:
         if facility not in facilities:
-            print >> sys.stderr, 'Missing required stop facility', facility
+            print('Missing required stop facility', facility, file=sys.stderr)
             sys.exit(1)
         else:
-            for script, pri in facilities[facility].iteritems():
+            for script, pri in facilities[facility].items():
                 if script != initfile:
                     start, stop = pri
                     stoppri = min(stoppri, stop-1)
@@ -89,9 +89,9 @@ if reqstop or shouldstop:
 
     for facility in shouldstop:
         if facility not in facilities:
-            print >> sys.stderr, 'Missing should-stop facility', facility, '(ignored)'
+            print('Missing should-stop facility', facility, '(ignored)', file=sys.stderr)
         else:
-            for script, pri in facilities[facility].iteritems():
+            for script, pri in facilities[facility].items():
                 if script != initfile:
                     start, stop = pri
                     stoppri = min(stoppri, stop-1)
@@ -105,9 +105,9 @@ provides = headers.get('Provides', [])
 if provides:
     for facility in provides:
         if facility[0] == '$':
-            print >> sys.stderr, 'Ignoring system-provided facility', facility
+            print('Ignoring system-provided facility', facility, file=sys.stderr)
             continue
-        if not facilities.has_key(facility):
+        if facility not in facilities:
             facilities[facility] = {}
 
         facilities[facility][initfile] = (startpri, stoppri)
index 5e3fc5c18eea8c4524f0f5bed763e0a340d9430b..433d5a50236ee2886c9e06ff6cca26bbbd819edb 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python -Es
+#!/usr/bin/python3 -Es
 
 # lsb_release command for Debian
 # (C) 2005-10 Chris Lawrence <lawrencc@debian.org>
@@ -17,9 +17,6 @@
 #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 #    02110-1301 USA
 
-# Python3-compatible print() function
-from __future__ import print_function
-
 from optparse import OptionParser
 import sys
 import os
index ecf46e3ebbcf6b67aae5e2e226d3ba5a6df369cf..94dad4e4dc57ec2e165dc549f52a69484bfa2eb3 100644 (file)
@@ -204,7 +204,7 @@ def compare_release(x, y):
 def parse_apt_policy():
     data = []
     
-    C_env = os.environ.copy(); C_env['LC_ALL'] = 'C'
+    C_env = os.environ.copy(); C_env['LC_ALL'] = 'C.UTF-8'
     policy = subprocess.Popen(['apt-cache','policy'],
                               env=C_env,
                               stdout=subprocess.PIPE,
index f00751792e2e7449700ee6d626ca5cdbac0bb140..4ae66f6b89b2580db5f935e077cbe026490821ea 100755 (executable)
@@ -1,10 +1,10 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import sys
 import os
 import shutil
 import socket
-import commands
+import subprocess
 from tempfile import NamedTemporaryFile
 from initdutils import load_lsbinstall_info, save_lsbinstall_info
 
@@ -19,7 +19,7 @@ objecttypes = (
     )
 
 def installed_message(objectname):
-    print objectname, 'is installed'
+    print(objectname, 'is installed')
 
 def handle_generic_install(options, args, location, showinstloc=False):
     filename = args[0]
@@ -40,9 +40,9 @@ def handle_generic_install(options, args, location, showinstloc=False):
         if os.path.exists(fileinfo):
             try:
                 os.unlink(fileinfo)
-            except (IOError, OSError, os.error), why:
-                print >> sys.stderr, 'Removal of %s failed: %s' % (
-                    instloc, str(why))
+            except OSError as why:
+                print('Removal of %s failed: %s' % (
+                    instloc, str(why)), file=sys.stderr)
                 sys.exit(1)
 
         # Remove it from the database, even if it was previously removed
@@ -54,27 +54,27 @@ def handle_generic_install(options, args, location, showinstloc=False):
         instloc = os.path.join(location, '%s.%s' % (options.package, basename))
 
     if os.path.exists(instloc):
-        print >> sys.stderr, 'Unable to install %s: %s exists' % (
-            filename, instloc)
+        print('Unable to install %s: %s exists' % (
+            filename, instloc), file=sys.stderr)
         sys.exit(1)
 
     if not os.path.exists(location):
         try:
             os.makedirs(location)
-        except (IOError, OSError, os.error), why:
-            print >> sys.stderr, 'Unable to create %s to install %s: %s' % (
-                location, filename, str(why))
+        except OSError as why:
+            print('Unable to create %s to install %s: %s' % (
+                location, filename, str(why)), file=sys.stderr)
             sys.exit(1)
         
     try:
         shutil.copy2(filename, instloc)
-    except (IOError, os.error), why:
-        print >> sys.stderr, 'Installation of %s as %s failed: %s' % (
-            filename, instloc, str(why))
+    except (IOError, os.error) as why:
+        print('Installation of %s as %s failed: %s' % (
+            filename, instloc, str(why)), file=sys.stderr)
         sys.exit(1)
         
     if showinstloc:
-        print instloc
+        print(instloc)
 
     filemap[(package, filename)] = instloc
     save_lsbinstall_info(filemap)
@@ -90,8 +90,8 @@ def handle_service(options, args):
         pproto = args[0]
         port, proto = pproto.split('/', 1)
         port = int(port)
-    except:
-        print >> sys.stderr, 'You must specify a port/protocol pair as the first argument.'
+    except ValueError:
+        print('You must specify a port/protocol pair as the first argument.', file=sys.stderr)
         sys.exit(2)
 
     if options.check:
@@ -100,7 +100,7 @@ def handle_service(options, args):
         except socket.error:
             sys.exit(1)
 
-        print '%d/%s corresponds to service %s' % (port, proto, serv)
+        print('%d/%s corresponds to service %s' % (port, proto, serv))
         return
 
     sname = args[1]
@@ -143,7 +143,7 @@ def handle_service(options, args):
                             laliases += [a]
                 elif name == lname or name in laliases:
                     # name shows up, but in wrong protocol/port
-                    print >> sys.stderr, 'Conflict between specified addition and /etc/services; aborting.'
+                    print('Conflict between specified addition and /etc/services; aborting.', file=sys.stderr)
                     fpout.close()
                     os.unlink(newfname)
                     sys.exit(1)
@@ -157,7 +157,7 @@ def handle_service(options, args):
                 line = '%15s %15s %s' % lname, lpproto, endbits
                 line = line.rstrip()
 
-            print >> fpout, line
+            print(line, file=fpout)
         
         fpin.close()
         fpout.close()
@@ -167,8 +167,8 @@ def handle_service(options, args):
         return
 
     fp = open('/etc/services', 'a')
-    print >> fp, '%15s %15s %s # Added by lsbinstall for %s' % (
-        sname, pproto, ' '.join(saliases), pkg)
+    print('%15s %15s %s # Added by lsbinstall for %s' % (
+        sname, pproto, ' '.join(saliases), pkg), file=fp)
     fp.close()
 
 def handle_inet(options, args, parser):
@@ -184,7 +184,7 @@ def handle_inet(options, args, parser):
     
     if options.remove:
         parts = r'%s\s+.*\s+%s\s+.*' % (re.escape(alist[0], alist[1]))
-        cmd += '--remove '+commands.mkarg(parts)
+        cmd += '--remove '+subprocess.mkarg(parts)
     elif options.check:
         return
     else:
@@ -192,7 +192,7 @@ def handle_inet(options, args, parser):
             parser.error('The operand must have six colon-separated arguments.')
             return
         newalist = [alist[0], alist[2], alist[1]] + alist[3:]
-        cmd += '--add '+commands.mkarg('\t'.join(newalist))
+        cmd += '--add '+subprocess.mkarg('\t'.join(newalist))
 
     os.system(cmd)
     pass
@@ -264,7 +264,7 @@ def main():
             parser.error('Only one argument supported for %s' % options.type)
         handle_man(options, args)
     else:
-        print >> sys.stderr, 'Unsupported type %s' % options.type
+        print('Unsupported type %s' % options.type, file=sys.stderr)
         sys.exit(1)
 
 if __name__ == '__main__':
index 0322c7f77ec8d73d595e6299bc4a4978720547c0..2eaa440a1511f557275a43f848e3c44b9e43b739 100755 (executable)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 import sys, re, os, initdutils
 
@@ -12,7 +12,7 @@ if len(sys.argv) > 1:
     else:
         initfile = os.path.join('/etc/init.d', initfile)
 else:
-    print >> sys.stderr, 'Usage: %s /etc/init.d/<init-script>' % sys.argv[0]
+    print('Usage: %s /etc/init.d/<init-script>' % sys.argv[0], file=sys.stderr)
     sys.exit(1)
 
 headers = initdutils.scan_initfile(initfile)
@@ -30,13 +30,13 @@ if provides:
                     entries[entry[0]] = entry[1]
             facilities[facility] = entries
 
-    for (initscript, needed) in depends.iteritems():
+    for (initscript, needed) in depends.items():
         for facility in needed:
             if facility[0] == "$":
                 continue
             if not facilities.get(facility) and facility in provides:
-                print >> sys.stderr, 'Unable to remove %s: %s needs %s\n' % (
-                    initfile, initscript, facility)
+                print('Unable to remove %s: %s needs %s\n' % (
+                    initfile, initscript, facility), file=sys.stderr)
                 sys.exit(1)
 
     if initfile in depends:
index c9a3ae7440f3c9b97a8eae1209ed0f7ae3f14f91..7492dc07010774385465de1ce8433e2d02e20e05 100755 (executable)
@@ -1,11 +1,8 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 # coding=utf-8
 
 # Fake apt-cache python script to emulate policy output for test usage
 
-# Python3-compatible print() function
-from __future__ import print_function
-
 import sys
 import os
 
index 8ff193b697f799978358f7f6c44e933271cf901f..6a79fccf3257d91edf06c0f8423d4a2cf63dc396 100755 (executable)
@@ -1,10 +1,7 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 
 # Fake dpkg-query  python script to emulate output for test usage
 
-# Python3-compatible print() function
-from __future__ import print_function
-
 import sys
 import os
 import random
index cdb5a9e431e7f1c1d7da08b3438cdf3cc553e2bd..07952d89a693423ff77f53b6b2c006207628999a 100644 (file)
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 import unittest
 
 import initdutils as iu
index ae1e1c9e2227217a91b10ea3f58360b82130866f..8681bec73f68095cf981d28da0898649d8c92b5c 100644 (file)
@@ -1,6 +1,5 @@
-#!/usr/bin/python
+#!/usr/bin/python3
 # coding=utf-8
-from __future__ import unicode_literals
 
 import unittest