diff --git a/language-python.cabal b/language-python.cabal
--- a/language-python.cabal
+++ b/language-python.cabal
@@ -1,6 +1,6 @@
 name:                language-python
-version:             0.5.6
-cabal-version:       >= 1.6
+version:             0.5.8
+cabal-version:       >= 1.10 
 synopsis:            Parsing and pretty printing of Python code. 
 description:         language-python is a Haskell library for lexical analysis, parsing 
                      and pretty printing Python code. It supports versions 2.x and 3.x of Python. 
@@ -24,11 +24,12 @@
    location: https://github.com/bjpop/language-python
 
 Library
+   default-language: Haskell2010
    hs-source-dirs: src 
    ghc-options: -fwarn-incomplete-patterns -fwarn-unused-imports -fwarn-warnings-deprecations
    build-depends:
       base == 4.*,
-      containers == 0.5.*,
+      containers >= 0.5 && < 0.7,
       pretty == 1.1.*,
       array >= 0.4 && < 0.6,
       transformers >= 0.3 && < 0.6,
diff --git a/src/Language/Python/Common/LexerUtils.hs b/src/Language/Python/Common/LexerUtils.hs
--- a/src/Language/Python/Common/LexerUtils.hs
+++ b/src/Language/Python/Common/LexerUtils.hs
@@ -14,7 +14,6 @@
 module Language.Python.Common.LexerUtils where
 
 import Control.Monad (liftM)
-import Control.Monad.Error.Class (throwError)
 import Data.List (foldl')
 import Data.Word (Word8)
 import Language.Python.Common.Token as Token
@@ -115,6 +114,11 @@
 notEOF _user _inputBeforeToken _tokenLength (_loc, _bs, inputAfterToken) 
    = not (null inputAfterToken)
 
+delUnderscores :: String -> String
+delUnderscores []       = []
+delUnderscores ('_':xs) = delUnderscores xs
+delUnderscores (x  :xs) = x : delUnderscores xs
+
 readBinary :: String -> Integer
 readBinary 
    = toBinary . drop 2 
@@ -122,6 +126,7 @@
    toBinary = foldl' acc 0
    acc b '0' = 2 * b
    acc b '1' = 2 * b + 1
+   acc _ _ = error "Lexer ensures all digits passed to readBinary are 0 or 1."
 
 readFloat :: String -> Double
 readFloat str@('.':cs) = read ('0':readFloatRest str)
@@ -230,3 +235,4 @@
 
 readOctNoO :: String -> Integer
 readOctNoO (zero:rest) = read (zero:'O':rest)
+readOctNoO [] = error "Lexer ensures readOctNoO is never called on an empty string"
diff --git a/src/Language/Python/Common/ParseError.hs b/src/Language/Python/Common/ParseError.hs
--- a/src/Language/Python/Common/ParseError.hs
+++ b/src/Language/Python/Common/ParseError.hs
@@ -14,14 +14,9 @@
 
 import Language.Python.Common.SrcLocation (SrcLocation)
 import Language.Python.Common.Token (Token)
-import Control.Monad.Error.Class
 
 data ParseError  
    = UnexpectedToken Token           -- ^ An error from the parser. Token found where it should not be. Note: tokens contain their own source span.
    | UnexpectedChar Char SrcLocation -- ^ An error from the lexer. Character found where it should not be.
    | StrError String                 -- ^ A generic error containing a string message. No source location.
    deriving (Eq, Ord, Show)
-
-instance Error ParseError where
-   noMsg = StrError ""
-   strMsg = StrError 
diff --git a/src/Language/Python/Common/ParserMonad.hs b/src/Language/Python/Common/ParserMonad.hs
--- a/src/Language/Python/Common/ParserMonad.hs
+++ b/src/Language/Python/Common/ParserMonad.hs
@@ -43,6 +43,7 @@
    , addComment
    , getComments
    , spanError
+   , throwError
    ) where
 
 import Language.Python.Common.SrcLocation (SrcLocation (..), SrcSpan (..), Span (..))
@@ -51,7 +52,6 @@
 import Control.Applicative ((<$>))
 import Control.Monad.State.Class
 import Control.Monad.State.Strict as State
-import Control.Monad.Error as Error
 import Language.Python.Common.Pretty
 
 internalError :: String -> P a 
@@ -90,6 +90,9 @@
    }
 
 type P a = StateT ParseState (Either ParseError) a
+
+throwError :: ParseError -> P a
+throwError = lift . Left
 
 execParser :: P a -> ParseState -> Either ParseError a
 execParser = evalStateT 
diff --git a/src/Language/Python/Common/ParserUtils.hs b/src/Language/Python/Common/ParserUtils.hs
--- a/src/Language/Python/Common/ParserUtils.hs
+++ b/src/Language/Python/Common/ParserUtils.hs
@@ -15,7 +15,6 @@
 
 import Data.List (foldl')
 import Data.Maybe (isJust)
-import Control.Monad.Error.Class (throwError)
 import Language.Python.Common.AST as AST
 import Language.Python.Common.Token as Token 
 import Language.Python.Common.ParserMonad hiding (location)
@@ -98,6 +97,7 @@
 makeTupleOrExpr [e] Nothing = e
 makeTupleOrExpr es@(_:_) (Just t) = Tuple es (spanning es t) 
 makeTupleOrExpr es@(_:_) Nothing  = Tuple es (getSpan es)
+makeTupleOrExpr [] _ = error "makeTupleOrExpr should never be called with an empty list"
 
 makeAssignmentOrExpr :: ExprSpan -> Either [ExprSpan] (AssignOpSpan, ExprSpan) -> StatementSpan
 makeAssignmentOrExpr e (Left es) 
@@ -188,6 +188,7 @@
 -- parser guarantees that the first list is non-empty
 makeDecorated :: [DecoratorSpan] -> StatementSpan -> StatementSpan
 makeDecorated ds@(d:_) def = Decorated ds def (spanning d def)
+makeDecorated [] _ = error "parser guarantees that makeDecorated's first argument is non-empty"
 
 -- suite can't be empty so it is safe to take span over it
 makeFun :: Token -> IdentSpan -> [ParameterSpan] -> Maybe ExprSpan -> SuiteSpan -> StatementSpan
@@ -220,6 +221,7 @@
    countDots count (Left token:rest) = countDots (count + dots token) rest 
    dots (DotToken {}) = 1
    dots (EllipsisToken {}) = 3
+   dots _ = error "Parser ensures dots is only called on DotToken or EllipsisToken."
 
 {-
    See: http://docs.python.org/3.0/reference/expressions.html#calls
@@ -254,9 +256,11 @@
          ArgKeyword {}
             | state `elem` [1,2] -> check 2 rest
             | state `elem` [3,4] -> check 4 rest
+            | otherwise -> error "state should always be in range 1..4 here"
          ArgVarArgsPos {}
             | state `elem` [1,2] -> check 3 rest
             | state `elem` [3,4] -> spanError arg "there must not be two *arguments in an argument list"
+            | otherwise -> error "state should always be in range 1..4 here"
          ArgVarArgsKeyword {} -> check 5 rest
 
 {-
@@ -290,9 +294,11 @@
          UnPackTuple {}
             | state `elem` [1,3] -> check state rest
             | state == 2 -> check 3 rest 
+            | otherwise -> error "state should always be in range 1..3 here"
          Param {}
             | state `elem` [1,3] -> check state rest
             | state == 2 -> check 3 rest 
+            | otherwise -> error "state should always be in range 1..3 here"
          EndPositional {}
             | state == 1 -> check 2 rest
             | otherwise -> spanError param "there must not be two *parameters in a parameter list"
diff --git a/src/Language/Python/Common/PrettyAST.hs b/src/Language/Python/Common/PrettyAST.hs
--- a/src/Language/Python/Common/PrettyAST.hs
+++ b/src/Language/Python/Common/PrettyAST.hs
@@ -19,7 +19,7 @@
 
 import Language.Python.Common.Pretty
 import Language.Python.Common.AST
-import Data.Maybe (isJust, fromMaybe)
+import Data.Maybe (fromMaybe)
 
 --------------------------------------------------------------------------------
 
diff --git a/src/Language/Python/Common/PrettyParseError.hs b/src/Language/Python/Common/PrettyParseError.hs
--- a/src/Language/Python/Common/PrettyParseError.hs
+++ b/src/Language/Python/Common/PrettyParseError.hs
@@ -15,7 +15,7 @@
 import Language.Python.Common.Pretty
 import Language.Python.Common.ParseError (ParseError (..))
 import Language.Python.Common.SrcLocation 
-import Language.Python.Common.PrettyToken
+import Language.Python.Common.PrettyToken()
 
 instance Pretty ParseError where
     pretty (UnexpectedToken t) = pretty (getSpan t) <+> text "unexpected token:" <+> pretty t
diff --git a/src/Language/Python/Common/SrcLocation.hs b/src/Language/Python/Common/SrcLocation.hs
--- a/src/Language/Python/Common/SrcLocation.hs
+++ b/src/Language/Python/Common/SrcLocation.hs
@@ -104,6 +104,7 @@
 incColumn :: Int -> SrcLocation -> SrcLocation
 incColumn n loc@(Sloc { sloc_column = col })
    = loc { sloc_column = col + n }
+incColumn _ NoLocation = NoLocation
 
 -- | Increment the column of a location by one tab stop.
 incTab :: SrcLocation -> SrcLocation
@@ -111,11 +112,13 @@
    = loc { sloc_column = newCol } 
    where
    newCol = col + 8 - (col - 1) `mod` 8
+incTab NoLocation = NoLocation
 
 -- | Increment the line number (row) of a location by one.
 incLine :: Int -> SrcLocation -> SrcLocation
 incLine n loc@(Sloc { sloc_row = row }) 
    = loc { sloc_column = 1, sloc_row = row + n }
+incLine _ NoLocation = NoLocation
 
 {-
 Inspired heavily by compiler/basicTypes/SrcLoc.lhs 
diff --git a/src/Language/Python/Version2.hs b/src/Language/Python/Version2.hs
--- a/src/Language/Python/Version2.hs
+++ b/src/Language/Python/Version2.hs
@@ -13,7 +13,7 @@
 --
 -- * <http://docs.python.org/2.6/reference/index.html> for an overview of the language. 
 --
-  -- * <http://docs.python.org/2.6/reference/grammar.html> for the full grammar.
+-- * <http://docs.python.org/2.6/reference/grammar.html> for the full grammar.
 -- 
 -- * <http://docs.python.org/2.6/reference/toplevel_components.html> for a description of 
 -- the various Python top-levels, which correspond to the parsers provided here.
diff --git a/src/Language/Python/Version3/Parser/Lexer.x b/src/Language/Python/Version3/Parser/Lexer.x
--- a/src/Language/Python/Version3/Parser/Lexer.x
+++ b/src/Language/Python/Version3/Parser/Lexer.x
@@ -9,7 +9,7 @@
 -- Portability : ghc
 --
 -- Implementation of a lexer for Python version 3.x programs. Generated by
--- alex. 
+-- alex. Edited by Curran McConnell to conform to PEP515.
 -----------------------------------------------------------------------------
 
 module Language.Python.Version3.Parser.Lexer 
@@ -20,9 +20,6 @@
 import Language.Python.Common.SrcLocation
 import Language.Python.Common.LexerUtils
 import qualified Data.Map as Map
-import Control.Monad (liftM)
-import Data.List (foldl')
-import Numeric (readHex, readOct)
 }
 
 -- character sets
@@ -46,9 +43,9 @@
 $not_double_quote = [. \n] # \"
 
 -- macro definitions
-@exponent = (e | E) (\+ | \-)? $digit+ 
-@fraction = \. $digit+
-@int_part = $digit+
+@exponent = (e | E) (\+ | \-)? $digit(_?$digit+)*
+@fraction = \. $digit(_?$digit+)*
+@int_part = $digit(_?$digit+)*
 @point_float = (@int_part? @fraction) | @int_part \.
 @exponent_float = (@int_part | @point_float) @exponent
 @float_number = @point_float | @exponent_float
@@ -88,13 +85,13 @@
 \\ @eol_pattern { lineJoin } -- line join 
 
 <0> {
-   @float_number { token FloatToken readFloat }
-   $non_zero_digit $digit* { token IntegerToken read }  
+   @float_number { token FloatToken (readFloat.delUnderscores) }
+   $non_zero_digit (_?$digit)* { token IntegerToken (read.delUnderscores) }
    (@float_number | @int_part) (j | J) { token ImaginaryToken (readFloat.init) }
-   0+ { token IntegerToken read }  
-   0 (o | O) $oct_digit+ { token IntegerToken read }
-   0 (x | X) $hex_digit+ { token IntegerToken read }
-   0 (b | B) $bin_digit+ { token IntegerToken readBinary }
+   0+(_?0+)* { token IntegerToken (read.delUnderscores) }
+   0 (o | O) (_?$oct_digit+)+ { token IntegerToken (read.delUnderscores) }
+   0 (x | X) (_?$hex_digit+)+ { token IntegerToken (read.delUnderscores) }
+   0 (b | B) (_?$bin_digit+)+ { token IntegerToken (readBinary.delUnderscores) }
 }
 
 -- String literals 
