Repository: sqlfluff/sqlfluff
Issue: Bug: Unexpected L003 fix behavior on python2

On python3, L003 handles this case as expected:
```
➜ echo '  select 1 from tbl;' | sqlfluff fix - --rules L003
select 1 from tbl;
```

But not on python2:

```
➜ echo '  select 1 from tbl;' | sqlfluff fix - --rules L003
    select 1 from tbl;

➜ python --version       
Python 2.7.16

➜ sqlfluff version  
0.2.4
```

I have noticed that python2 handles this correctly if there is only one preceding space. any idea what could be going on?

Changed files:
src/sqlfluff/rules/std.py, test/rules_std_test.py, src/sqlfluff/rules/base.py

diff --git a/src/sqlfluff/rules/base.py b/src/sqlfluff/rules/base.py
index 01f7349e..7f26956b 100644
--- a/src/sqlfluff/rules/base.py
+++ b/src/sqlfluff/rules/base.py
@@ -90,7 +90,21 @@ class LintFix(object):
         self.edit = edit
 
     def __repr__(self):
-        return "<LintFix: {0} @{1}>".format(self.edit_type, self.anchor.pos_marker)
+        if self.edit_type == 'delete':
+            detail = 'del:{0!r}'.format(self.anchor.raw)
+        elif self.edit_type in ('edit', 'create'):
+            if hasattr(self.edit, 'raw'):
+                new_detail = self.edit.raw
+            else:
+                new_detail = ''.join([s.raw for s in self.edit])
+
+            if self.edit_type == 'edit':
+                detail = 'edt:{0!r}>{1!r}'.format(self.anchor.raw, new_detail)
+            else:
+                detail = 'crt:{0!r}'.format(new_detail)
+        else:
+            detail = ''
+        return "<LintFix: {0} @{1} {2}>".format(self.edit_type, self.anchor.pos_marker, detail)
 
 
 class BaseCrawler(object):
diff --git a/src/sqlfluff/rules/std.py b/src/sqlfluff/rules/std.py
index 71f0fff9..17804ae9 100644
--- a/src/sqlfluff/rules/std.py
+++ b/src/sqlfluff/rules/std.py
@@ -1,5 +1,7 @@
 """Standard SQL Linting Rules."""
 
+import six
+
 from ..parser import RawSegment, KeywordSegment
 from .base import BaseCrawler, LintFix, LintResult, RuleSet
 
@@ -128,12 +130,27 @@ class Rule_L003(BaseCrawler):
 
         We can only trigger on whitespace which is either
         preceeded by nothing or a newline.
+
         """
+        def round3(val):
+            """Round consistently with py3 even in py2."""
+            if six.PY2:
+                r = round(val)
+                # We want ties to nearest even, not ties away from zero
+                if val % 1 == 0.5 and r % 2 != 0:
+                    if val > r:
+                        r += 1
+                    else:
+                        r -= 1
+                return r
+            else:
+                return round(val)
+
         if segment.name == 'whitespace':
             ws_len = segment.raw.count(' ')
             if ws_len % self.tab_space_size != 0:
                 if len(raw_stack) == 0 or raw_stack[-1].name == 'newline':
-                    best_len = int(round(ws_len * 1.0 / self.tab_space_size)) * self.tab_space_size
+                    best_len = int(round3(ws_len * 1.0 / self.tab_space_size)) * self.tab_space_size
                     return LintResult(
                         anchor=segment,
                         fixes=[LintFix('edit', segment, segment.edit(' ' * best_len))]
diff --git a/test/rules_std_test.py b/test/rules_std_test.py
index 146221b4..f9659a9a 100644
--- a/test/rules_std_test.py
+++ b/test/rules_std_test.py
@@ -81,6 +81,8 @@ def assert_rule_pass_in_sql(code, sql):
     # Test that we don't have the "inconsistent" bug
     ('L010', 'fail', 'SeLeCt 1', 'SELECT 1'),
     ('L010', 'fail', 'SeLeCt 1 from blah', 'SELECT 1 FROM blah'),
+    # Gihub Bug #99. Python2 Issues with fixing L003
+    ('L003', 'fail', '  select 1 from tbl;', 'select 1 from tbl;')
 ])
 def test__rules__std_string(rule, pass_fail, qry, fixed):
     """Test that a rule passes/fails on a given string.