diff --git a/src/diana/sgfParser/propValues.py b/src/diana/sgfParser/propValues.py
--- a/src/diana/sgfParser/propValues.py
+++ b/src/diana/sgfParser/propValues.py
@@ -4,175 +4,180 @@ from . import ParserError, skipWhitespac
 
 
 class Regexp:
-	number=re.compile(r"(\+|-|)\d+")
-	real=re.compile(r"(\+|-|)\d+(\.\d+)?")
-	point=re.compile(r"[a-zA-Z]{2}|")
-	text=re.compile(r"(?:.*?[^\\])??(?:\\\\)*(?=])", re.DOTALL)
-	composedText=re.compile(r"(?:.*?[^\\])??(?:\\\\)*(?=]|:)", re.DOTALL)
+	number = re.compile(r"(\+|-|)\d+")
+	real = re.compile(r"(\+|-|)\d+(\.\d+)?")
+	point = re.compile(r"[a-zA-Z]{2}|")
+	text = re.compile(r"(?:.*?[^\\])??(?:\\\\)*(?=])", re.DOTALL)
+	composedText = re.compile(r"(?:.*?[^\\])??(?:\\\\)*(?=]|:)", re.DOTALL)
 
 	class Text:
-		softBreaks=re.compile(r"(^|[^\\])((\\\\)*)\\((\n\r)|(\r\n)|\r|\n)")
-		whitespace=re.compile(r"[\t\f\v]")
-		simpleWhitespace=re.compile(r"[\t\f\v\n\r]")
-		removeSlashes=re.compile(r"(^|[^\\])((\\\\)*)\\($|[^\\])")
-		unescapeSlashes=re.compile(r"\\\\")
+		softBreaks = re.compile(r"(^|[^\\])((\\\\)*)\\((\n\r)|(\r\n)|\r|\n)")
+		whitespace = re.compile(r"[\t\f\v]")
+		simpleWhitespace = re.compile(r"[\t\f\v\n\r]")
+		removeSlashes = re.compile(r"(^|[^\\])((\\\\)*)\\($|[^\\])")
+		unescapeSlashes = re.compile(r"\\\\")
 
 
 class Composed:
-	def __init__(self,a=None,b=None):
-		self.a=a
-		self.b=b
+	def __init__(self, a=None, b=None):
+		self.a = a
+		self.b = b
 
 	def __str__(self):
-		return "{0}:{1}".format(self.a,self.b)
+		return "{0}:{1}".format(self.a, self.b)
 
 
 class Point:
-	def __init__(self,c,r):
-		self.r=r
-		self.c=c
+	def __init__(self, c, r):
+		self.r = r
+		self.c = c
 
 	def __iter__(self):
 		yield self.c
 		yield self.r
 
 	def __str__(self):
-		a=ord("a")
-		return chr(a+self.c)+chr(a+self.r)
+		a = ord("a")
+		return chr(a+self.c) + chr(a+self.r)
 
 
 ## Metatype matching one of the provided types.
 #
 # Returns the first match, so the order is important.
 def choose(*vTypes):
-	def f(s,start):
+	def f(s, start):
 		for vType in vTypes:
 			try:
-				i,x=vType(s,start)
-				return (i,x)
-			except ParserError: pass
-		raise ParserError("no variant of a 'choose' property value matched",s,start)
+				(i, x) = vType(s, start)
+				return (i, x)
+			except ParserError:
+				pass
+		raise ParserError("no variant of a 'choose' property value matched", s, start)
 	return f
 
 
-def singletonFits(s,i):
-	return i<len(s) and s[i]=="["
+def singletonFits(s, i):
+	return i < len(s) and s[i] == "["
 
 
-def singletonEnds(s,i):
-	return i<len(s) and s[i]=="]"
+def singletonEnds(s, i):
+	return i < len(s) and s[i] == "]"
 
 
 def singleton(vType):
-	def f(s,start):
-		if not singletonFits(s,start):
-			raise ParserError("expected a property value starting with '['",s,start)
-		i,x=vType(s,start+1)
-		if not singletonEnds(s,i):
-			raise ParserError("expected a property value ending with ']'",s,i)
-		i=skipWhitespace(s,i+1)
-		return (i,x)
+	def f(s, start):
+		if not singletonFits(s, start):
+			raise ParserError("expected a property value starting with '['", s, start)
+		(i, x) = vType(s, start+1)
+		if not singletonEnds(s, i):
+			raise ParserError("expected a property value ending with ']'", s, i)
+		i = skipWhitespace(s, i+1)
+		return (i, x)
 	return f
 
 
-def listOf(vType,allowEmpty=False):
-	def f(s,start):
-		i=start
-		if not singletonFits(s,i):
-			raise ParserError("expected a property value starting with '['",s,i)
-		if singletonEnds(s,i+1) and allowEmpty:
-			i=skipWhitespace(s,i+2)
-			return (i,[])
-		single=singleton(vType)
-		i,x=single(s,i)
-		res=[x]
-		while singletonFits(s,i):
-			i,x=single(s,i)
+def listOf(vType, allowEmpty=False):
+	def f(s, start):
+		i = start
+		if not singletonFits(s, i):
+			raise ParserError("expected a property value starting with '['", s, i)
+		if singletonEnds(s, i+1) and allowEmpty:
+			i = skipWhitespace(s, i+2)
+			return (i, [])
+		single = singleton(vType)
+		(i, x) = single(s, i)
+		res = [x]
+		while singletonFits(s, i):
+			(i, x) = single(s, i)
 			res.append(x)
-		return (i,res)
+		return (i, res)
 	return f
 
 
-def compose(vTypeA,vTypeB):
-	def f(s,start):
-		i,a=vTypeA(s,start)
-		if i>=len(s) or s[i]!=":":
-			raise ParserError("expected a composed property value separated by ':'",s,i)
-		i,b=vTypeB(s,i+1)
-		return (i,Composed(a,b))
+def compose(vTypeA, vTypeB):
+	def f(s, start):
+		(i, a) = vTypeA(s, start)
+		if i >= len(s) or s[i] != ":":
+			raise ParserError("expected a composed property value separated by ':'", s, i)
+		(i, b) = vTypeB(s, i+1)
+		return (i, Composed(a, b))
 	return f
 
 
-def number(s,start):
-	m=Regexp.number.match(s,start)
-	if m is None: raise ParserError("expected a number matching '{0}'".format(Regexp.number.pattern),s,start)
-	res=int(m.group(0))
-	return (m.end(),res)
+def number(s, start):
+	m = Regexp.number.match(s, start)
+	if m is None:
+		raise ParserError("expected a number matching '{0}'".format(Regexp.number.pattern), s, start)
+	res = int(m.group(0))
+	return (m.end(), res)
 
 
-def real(s,start):
-	m=Regexp.real.match(s,start)
-	if m is None: raise ParserError("expected a real number matching '{0}'".format(Regexp.real.pattern),s,start)
-	res=float(m.group(0))
-	return (m.end(),res)
+def real(s, start):
+	m = Regexp.real.match(s, start)
+	if m is None:
+		raise ParserError("expected a real number matching '{0}'".format(Regexp.real.pattern), s, start)
+	res = float(m.group(0))
+	return (m.end(), res)
 
 
-def double(s,start):
-	c=s[start]
+def double(s, start):
+	c = s[start]
 	if c not in ("1", "2"):
-		raise ParserError("expected a double value, either '1' or '2'",s,start)
-	return (start+1,c)
+		raise ParserError("expected a double value, either '1' or '2'", s, start)
+	return (start+1, c)
 
 
 def color(s,start):
-	c=s[start]
+	c = s[start]
 	if c not in ("B", "W"):
-		raise ParserError("expected a color value, either 'B' or 'W'",s,start)
-	return (start+1,c)
+		raise ParserError("expected a color value, either 'B' or 'W'", s, start)
+	return (start+1, c)
 
 
-def text(simple=True,composed=False):
-	def f(s,start):
-		regexps=Regexp.Text
-		m=Regexp.composedText.match(s,start) if composed else Regexp.text.match(s,start)
-		res=m.group(0)
-		res=regexps.softBreaks.sub(r"\1\2",res) # remove soft line breaks
+def text(simple=True, composed=False):
+	def f(s, start):
+		regexps = Regexp.Text
+		m = Regexp.composedText.match(s, start) if composed else Regexp.text.match(s, start)
+		res = m.group(0)
+		res = regexps.softBreaks.sub(r"\1\2", res)  # remove soft line breaks
 		if simple:
-			res=regexps.simpleWhitespace.sub(" ",res) # convert whitespace to spaces, no escapes
+			res = regexps.simpleWhitespace.sub(" ", res)  # convert whitespace to spaces, no escapes
 		else:
-			res=regexps.whitespace.sub(" ",res) # convert whitespace to spaces, no escapes
-		res=regexps.removeSlashes.sub(r"\1\2\4",res)
-		res=regexps.unescapeSlashes.sub(r"\\",res) # unescape slashes
+			res = regexps.whitespace.sub(" ", res)  # convert whitespace to spaces, no escapes
+		res = regexps.removeSlashes.sub(r"\1\2\4", res)
+		res = regexps.unescapeSlashes.sub(r"\\", res)  # unescape slashes
 
-		return (m.end(),res)
+		return (m.end(), res)
 	return f
 
 
-def empty(s,start): return (start,"")
+def empty(s, start):
+	return (start, "")
 
 
-def anything(s,start):
-	esc=False
-	i=start
-	for i,c in enumerate(s[start:],start):
-		if esc: esc=False
-		elif c=="\\": esc=True
-		elif c=="]": break
-	return (i,s[start:i])
+def anything(s, start):
+	esc = False
+	i = start
+	for (i, c) in enumerate(s[start:], start):
+		if esc: esc = False
+		elif c == "\\": esc = True
+		elif c == "]": break
+	return (i, s[start:i])
 
 
 # go specific
-def point(s,start):
-	m=Regexp.point.match(s,start) # !! limit to board size
-	if m is None: raise ParserError("expected a point value matching '{0}'".format(Regexp.point.pattern),s,start)
-	if m.group(0)=="": # pass, !! tt
-		return (m.end(),tuple())
-	col=m.group(0)[0]
-	row=m.group(0)[1]
-	col=ord(col)-(ord("a") if "a"<=col<="z" else ord("A")-26)
-	row=ord(row)-(ord("a") if "a"<=row<="z" else ord("A")-26)
-	return (m.end(),Point(col,row))
+def point(s, start):
+	m = Regexp.point.match(s, start)  # !! limit to board size
+	if m is None:
+		raise ParserError("expected a point value matching '{0}'".format(Regexp.point.pattern), s, start)
+	if m.group(0) == "":  # pass, !! tt
+		return (m.end(), tuple())
+	col = m.group(0)[0]
+	row = m.group(0)[1]
+	col = ord(col) - (ord("a") if "a" <= col <= "z" else ord("A")-26)
+	row = ord(row) - (ord("a") if "a" <= row <= "z" else ord("A")-26)
+	return (m.end(), Point(col, row))
 
 
-move=point
-stone=point
+move = point
+stone = point