# HG changeset patch # User Ludovic Chabant # Date 1429502294 25200 # Node ID 03e3e793fa2217bc6f7477e588311c91c0ca1b4a # Parent cc038c6369015c66e464a39d514c89aedf146c9d Convert project to Python 3.4. diff -r cc038c636901 -r 03e3e793fa22 requirements.txt --- a/requirements.txt Sun Apr 19 20:54:10 2015 -0700 +++ b/requirements.txt Sun Apr 19 20:58:14 2015 -0700 @@ -1,12 +1,15 @@ +colorama==0.2.7 Flask==0.10.1 Flask-Login==0.2.10 -Flask-Script==0.5.1 -Jinja2==2.7.2 +itsdangerous==0.24 +Jinja2==2.7.3 Markdown==2.2.1 +MarkupSafe==0.23 +py==1.4.26 Pygments==1.6 +pytest==2.5.2 +python-hglib===unknown +repoze.lru==0.6 SQLAlchemy==0.9.3 +Werkzeug==0.10.4 Whoosh==2.5.5 -colorama==0.2.7 -pytest==2.5.2 -repoze.lru==0.6 -python-hglib diff -r cc038c636901 -r 03e3e793fa22 tests/__init__.py --- a/tests/__init__.py Sun Apr 19 20:54:10 2015 -0700 +++ b/tests/__init__.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,11 +1,11 @@ import os import os.path -import urllib +import urllib.request, urllib.parse, urllib.error import shutil import unittest from wikked.wiki import Wiki from wikked.db.sql import SQLDatabase -from mock import MockWikiParameters, MockFileSystem +from .mock import MockWikiParameters, MockFileSystem class MockWikiParametersWithStructure(MockWikiParameters): @@ -26,7 +26,7 @@ def tearDown(self): if hasattr(self, 'wiki') and self.wiki is not None: - self.wiki.db.close(False, None) + self.wiki.db.close(None) if os.path.isdir(self.test_data_dir): shutil.rmtree(self.test_data_dir) @@ -68,7 +68,7 @@ res = '\w[\w\d]*)\s*=(?P.*)', value) if m: - name = unicode(m.group('name')) - value = unicode(m.group('value')) + name = str(m.group('name')) + value = str(m.group('value')) value = html_escape(value.strip()) parameters += '
%s
' % (name, value) @@ -182,8 +182,8 @@ arg_pattern = r"(\A|\|)\s*(?P(__)?[a-zA-Z][a-zA-Z0-9_\-]+)\s*="\ r"(?P[^\|]+)" for m in re.finditer(arg_pattern, query, re.MULTILINE): - name = unicode(m.group('name')).strip() - value = unicode(m.group('value')).strip() + name = str(m.group('name')).strip() + value = str(m.group('value')).strip() processed_args.append('%s=%s' % (name, value)) mod_attr = '' @@ -230,7 +230,7 @@ urls = [] pattern = r"
[^\"]+)\">" for m in re.finditer(pattern, text): - urls.append(unicode(m.group('url'))) + urls.append(str(m.group('url'))) return urls LEXER_STATE_NORMAL = 0 diff -r cc038c636901 -r 03e3e793fa22 wikked/fs.py --- a/wikked/fs.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/fs.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,12 +1,11 @@ import os import os.path import re -import string import codecs import fnmatch import logging import itertools -from utils import (PageNotFoundError, NamespaceNotFoundError, +from .utils import (PageNotFoundError, NamespaceNotFoundError, split_page_url) @@ -39,7 +38,7 @@ to list existing pages. """ def __init__(self, root, config): - self.root = unicode(root) + self.root = root self.excluded = None self.page_extensions = None @@ -47,7 +46,7 @@ def start(self, wiki): self.page_extensions = list(set( - itertools.chain(*wiki.formatters.itervalues()))) + itertools.chain(*wiki.formatters.values()))) excluded = [] excluded += wiki.getSpecialFilenames() @@ -84,8 +83,6 @@ def getPageInfo(self, path): logger.debug("Reading page info from: %s" % path) - if not isinstance(path, unicode): - path = unicode(path) for e in self.excluded: if fnmatch.fnmatch(path, e): return None @@ -101,7 +98,7 @@ logger.debug("Saving page '%s' to: %s" % (url, path)) dirname = os.path.dirname(path) if not os.path.isdir(dirname): - os.makedirs(dirname, 0775) + os.makedirs(dirname, 0o775) with codecs.open(path, 'w', encoding='utf-8') as f: f.write(content) return PageInfo(url, path) @@ -137,14 +134,14 @@ url = '/' + name if meta: - url = u"%s:/%s" % (meta.lower(), name) + url = "%s:/%s" % (meta.lower(), name) return PageInfo(url, abs_path) def _getPhysicalPath(self, url, is_file=True, make_new=False): endpoint, url = split_page_url(url) if url[0] != '/': raise ValueError("Page URLs need to be absolute: " + url) - if string.find(url, '..') >= 0: + if '..' in url: raise ValueError("Page URLs can't contain '..': " + url) # Find the root directory in which we'll be searching for the diff -r cc038c636901 -r 03e3e793fa22 wikked/indexer/whooshidx.py --- a/wikked/indexer/whooshidx.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/indexer/whooshidx.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,7 +1,7 @@ import os import os.path import logging -from base import WikiIndex, HitResult +from .base import WikiIndex, HitResult from whoosh.analysis import (StandardAnalyzer, StemmingAnalyzer, CharsetFilter, NgramFilter) from whoosh.fields import Schema, ID, TEXT, STORED @@ -119,10 +119,10 @@ def _indexPage(self, writer, page): logger.debug("Indexing '%s'." % page.url) writer.add_document( - url=unicode(page.url), - title_preview=unicode(page.title), - title=unicode(page.title), - text=unicode(page.text), + url=page.url, + title_preview=page.title, + title=page.title, + text=page.text, path=page.path, time=os.path.getmtime(page.path) ) diff -r cc038c636901 -r 03e3e793fa22 wikked/page.py --- a/wikked/page.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/page.py Sun Apr 19 20:58:14 2015 -0700 @@ -2,7 +2,7 @@ import os.path import re import logging -from formatter import PageFormatter, FormattingContext +from .formatter import PageFormatter, FormattingContext logger = logging.getLogger(__name__) diff -r cc038c636901 -r 03e3e793fa22 wikked/resolver.py --- a/wikked/resolver.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/resolver.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,5 +1,5 @@ import re -import urllib +import urllib.request, urllib.parse, urllib.error import os.path import logging import jinja2 @@ -83,7 +83,7 @@ self.meta = dict(page.getLocalMeta()) def add(self, other): - for original_key, val in other.meta.iteritems(): + for original_key, val in other.meta.items(): # Ignore internal properties. Strip include-only properties # from their prefix. key, mod = get_meta_name_and_modifiers(original_key) @@ -135,9 +135,9 @@ return self._unsafeRun() except Exception as e: logger.error("Error resolving page '%s':" % self.page.url) - logger.exception(unicode(e.message)) + logger.exception(e.message) self.output = ResolveOutput(self.page) - self.output.text = u'
%s
' % e + self.output.text = '
%s
' % e return self.output def _getPage(self, url): @@ -173,15 +173,15 @@ # Resolve queries, includes, etc. def repl2(m): - meta_name = unicode(m.group('name')) - meta_value = unicode(m.group('value')) + meta_name = m.group('name') + meta_value = m.group('value') meta_opts = {} if m.group('opts'): for c in re.finditer( r'data-wiki-(?P[a-z]+)="(?P[^"]+)"', - unicode(m.group('opts'))): - opt_name = unicode(c.group('name')) - opt_value = unicode(c.group('value')) + m.group('opts')): + opt_name = c.group('name') + opt_value = c.group('value') meta_opts[opt_name] = opt_value resolver = self.resolvers.get(meta_name) @@ -207,10 +207,10 @@ # Resolve link states. def repl1(m): - raw_url = unicode(m.group('url')) + raw_url = m.group('url') url = self.ctx.getAbsoluteUrl(raw_url) self.output.out_links.append(url) - quoted_url = urllib.quote(url.encode('utf-8')) + quoted_url = urllib.parse.quote(url.encode('utf-8')) if self.wiki.pageExists(url): return '
' % quoted_url return '' % quoted_url @@ -261,12 +261,12 @@ # root page. arg_pattern = r'
(?P.*?)
' for i, m in enumerate(re.finditer(arg_pattern, args)): - value = unicode(m.group('value')).strip() + value = m.group('value').strip() value = html_unescape(value) value = self._renderTemplate(value, self.parameters, error_url=self.page.url) if m.group('name'): - key = unicode(m.group('name')).lower() + key = m.group('name').lower() parameters[key] = value else: parameters['__xargs'].append(value) @@ -306,9 +306,9 @@ for m in re.finditer(arg_pattern, query): key = m.group('name').lower() if key in parameters: - parameters[key] = unicode(m.group('value')) + parameters[key] = m.group('value') else: - meta_query[key] = unicode(m.group('value')) + meta_query[key] = m.group('value') # Find pages that match the query, excluding any page # that is in the URL trail. @@ -317,13 +317,13 @@ for p in self.pages_meta_getter(): if p.url in self.ctx.url_trail: continue - for key, value in meta_query.iteritems(): + for key, value in meta_query.items(): try: if self._isPageMatch(p, key, value): matched_pages.append(p) except Exception as e: logger.error("Can't query page '%s' for '%s':" % (p.url, self.page.url)) - logger.exception(unicode(e.message)) + logger.exception(e.message) # We'll have to format things... fmt_ctx = FormattingContext(self.page.url) @@ -440,7 +440,7 @@ def _getFormatter(self, extension): known_exts = [] - for k, v in self.page.wiki.formatters.iteritems(): + for k, v in self.page.wiki.formatters.items(): if extension in v: return k known_exts += v diff -r cc038c636901 -r 03e3e793fa22 wikked/scheduler.py --- a/wikked/scheduler.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/scheduler.py Sun Apr 19 20:58:14 2015 -0700 @@ -3,7 +3,7 @@ import datetime import threading import jinja2 -from Queue import Queue, Empty +from queue import Queue, Empty from repoze.lru import LRUCache from wikked.resolver import PageResolver, ResolveOutput, CircularIncludeError diff -r cc038c636901 -r 03e3e793fa22 wikked/scm/git.py --- a/wikked/scm/git.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/scm/git.py Sun Apr 19 20:58:14 2015 -0700 @@ -2,7 +2,7 @@ import os.path import logging import subprocess -from base import ( +from .base import ( SourceControl, STATE_NEW, STATE_MODIFIED, STATE_COMMITTED) diff -r cc038c636901 -r 03e3e793fa22 wikked/scm/mercurial.py --- a/wikked/scm/mercurial.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/scm/mercurial.py Sun Apr 19 20:58:14 2015 -0700 @@ -8,7 +8,7 @@ import subprocess from hglib.error import CommandError from hglib.util import cmdbuilder -from base import ( +from .base import ( SourceControl, Author, Revision, SourceControlError, ACTION_ADD, ACTION_EDIT, ACTION_DELETE, STATE_NEW, STATE_MODIFIED, STATE_COMMITTED) @@ -61,7 +61,8 @@ MercurialBaseSourceControl.__init__(self, root) self.hg = 'hg' - self.log_style = os.path.join(os.path.dirname(__file__), 'resources', 'hg_log.style') + self.log_style = os.path.join(os.path.dirname(__file__), + 'resources', 'hg_log.style') def getHistory(self, path=None, limit=10, after_rev=None): if path is not None: @@ -148,7 +149,8 @@ m = re.match(r'(\d+) ([0-9a-f]+) \[([^\]]+)\] ([^ ]+)', lines[0]) if m is None: - raise Exception('Error parsing history from Mercurial, got: ' + lines[0]) + raise Exception('Error parsing history from Mercurial, got: ' + + lines[0]) rev = Revision() rev.rev_id = int(m.group(1)) @@ -190,6 +192,24 @@ cl_lock = threading.Lock() +def _b(strs): + """ Convert a list of strings to binary UTF8 arrays. """ + if strs is None: + return None + if isinstance(strs, str): + return strs.encode('utf8') + return list([s.encode('utf8') if s is not None else None for s in strs]) + + +def _s(strs): + """ Convert a byte array to string using UTF8 encoding. """ + if strs is None: + return None + if isinstance(strs, bytes): + return strs.decode('utf8') + return list([s.decode('utf8') if s is not None else None for s in strs]) + + def create_hg_client(root): logger.debug("Spawning Mercurial command server at: %s" % root) import hglib @@ -241,7 +261,7 @@ def getHistory(self, path=None, limit=10, after_rev=None): if path is not None: - status = self.client.status(include=[path]) + status = _s(self.client.status(include=_b([path]))) if len(status) > 0 and status[0] == '?': return [] @@ -253,34 +273,34 @@ needs_files = False if path is not None: - repo_revs = self.client.log(files=[path], follow=True, - limit=limit, revrange=rev) + repo_revs = self.client.log(files=_b([path]), follow=True, + limit=limit, revrange=_b(rev)) else: needs_files = True repo_revs = self.client.log(follow=True, limit=limit, - revrange=rev) + revrange=_b(rev)) revisions = [] for rev in repo_revs: - r = Revision(rev.node) - r.rev_name = rev.node[:12] - r.author = Author(rev.author) + r = Revision(_s(rev.node)) + r.rev_name = _s(rev.node[:12]) + r.author = Author(_s(rev.author)) r.timestamp = time.mktime(rev.date.timetuple()) - r.description = unicode(rev.desc) + r.description = _s(rev.desc) if needs_files: rev_statuses = self.client.status(change=rev.node) for rev_status in rev_statuses: r.files.append({ - 'path': rev_status[1].decode('utf-8', 'replace'), - 'action': self.actions[rev_status[0]] + 'path': _s(rev_status[1]), + 'action': self.actions[_s(rev_status[0])] }) revisions.append(r) return revisions def getState(self, path): - statuses = self.client.status(include=[path]) + statuses = self.client.status(include=_b([path])) if len(statuses) == 0: return STATE_COMMITTED - status = statuses[0] + status = _s(statuses[0]) if status[0] == '?' or status[0] == 'A': return STATE_NEW if status[0] == 'M': @@ -288,12 +308,14 @@ raise Exception("Unsupported status: %s" % status) def getRevision(self, path, rev): - return self.client.cat([path], rev=rev) + return _s(self.client.cat(_b([path]), rev=_b(rev))) def diff(self, path, rev1, rev2): if rev2 is None: - return self.client.diff(files=[path], change=rev1, git=True) - return self.client.diff(files=[path], revs=[rev1, rev2], git=True) + return _s(self.client.diff(files=_b([path]), change=_b(rev1), + git=True)) + return _s(self.client.diff(files=_b([path]), revs=_b([rev1, rev2]), + git=True)) def commit(self, paths, op_meta): if 'message' not in op_meta or not op_meta['message']: @@ -301,13 +323,14 @@ kwargs = {} if 'author' in op_meta: - kwargs['u'] = op_meta['author'] + kwargs['u'] = _b(op_meta['author']) try: # We need to write our own command because somehow the `commit` # method in `hglib` doesn't support specifying the file(s) # directly -- only with `--include`. Weird. - args = cmdbuilder('commit', *paths, - debug=True, m=op_meta['message'], A=True, + args = cmdbuilder( + b'commit', *_b(paths), + debug=True, m=_b(op_meta['message']), A=True, **kwargs) self.client.rawcommand(args) except CommandError as e: @@ -315,7 +338,7 @@ def revert(self, paths=None): if paths is not None: - self.client.revert(files=paths, nobackup=True) + self.client.revert(files=_b(paths), nobackup=True) else: self.client.revert(all=True, nobackup=True) diff -r cc038c636901 -r 03e3e793fa22 wikked/utils.py --- a/wikked/utils.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/utils.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,7 +1,7 @@ import re import os import os.path -import urllib +import urllib.request, urllib.parse, urllib.error from xml.sax.saxutils import escape, unescape @@ -68,7 +68,7 @@ raw_abs_url = os.path.join(urldir, url) abs_url = os.path.normpath(raw_abs_url).replace('\\', '/') if quote: - abs_url = urllib.quote(abs_url.encode('utf-8')) + abs_url = urllib.parse.quote(abs_url.encode('utf-8')) if endpoint: return '%s:%s' % (endpoint, abs_url) return abs_url @@ -78,8 +78,8 @@ m = endpoint_regex.match(url) if m is None: return (None, url) - endpoint = unicode(m.group(1)) - path = unicode(m.group(2)) + endpoint = m.group(1) + path = m.group(2) return (endpoint, path) @@ -100,7 +100,7 @@ def flatten_single_metas(meta): - items = list(meta.iteritems()) + items = list(meta.items()) for k, v in items: if isinstance(v, list): l = len(v) @@ -112,7 +112,7 @@ html_escape_table = {'"': """, "'": "'"} -html_unescape_table = {v: k for k, v in html_escape_table.items()} +html_unescape_table = {v: k for k, v in list(html_escape_table.items())} def html_escape(text): return escape(text, html_escape_table) diff -r cc038c636901 -r 03e3e793fa22 wikked/views/__init__.py --- a/wikked/views/__init__.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/views/__init__.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,5 +1,5 @@ import os.path -import urllib +import urllib.request, urllib.parse, urllib.error import string import datetime from flask import g, abort, jsonify @@ -17,16 +17,16 @@ def url_from_viewarg(url): endpoint, path = split_url_from_viewarg(url) if endpoint: - return u'%s:%s' % (endpoint, path) + return '%s:%s' % (endpoint, path) return path def split_url_from_viewarg(url): - url = urllib.unquote(url) + url = urllib.parse.unquote(url) endpoint, path = split_page_url(url) if endpoint: return (endpoint, path) - return (None, u'/' + path) + return (None, '/' + path) def make_page_title(url): @@ -99,7 +99,7 @@ else: meta = dict(page.getMeta() or {}) meta['title'] = page.title - meta['url'] = urllib.quote(page.url.encode('utf-8')) + meta['url'] = urllib.parse.quote(page.url.encode('utf-8')) for name in COERCE_META: if name in meta: meta[name] = COERCE_META[name](meta[name]) @@ -110,7 +110,7 @@ result = [] for item in category: result.append({ - 'url': u'category:/' + urllib.quote(item.encode('utf-8')), + 'url': 'category:/' + urllib.parse.quote(item.encode('utf-8')), 'name': item }) return result diff -r cc038c636901 -r 03e3e793fa22 wikked/views/edit.py --- a/wikked/views/edit.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/views/edit.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,4 +1,4 @@ -import urllib +import urllib.request, urllib.parse, urllib.error from flask import g, abort, request, jsonify from flask.ext.login import current_user from wikked.page import Page, PageData @@ -43,7 +43,7 @@ if page is None: result = { 'meta': { - 'url': urllib.quote(url.encode('utf-8')), + 'url': urllib.parse.quote(url.encode('utf-8')), 'title': default_title or make_page_title(url) }, 'text': '' @@ -108,8 +108,8 @@ default_title = None custom_data = None if endpoint is not None: - url = u'%s:%s' % (endpoint, path) - default_title = u'%s: %s' % (endpoint, path) + url = '%s:%s' % (endpoint, path) + default_title = '%s: %s' % (endpoint, path) custom_data = { 'meta_query': endpoint, 'meta_value': path.lstrip('/') @@ -121,10 +121,10 @@ custom_data=custom_data) url = path - default_message = u'Edited ' + url + default_message = 'Edited ' + url if endpoint is not None: - url = u'%s:%s' % (endpoint, path) - default_message = u'Edited %s %s' % (endpoint, path.lstrip('/')) + url = '%s:%s' % (endpoint, path) + default_message = 'Edited %s %s' % (endpoint, path.lstrip('/')) return do_edit_page(url, default_message) diff -r cc038c636901 -r 03e3e793fa22 wikked/views/read.py --- a/wikked/views/read.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/views/read.py Sun Apr 19 20:58:14 2015 -0700 @@ -1,5 +1,5 @@ import time -import urllib +import urllib.request, urllib.parse, urllib.error from flask import (render_template, request, g, jsonify, make_response, abort) from flask.ext.login import current_user @@ -17,15 +17,15 @@ tpl_name = 'index.html' if app.config['WIKI_DEV_ASSETS']: tpl_name = 'index-dev.html' - return render_template(tpl_name, cache_bust=('?%d' % time.time())); + return render_template(tpl_name, cache_bust=('?%d' % time.time())) @app.route('/read/') -def read(): +def read(url): tpl_name = 'index.html' if app.config['WIKI_DEV_ASSETS']: tpl_name = 'index-dev.html' - return render_template(tpl_name, cache_bust=('?%d' % time.time())); + return render_template(tpl_name, cache_bust=('?%d' % time.time())) @app.route('/search') @@ -33,7 +33,7 @@ tpl_name = 'index.html' if app.config['WIKI_DEV_ASSETS']: tpl_name = 'index-dev.html' - return render_template(tpl_name, cache_bust=('?%d' % time.time())); + return render_template(tpl_name, cache_bust=('?%d' % time.time())) @app.route('/api/list') @@ -44,7 +44,7 @@ @app.route('/api/list/') def api_list_pages(url): wiki = get_wiki() - pages = filter(is_page_readable, wiki.getPages(url_from_viewarg(url))) + pages = list(filter(is_page_readable, wiki.getPages(url_from_viewarg(url)))) page_metas = [get_page_meta(page) for page in pages] result = {'path': url, 'pages': list(page_metas)} return jsonify(result) @@ -140,7 +140,7 @@ 'name': endpoint, 'url': meta_page_url, 'value': value, - 'safe_value': urllib.quote(value.encode('utf-8')), + 'safe_value': urllib.parse.quote(value.encode('utf-8')), 'pages': [get_page_meta(p) for p in pages] # TODO: skip pages that are forbidden for the current user } @@ -156,7 +156,7 @@ 'meta_value': value, 'query': query, 'meta': { - 'url': urllib.quote(meta_page_url.encode('utf-8')), + 'url': urllib.parse.quote(meta_page_url.encode('utf-8')), 'title': value }, 'text': text diff -r cc038c636901 -r 03e3e793fa22 wikked/views/special.py --- a/wikked/views/special.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/views/special.py Sun Apr 19 20:58:14 2015 -0700 @@ -43,7 +43,7 @@ rev_links[abs_l] = cnt + 1 or_pages = [] - for tgt, cnt in rev_links.iteritems(): + for tgt, cnt in rev_links.items(): if cnt == 0: or_pages.append(pages[tgt]) return or_pages @@ -93,7 +93,7 @@ redirs[p.url] = target dr_pages = [] - for src, tgt in redirs.iteritems(): + for src, tgt in redirs.items(): if tgt in redirs: dr_pages.append(pages[src]) return dr_pages diff -r cc038c636901 -r 03e3e793fa22 wikked/wiki.py --- a/wikked/wiki.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/wiki.py Sun Apr 19 20:58:14 2015 -0700 @@ -3,7 +3,7 @@ import time import logging import importlib -from ConfigParser import SafeConfigParser, NoOptionError +from configparser import SafeConfigParser, NoOptionError from wikked.page import FileSystemPage from wikked.fs import FileSystem from wikked.auth import UserManager @@ -426,5 +426,5 @@ mtimes[path] = mtime continue elif mtime > old_time: - print "Change detected in '%s'." % path + print("Change detected in '%s'." % path) time.sleep(interval) diff -r cc038c636901 -r 03e3e793fa22 wikked/witch.py --- a/wikked/witch.py Sun Apr 19 20:54:10 2015 -0700 +++ b/wikked/witch.py Sun Apr 19 20:58:14 2015 -0700 @@ -109,7 +109,7 @@ # Setup the command parsers. subparsers = parser.add_subparsers() - commands = map(lambda cls: cls(), command_classes) + commands = [cls() for cls in command_classes] logger.debug("Got %d commands." % len(commands)) for c in commands: cp = subparsers.add_parser(c.name, help=c.description) @@ -152,14 +152,14 @@ def print_version(): if os.path.isdir(os.path.join(os.path.dirname(__file__), '..', '.hg')): - print "Wikked (development version)" + print("Wikked (development version)") return 0 try: from wikked.__version__ import version except ImportError: - print "Can't find version information." + print("Can't find version information.") return 1 - print "Wikked %s" % version + print("Wikked %s" % version) return 0