curly.utils

A various utilities which are used by Curly.

curly.utils.get_item_or_attr(varname, context)[source]

Resolve literal varname in context for resolve_variable().

Supports resolving of items and attributes. Also, tries indexes if possible.

Parameters:
  • varname (str) – Expression to resolve
  • context (dict) – A dictionary with variables to resolve.
Returns:

Resolved value

Raises:

curly.exceptions.CurlyEvaluateNoKeyError: if it is not possible to resolve varname within a context.

curly.utils.make_expression(text)[source]

Make template expression from the tag in the pattern.

Anatomy of the tag is rather simple: {% if something | went | through "named pipe" %} is a valid tag. if here is the function name you are going to apply. And this long line something | went | through "named pipe" is called expression. Yes, basic reference implementation considers whole expression as a name in the context, but in more advanced implementations, it is a DSL which is used for calculation of function arguments from the expression.

This function uses shell lexing to split expression above into the list of words like ["something", "|", "went", "through", "named pipe"].

Parameters:text (str or None) – A text to make expression from
Returns:The list of parsed expressions
Return type:list[str]
curly.utils.make_regexp(pattern)[source]

Make regular expression from the given patterns.

This is just a trivial wrapper for re.compile() which sets a list of default flags.

Parameters:pattern (str) – A pattern to compile into regular expression.
Returns:Compiled regular expression
curly.utils.resolve_variable(varname, context)[source]

Resolve value named as varname from the context.

In most trivial case, implementation of the method is like that:

def resolve_variable(varname, context):
    return context[varname]

but it works only for the most trivial cases. Even such simple template language as Curly is is required to support dot notation. So:

>>> context = {
...     "first_name": "Sergey",
...     "last_name": "Arkhipov",
...     "roles": {
...         "admin": [
...             "view_user",
...             "update_user",
...             "delete_user"
...         ]
...     }
... }
>>> resolve_variable("roles.admin.1", context)
'update_user'

So it is possible to resolve nested structures and also - arrays. But sometimes you may have ambiguous situations. The rule of this function is to try to resolve literally before going deep into the nested structure.

>>> context = {
...     "first_name": "Sergey",
...     "last_name": "Arkhipov",
...     "roles": {
...         "admin": [
...             "view_user",
...             "update_user",
...             "delete_user"
...         ]
...     },
...     "roles.admin.1": "haha!"
... }
>>> resolve_variable("roles.admin.1", context)
'haha!'

Also, dot notation supports not only items, but attributes also.

Parameters:
  • varname (str) – Expression to resolve
  • context (dict) – A dictionary with variables to resolve.
Returns:

Resolved value

Raises:

curly.exceptions.CurlyEvaluateNoKeyError: if it is not possible to resolve varname within a context.