summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorWolfgang Rohdewald <wolfgang@rohdewald.de>2016-08-05 10:35:06 (GMT)
committerWolfgang Rohdewald <wolfgang@rohdewald.de>2016-08-24 10:26:50 (GMT)
commit72179021015e7a2ba7c7a483d9d75efc70e3ecda (patch)
treec3d82561c3d43fe36cee2ddc42d7804f7bd51c02
parent118a84030403f8692f5e4ba4693cc056c770cee4 (diff)
CSV: encapsulate differences between py2 and py3 in new compat.py
-rw-r--r--CMakeLists.txt1
-rw-r--r--src/compat.py64
-rw-r--r--src/game.py6
-rwxr-xr-xsrc/kajonggtest.py10
4 files changed, 73 insertions, 8 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 2146806..629bda8 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -33,6 +33,7 @@ src/client.py
src/intelligence.py
src/altint.py
src/common.py
+src/compat.py
src/config.py
src/kdestub.py
src/deferredutil.py
diff --git a/src/compat.py b/src/compat.py
new file mode 100644
index 0000000..aec7b6e
--- /dev/null
+++ b/src/compat.py
@@ -0,0 +1,64 @@
+# -*- coding: utf-8 -*-
+
+"""
+Copyright (C) 2008-2014 Wolfgang Rohdewald <wolfgang@rohdewald.de>
+
+Kajongg 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+"""
+
+from __future__ import print_function
+
+import csv
+
+from common import isPython3, unicode
+
+class CsvWriter(object):
+ """hide differences between Python 2 and 3"""
+ def __init__(self, filename, mode='w'):
+ self.outfile = open(filename, mode if isPython3 else mode+'b')
+ self.__writer = csv.writer(self.outfile, delimiter=Csv.delimiter)
+
+ def writerow(self, row):
+ """write one row"""
+ if isPython3:
+ self.__writer.writerow(list(
+ cell if isinstance(cell, unicode) else str(cell) for cell in row))
+ else:
+ self.__writer.writerow(list(
+ cell.encode('utf-8') if isinstance(cell, unicode) else str(cell) for cell in row))
+
+ def __del__(self):
+ """clean up"""
+ self.outfile.close()
+
+class Csv(object):
+ """hide differences between Python 2 and 3"""
+
+ delimiter = ';'
+
+ @staticmethod
+ def unicode_reader(infile):
+ """generator decoding utf-8 input"""
+ for row in csv.reader(infile, delimiter=Csv.delimiter):
+ yield list(cell.decode('utf-8') for cell in row)
+
+ @staticmethod
+ def reader(filename):
+ """returns a generator for decoded strings"""
+ if isPython3:
+ return csv.reader(open(filename, 'r', encoding='utf-8'), delimiter=Csv.delimiter)
+ else:
+ return Csv.unicode_reader(open(filename, 'rb'))
+
diff --git a/src/game.py b/src/game.py
index 5ee9d07..48ce209 100644
--- a/src/game.py
+++ b/src/game.py
@@ -21,7 +21,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
import datetime
import weakref
import os
-import csv
if os.name != 'nt':
import resource
from random import Random
@@ -39,6 +38,7 @@ from sound import Voice
from wall import Wall
from move import Move
from player import Players, Player, PlayingPlayer
+from compat import CsvWriter
class CountingRandom(Random):
@@ -880,7 +880,7 @@ class PlayingGame(Game):
"""write game summary to Options.csv"""
if self.finished() and Options.csv:
gameWinner = max(self.players, key=lambda x: x.balance)
- writer = csv.writer(open(Options.csv, 'ab'), delimiter=';')
+ writer = CsvWriter(Options.csv, mode='a')
if Debug.process and os.name != 'nt':
self.csvTags.append('MEM:%s' % resource.getrusage(
resource.RUSAGE_SELF).ru_maxrss)
@@ -889,7 +889,7 @@ class PlayingGame(Game):
row = [self.ruleset.name, Options.AI, gitHead(), str(self.seed),
','.join(self.csvTags)]
for player in sorted(self.players, key=lambda x: x.name):
- row.append(player.name.encode('utf-8'))
+ row.append(player.name)
row.append(player.balance)
row.append(player.wonCount)
row.append(1 if player == gameWinner else 0)
diff --git a/src/kajonggtest.py b/src/kajonggtest.py
index 473ffdf..2d0b22e 100755
--- a/src/kajonggtest.py
+++ b/src/kajonggtest.py
@@ -26,7 +26,6 @@ signal.signal(signal.SIGINT, signal.SIG_DFL)
import os
import sys
-import csv
import subprocess
import random
import shutil
@@ -38,6 +37,7 @@ from optparse import OptionParser
from common import Debug, StrMixin
from util import removeIfExists, gitHead, checkMemory
+from compat import Csv, CsvWriter
# fields in row:
RULESETFIELD = 0
@@ -344,7 +344,7 @@ def neutralize(rows):
"""remove things we do not want to compare"""
for row in rows:
for idx, field in enumerate(row):
- if field.startswith('Tester '):
+ if field.startswith(u'Tester '):
row[idx] = 'Tester'
if 'MEM' in field:
parts = field.split(',')
@@ -373,7 +373,7 @@ def removeInvalidCommits(csvFile):
"""remove rows with invalid git commit ids"""
if not os.path.exists(csvFile):
return
- rows = list(csv.reader(open(csvFile, 'rb'), delimiter=';'))
+ rows = list(Csv.reader(csvFile))
_ = set(x[COMMITFIELD] for x in rows)
csvCommits = set(
x for x in _ if set(
@@ -385,7 +385,7 @@ def removeInvalidCommits(csvFile):
print(
'removing rows from kajongg.csv for commits %s' %
','.join(nonExisting))
- writer = csv.writer(open(csvFile, 'wb'), delimiter=';')
+ writer = CsvWriter(csvFile)
for row in rows:
if row[COMMITFIELD] not in nonExisting:
writer.writerow(row)
@@ -405,7 +405,7 @@ def readGames(csvFile):
"""returns a dict holding a frozenset of games for each variant"""
if not os.path.exists(csvFile):
return
- allRows = neutralize(csv.reader(open(csvFile, 'rb'), delimiter=';'))
+ allRows = neutralize(Csv.reader(csvFile))
if not allRows:
return
# we want unique tuples so we can work with sets