This second major release doubles down on the ease-of-use promise of Parsita. The interface has been simplified and the amount of global mutable state needed to perform Parsita's magic has been drastically reduced. The internals have been totally rewritten to eliminate the possibility catastrophic backtracking, a rare and confusing property of some parsers.
Code that runs on 1.x will need to be modified to run on run on 2.x. The 1.8.0 release was made to ease the transition. Code written for 1.7.2 and earlier will produce deprecation warnings when run in 1.8.0. Code that has been modified to no longer produce those deprecation warnings should run without further modifications on 2.0.0.
* Replace `GeneralParsers` and `TextParsers` with `ParserContext`, which behaves like a `TextParsers` with a default `whitespace` of `None`
* The separate parser contexts were always kind of confusing and, in reality, not all that different. Both could parse text. The only advantage of `TextParsers` was its `whitespace` option. Add that to `GeneralParsers` and `TextParsers` is no longer needed and `ParserContext` is born.
* Replace the custom `parsita.Result` with `returns.result.Result`
* `Result`, `Success`, and `Failure` are now simple reexports of the classes from [`returns.result`](https://returns.readthedocs.io/en/latest/pages/result.html)
* `Result.or_die()` and `Success.value` have been replaced by `Result.unwrap()`
* `Failure.message` has been replaced by `str(Result.failure())`
* Replace the internal parsing engine with a [packrat parser](https://pdos.csail.mit.edu/~baford/packrat/icfp02/packrat-icfp02.pdf)
* Every time a parser finishes at a particular location in the input, a packrat parser caches the response. This guarantees that the time the parser takes to parse is linear in the input. It should no longer possible to write a parser that appears to hang on a small amount of input.
* This is only a breaking change for custom parser classes (i.e. those that inherit from `Parser` instead of being built from combinations of other parsers). Classes that inherit from `Parsers` need to adopt the following changes:
* `consume` is now an abstract protected method. `consume` must be implemented in concrete subclasses of `Parser`, but is invoked by `cached_consumed` only and should not be directly invoked by other parsers.
* Invoke `cached_consume` on inner parsers instead of `consume` directly
* Return `None` on failure instead of `Backtrack`
* No need to do `status.merge` anymore
* Raise custom `RecursionError` instead of using the builtin one when Parsita detects infinite recursion
* It has `parser` and `context` attributes to store useful state about the parsing at the failure
* `ParseError` now has attributes (`farthest` and `expected`) so that the state can be queried instead of lost in the string
* Remove `parsita.options.parse_method` global mutable state
* `Parser.parse` is now a normal method instead of being extracted from global mutable state at parser instantiation
* Remove `parsita.options.handle_literal` global mutable state
* `LiteralParser` now handles everything. It has a specialization for `StringReader` for performance.
* Drop support for Python 3.7