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
conda_recipe_manager.parser.exceptions module
- Description:
Provides exceptions thrown by the parser.
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.
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:
- CARROT = '>'
- CARROT_MINUS = '>-'
- CARROT_PLUS = '>+'
- NONE = ''
- PIPE = '|'
- PIPE_MINUS = '|-'
- PIPE_PLUS = '|+'