# Buggy code
def _eval(self, segment, raw_stack, memory, **kwargs):
    """Inconsistent capitalisation of keywords.

    We use the `memory` feature here to keep track of
    what we've seen in the past.

    """
    cases_seen = memory.get("cases_seen", set())

    if segment.type == self._target_elem:
        raw = segment.raw
        uc = raw.upper()
        lc = raw.lower()
        cap = raw.capitalize()
        seen_case = None
        if uc == lc:
            # Caseless
            pass
        elif raw == uc:
            seen_case = "upper"
        elif raw == lc:
            seen_case = "lower"
        elif raw == cap:
            # NB: American spelling :(
            seen_case = "capitalize"
        else:
            seen_case = "inconsistent"

        # NOTE: We'll only add to cases_seen if we DONT
        # also raise an error, so that we can focus in.

        def make_replacement(seg, policy):
            """Make a replacement segment, based on seen capitalisation."""
            if policy == "lower":
                new_raw = seg.raw.lower()
            elif policy == "upper":
                new_raw = seg.raw.upper()
            elif policy == "capitalize":
                new_raw = seg.raw.capitalize()
            elif policy == "consistent":
                if cases_seen:
                    # Get an element from what we've already seen
                    return make_replacement(seg, list(cases_seen)[0])
                else:
                    # If we haven't seen anything yet, then let's default
                    # to upper
                    return make_replacement(seg, "upper")
            else:
                raise ValueError(
                    "Unexpected capitalisation policy: {0!r}".format(policy)
                )
            # Make a new class and return it.
            return seg.__class__(raw=new_raw, pos_marker=seg.pos_marker)

        if not seen_case:
            # Skip this if we haven't seen anything good.
            # No need to update memory
            return LintResult(memory=memory)
        elif (
            (
                self.capitalisation_policy == "consistent"
                and cases_seen
                and seen_case not in cases_seen
            )
            # Policy is either upper, lower or capitalize
            or (
                self.capitalisation_policy != "consistent"
                and seen_case != self.capitalisation_policy
            )
        ):
            return LintResult(
                anchor=segment,
                fixes=[
                    LintFix(
                        "edit",
                        segment,
                        make_replacement(segment, self.capitalisation_policy),
                    )
                ],
                memory=memory,
            )
        else:
            # Update memory and carry on
            cases_seen.add(seen_case)
            memory["cases_seen"] = cases_seen
            return LintResult(memory=memory)

    # If it's not a keyword just carry on
    return LintResult(memory=memory)


# Traceback (ValueError)
➜ sqlfluff version
0.2.4

➜ echo 'selECT * from table;' > test.sql

➜ sqlfluff fix test.sql --rules L001,L002,L003,L004,L005,L006,L007,L008,L009,L010,L011,L012,L013,L014
==== finding violations ====
Traceback (most recent call last):
File "/Users/nolan/anaconda3/bin/sqlfluff", line 10, in <module>
sys.exit(cli())
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/click/core.py", line 764, in __call__
return self.main(*args, **kwargs)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/click/core.py", line 717, in main
rv = self.invoke(ctx)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/click/core.py", line 1137, in invoke
return _process_result(sub_ctx.command.invoke(sub_ctx))
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/click/core.py", line 956, in invoke
return ctx.invoke(self.callback, **ctx.params)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/click/core.py", line 555, in invoke
return callback(*args, **kwargs)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/cli/commands.py", line 174, in fix
result = lnt.lint_paths(paths, verbosity=verbose)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/linter.py", line 605, in lint_paths
result.add(self.lint_path(path, verbosity=verbosity, fix=fix))
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/linter.py", line 592, in lint_path
fix=fix, config=config))
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/linter.py", line 536, in lint_string
lerrs, _, _, _ = crawler.crawl(parsed)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/base.py", line 192, in crawl
raw_stack=raw_stack, fix=fix, memory=memory)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/base.py", line 192, in crawl
raw_stack=raw_stack, fix=fix, memory=memory)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/base.py", line 192, in crawl
raw_stack=raw_stack, fix=fix, memory=memory)
[Previous line repeated 1 more time]
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/base.py", line 162, in crawl
raw_stack=raw_stack, memory=memory)
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/std.py", line 488, in _eval
segment, self.capitalisation_policy))
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/std.py", line 463, in make_replacement
return make_replacement(seg, list(cases_seen)[0])
File "/Users/nolan/anaconda3/lib/python3.7/site-packages/sqlfluff/rules/std.py", line 469, in make_replacement
raise ValueError("Unexpected capitalisation policy: {0!r}".format(policy))
ValueError: Unexpected capitalisation policy: 'inconsistent'

# Fixed code
def _eval(self, segment, raw_stack, memory, **kwargs):
    """Inconsistent capitalisation of keywords.

    We use the `memory` feature here to keep track of
    what we've seen in the past.

    """
    cases_seen = memory.get("cases_seen", set())

    if segment.type == self._target_elem:
        raw = segment.raw
        uc = raw.upper()
        lc = raw.lower()
        cap = raw.capitalize()
        seen_case = None
        if uc == lc:
            # Caseless
            pass
        elif raw == uc:
            seen_case = "upper"
        elif raw == lc:
            seen_case = "lower"
        elif raw == cap:
            # NB: American spelling :(
            seen_case = "capitalize"
        else:
            seen_case = "inconsistent"

        # NOTE: We'll only add to cases_seen if we DONT
        # also raise an error, so that we can focus in.

        def make_replacement(seg, policy):
            """Make a replacement segment, based on seen capitalisation."""
            if policy == "lower":
                new_raw = seg.raw.lower()
            elif policy == "upper":
                new_raw = seg.raw.upper()
            elif policy == "capitalize":
                new_raw = seg.raw.capitalize()
            elif policy == "consistent":
                # The only case we DONT allow here is "inconsistent",
                # because it doesn't actually help us.
                filtered_cases_seen = [c for c in cases_seen if c != "inconsistent"]
                if filtered_cases_seen:
                    # Get an element from what we've already seen.
                    return make_replacement(seg, list(filtered_cases_seen)[0])
                else:
                    # If we haven't seen anything yet, then let's default
                    # to upper
                    return make_replacement(seg, "upper")
            else:
                raise ValueError(
                    "Unexpected capitalisation policy: {0!r}".format(policy)
                )
            # Make a new class and return it.
            return seg.__class__(raw=new_raw, pos_marker=seg.pos_marker)

        if not seen_case:
            # Skip this if we haven't seen anything good.
            # No need to update memory
            return LintResult(memory=memory)
        elif (
            # Are we required to be consistent? (and this is inconsistent?)
            (
                self.capitalisation_policy == "consistent"
                and (
                    # Either because we've seen multiple
                    (cases_seen and seen_case not in cases_seen)
                    # Or just because this one is inconsistent internally
                    or seen_case == "inconsistent"
                )
            )
            # Are we just required to be specfic?
            # Policy is either upper, lower or capitalize
            or (
                self.capitalisation_policy != "consistent"
                and seen_case != self.capitalisation_policy
            )
        ):
            return LintResult(
                anchor=segment,
                fixes=[
                    LintFix(
                        "edit",
                        segment,
                        make_replacement(segment, self.capitalisation_policy),
                    )
                ],
                memory=memory,
            )
        else:
            # Update memory and carry on
            cases_seen.add(seen_case)
            memory["cases_seen"] = cases_seen
            return LintResult(memory=memory)

    # If it's not a keyword just carry on
    return LintResult(memory=memory)