Skip to content

Version 2.0.0

Choose a tag to compare

@jg-rp jg-rp released this 16 Mar 08:38
· 69 commits to main since this release

This is a major release with several breaking changes. As well as API changes listed below, we:

  • Drop support for Python version 3.7 and 3.8.
  • Promote rendering behavior from liquid.future.Environment to be the default, so as to improve Shopify/liquid compatibility by default.
  • Fix variable/identifier/path parsing described in issue #39.
  • Improve Liquid syntax error messages and exposes source index, line numbers and column numbers through methods on Liquid exceptions. See #53.
  • Change comment tag parsing to better match Shopify/Liquid. See #133.
  • Remove BoundTemplate.analyze_with_context(). Shout if you need contextual analysis and we'll restore this feature.
  • Remove the cache_size argument to liquid.Environment and liquid.Template. Template caching is now handled by template loaders.
  • Remove the expression_cache_size argument to liquid.Environment and liquid.Template. Environment-level expression caching is no longer available as it does not play nicely with detailed error messages. If you need to cache parsing of Liquid expressions, it is now recommended to implement a cache per tag, where it makes sense to do so for your use case.
  • Make markupsafe>=3 a dependency. Previously markupsafe was an optional dependency. Version 3 of markupsafe brings some subtle changes to the replace, replace_first and replace_last filters when they receive a "safe" string wrapped in Markup().
  • Add new filters reject, has, find and find_index.
  • Add the new doc tag.

API changes

Also see the migration guide.

Miscellaneous

  • Added liquid.parse(source), liquid.render(source, **data) and liquid.render_async(source, **data). These are shorthand functions that use liquid.DEFAULT_ENVIRONMENT.
  • Renamed liquid.Environment.parse to liquid.Environment._parse, which returns a list of nodes, not a template.
  • Aliased liquid.Environment.from_string as liquid.Environment.parse.
  • Added liquid.Environment.render(source, **data) and liquid.Environment.render_async(source, **data). These are convenience methods equivalent to liquid.Environment.from_string(source).render(**data).
  • Renamed liquid.Context to liquid.RenderContext.
  • Change the liquid.RenderContext constructor (previously liquid.Context) to require an instance of BoundTemplate as its only positional argument instead of an instance of Environment. All other arguments are now keyword only.
  • Renamed liquid.exceptions.Error to liquid.exceptions.LiquidError.
  • Renamed liquid.exceptions.TemplateNotFound to liquid.exceptions.TemplateNotFoundError.
  • Renamed liquid.exceptions.NoSuchFilterFunc to liquid.exceptions.UnknownFilterError.

Template loaders

  • Changed BaseLoader.get_source and BaseLoader.get_source_async to accept and optional context keyword argument and arbitrary keyword arguments as "load context".
  • Removed BaseLoader.get_source_with_args and BaseLoader.get_source_with_context, and their async equivalents. BaseLoader.get_source now accepts optional context and load context arguments.
  • Changed TemplateSource (a named tuple) to be (text, name, uptodate, matter). It used to be (source, filename, uptodate, matter)

Builtin expressions

  • Removed liquid.expression.*. Now built-in expressions live in liquid.builtin.expressions.
  • Renamed Identifier to Path.
  • Removed IdentifierPathElement. Path segments are now list[str | int | Path]].
  • Removed constant versions of True, False, Nil, Empty and Blank. Each of these primitive expressions now require a token, so they can't be constant.

Tag expression parsing

  • Changed liquid.token.Token to be a named tuple of (kind, value, index, source). It used to be (linenum, type, value).
  • Removed legacy expression parsing functions. If you're importing anything from liquid.parse for your custom tags, you'll need to use functions/methods from liquid.builtin.expressions instead.
  • Removed liquid.parse.expect() and liquid.parse.expect_peek() in favour of TokenStream.expect() and TokenStream.expect_peek().
  • Removed liquid.expressions.TokenStream. Now there's only one TokenStream class, liquid.stream.TokenStream, reexported as liquid.TokenStream.
  • All tokens are now named tuples. Previously functions in liquid.expressions would generate and use plain tuples internally.
  • Added the TOKEN_RANGE_LITERAL token kind. The opening parenthesis of a range expression will use this kind to differentiate logical grouping parentheses from range expressions.
  • Split tokens with kind TOKEN_OUTPUT in to two tokens, TOKEN_OUTPUT and TOKEN_EXPRESSION. Previously the value associated with TOKEN_OUTPUT would be the expression, now the expression follows in the next token, just like TOKEN_TAG.

Here's a summary mapping from old expression parsing functions to the recommended new parsing functions/methods.

Old New
tokenize_common_expression(str, linenum) liquid.builtin.expressions.tokenize(source, parent_token)
*.tokenize(source, linenum) liquid.builtin.expressions.tokenize(source, parent_token)
parse_common_expression(stream) liquid.builtin.expressions.parse_primitive(env, stream)
parse_keyword_arguments(expr, linenum) liquid.builtin.expressions.KeywordArgument.parse(env, stream)
parse_identifier(stream) liquid.builtin.expressions.Path.parse(env, stream)
parse_unchained_identifier(stream) liquid.builtin.expressions.parse_identifier(env, stream)
parse_string_or_identifier liquid.builtin.expressions.parse_string_or_path(env, stream)
parse_unchained_identifier liquid.builtin.expressions.parse_name(env, stream)
parse_boolean liquid.builtin.expressions.parse_primitive(env, stream)
parse_nil liquid.builtin.expressions.parse_primitive(env, stream)
parse_empty liquid.builtin.expressions.parse_primitive(env, stream)
parse_blank liquid.builtin.expressions.parse_primitive(env, stream)
parse_string_literal liquid.builtin.expressions.parse_primitive(env, stream)
parse_integer_literal liquid.builtin.expressions.parse_primitive(env, stream)
parse_float_literal liquid.builtin.expressions.parse_primitive(env, stream)
Environment.parse_boolean_expression liquid.builtin.expressions.BooleanExpression.parse(env, stream)
Environment.parse_filtered_expression liquid.builtin.expressions.FilteredExpression.parse(env, stream)
Environment.parse_loop_expression liquid.builtin.expressions.LoopExpression.parse(env, stream)