conda_recipe_manager.parser package

Submodules

conda_recipe_manager.parser.enums module

Description:

Provides enumerated types used by the parser.

class conda_recipe_manager.parser.enums.LogicOp(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: StrEnum

Logic operators used in selector syntax

AND = 'and'
NOT = 'not'
OR = 'or'
class conda_recipe_manager.parser.enums.SchemaVersion(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: IntEnum

Recipe schema_version enumeration. The Pre-CEP-13 "schema" is designated as "Version 0" and does not require a schema_version field in the recipe file.

V0 = 0
V1 = 1
class conda_recipe_manager.parser.enums.SelectorConflictMode(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: Enum

Defines how to handle the addition of a selector if one already exists.

AND = 1
OR = 2
REPLACE = 3

conda_recipe_manager.parser.exceptions module

Description:

Provides exceptions thrown by the parser.

exception conda_recipe_manager.parser.exceptions.JsonPatchValidationException(patch: JsonPatchType)[source]

Bases: Exception

Indicates that the calling code has attempted to use an illegal JSON patch payload that does not meet the schema criteria.

conda_recipe_manager.parser.recipe_parser module

Description:

Provides a class that takes text from a Jinja-formatted recipe file and parses it. This allows for easy semantic understanding and manipulation of the file.

For historical reasons, this is called the parser even though it provides editing capabilities. Initially the RecipeParser class and RecipeReader class were one massive class.

Patching these files is done using a JSON-patch like syntax. This project closely conforms to the RFC 6902 spec, but deviates in some specific ways to handle the Jinja variables and comments found in conda recipe files.

Links: - https://jsonpatch.com/ - https://datatracker.ietf.org/doc/html/rfc6902/

class conda_recipe_manager.parser.recipe_parser.RecipeParser(content: str)[source]

Bases: RecipeReader

Class that parses a recipe file string and provides editing tools for changing values in the document.

add_comment(path: str, comment: str) None[source]

Adds a comment to an existing path. If a comment exists, replaces the existing comment. If a selector exists, comment is appended after the selector component of the comment.

Parameters:
  • path -- Target path to add a comment to

  • comment -- Comment to add

Raises:
  • KeyError -- If the path provided is not found

  • ValueError -- If the comment provided is a selector, the empty string, or consists of only whitespace characters

add_selector(path: str, selector: str, mode: SelectorConflictMode = SelectorConflictMode.REPLACE) None[source]

Given a path, add a selector (include the surrounding brackets) to the line denoted by path.

Parameters:
  • path -- Path to add a selector to

  • selector -- Selector statement to add

  • mode -- (Optional) Indicates how to handle a conflict if a selector already exists at this path.

Raises:
  • KeyError -- If the path provided is not found

  • ValueError -- If the selector provided is malformed

del_variable(var: str) None[source]

Remove a variable from the project. If one is not found, no changes are made.

Parameters:

var -- Variable to delete

diff() str[source]

Returns a git-like-styled diff of the current recipe state with original state of the recipe. Useful for debugging and providing users with some feedback.

Returns:

User-friendly displayable string that represents notifications made to the recipe.

patch(patch: dict[str, dict[str, dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | list[dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | str | int | float | bool | None]) bool[source]

Given a JSON-patch object, perform a patch operation.

Modifications from RFC 6902
  • We're using a Jinja-formatted YAML file, not JSON

  • To modify comments, specify the path AND comment

Parameters:

patch -- JSON-patch payload to operate with.

Raises:

JsonPatchValidationException -- If the JSON-patch payload does not conform to our schema/spec.

Returns:

If the calling code attempts to perform the test operation, this indicates the return value of the test request. In other words, if value matches the target variable, return True. False otherwise. For all other operations, this indicates if the operation was successful.

remove_selector(path: str) str | None[source]

Given a path, remove a selector to the line denoted by path. - If a selector does not exist, nothing happens. - If a comment exists after the selector, keep it, discard the selector.

Parameters:

path -- Path to add a selector to

Raises:

KeyError -- If the path provided is not found

Returns:

If found, the selector removed (includes surrounding brackets). Otherwise, returns None

search_and_patch(regex: str | Pattern[str], patch: dict[str, dict[str, dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | list[dict[str, JsonType] | list[JsonType] | str | int | float | bool | None] | str | int | float | bool | None], include_comment: bool = False) bool[source]

Given a regex string and a JSON patch, apply the patch to any values that match the search expression.

Parameters:
  • regex -- Regular expression to match with

  • patch -- JSON patch to perform. NOTE: The path field will be replaced with the path(s) found, so it does not need to be provided.

  • include_comment -- (Optional) If set to True, this function will execute the regular expression on values WITH their comments provided. For example: 42 # This is a comment

Returns:

Returns a list of paths where the matched value was found.

set_variable(var: str, value: dict[str, JsonType] | list[JsonType] | str | int | float | bool | None) None[source]

Adds or changes an existing Jinja variable.

Parameters:
  • var -- Variable to modify

  • value -- Value to set

conda_recipe_manager.parser.recipe_parser_convert module

Description:

Provides a subclass of RecipeParser that performs the conversion of a v0 recipe to the new v1 recipe format. This tooling was originally part of the base class, but was broken-out for easier/cleaner code maintenance.

class conda_recipe_manager.parser.recipe_parser_convert.RecipeParserConvert(content: str)[source]

Bases: RecipeParser

Extension of the base RecipeParser class that enables upgrading recipes from the old to V1 format. This was originally part of the RecipeParser class but was broken-out for easier maintenance.

static pre_process_recipe_text(content: str) str[source]

Takes the content of a recipe file and performs manipulations prior to the parsing stage. This should be used sparingly for solving conversion issues.

Ideally the pre-processor phase is only used when:
  • There is no other feasible way to solve a conversion issue.

  • There is a proof-of-concept fix that would be easier to develop as a pre-processor step that could be refactored into the parser later.

  • The number of recipes afflicted by an issue does not justify the engineering effort required to handle the issue in the parsing phase.

Parameters:

content -- Recipe file contents to pre-process

Returns:

Pre-processed recipe file contents

render_to_v1_recipe_format() tuple[str, MessageTable, str][source]

Takes the current recipe representation and renders it to the V1 format WITHOUT modifying the current recipe state.

This "new" format is defined in the following CEPs:
Returns:

Returns a tuple containing: - The converted recipe, as a string - A MessageTbl instance that contains error logging - Converted recipe file debug string. USE FOR DEBUGGING PURPOSES ONLY!

conda_recipe_manager.parser.types module

Description:

Provides public types, type aliases, constants, and small classes used by the parser.

class conda_recipe_manager.parser.types.MultilineVariant(value, names=None, *, module=None, qualname=None, type=None, start=1, boundary=None)[source]

Bases: StrEnum

Captures which "multiline" descriptor was used on a Node, if one was used at all.

See this guide for details on the YAML spec:

https://stackoverflow.com/questions/3790454/how-do-i-break-a-string-in-yaml-over-multiple-lines/21699210

CARROT = '>'
CARROT_MINUS = '>-'
CARROT_PLUS = '>+'
NONE = ''
PIPE = '|'
PIPE_MINUS = '|-'
PIPE_PLUS = '|+'

Module contents