Skip to content

Commit

Permalink
Extract superclass for legacy parser
Browse files Browse the repository at this point in the history
  • Loading branch information
illicitonion committed Dec 28, 2018
1 parent f80faf0 commit ebe652f
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 20 deletions.
48 changes: 31 additions & 17 deletions src/python/pants/engine/legacy/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,30 +25,18 @@
logger = logging.getLogger(__name__)


class LegacyPythonCallbacksParser(Parser):
"""A parser that parses the given python code into a list of top-level objects.
Only Serializable objects with `name`s will be collected and returned. These objects will be
addressable via their name in the parsed namespace.
This parser attempts to be compatible with existing legacy BUILD files and concepts including
macros and target factories.
"""

def __init__(self, symbol_table, aliases, build_file_imports_behavior):
class AbstractLegacyPythonCallbacksParser(Parser):
def __init__(self, symbol_table, aliases):
"""
:param symbol_table: A SymbolTable for this parser, which will be overlaid with the given
additional aliases.
:type symbol_table: :class:`pants.engine.parser.SymbolTable`
:param aliases: Additional BuildFileAliases to register.
:type aliases: :class:`pants.build_graph.build_file_aliases.BuildFileAliases`
:param build_file_imports_behavior: How to behave if a BUILD file being parsed tries to use
import statements. Valid values: "allow", "warn", "error".
:type build_file_imports_behavior: string
"""
super(LegacyPythonCallbacksParser, self).__init__()
super(AbstractLegacyPythonCallbacksParser, self).__init__()
self._symbols, self._parse_context = self._generate_symbols(symbol_table, aliases)
self._build_file_imports_behavior = build_file_imports_behavior


@staticmethod
def _generate_symbols(symbol_table, aliases):
Expand Down Expand Up @@ -127,7 +115,33 @@ def __call__(self, *args, **kwargs):

return symbols, parse_context

def parse(self, filepath, filecontent):

class LegacyPythonCallbacksParser(AbstractLegacyPythonCallbacksParser):
"""A parser that parses the given python code into a list of top-level objects.
Only Serializable objects with `name`s will be collected and returned. These objects will be
addressable via their name in the parsed namespace.
This parser attempts to be compatible with existing legacy BUILD files and concepts including
macros and target factories.
"""

def __init__(self, symbol_table, aliases, build_file_imports_behavior):
"""
:param symbol_table: A SymbolTable for this parser, which will be overlaid with the given
additional aliases.
:type symbol_table: :class:`pants.engine.parser.SymbolTable`
:param aliases: Additional BuildFileAliases to register.
:type aliases: :class:`pants.build_graph.build_file_aliases.BuildFileAliases`
:param build_file_imports_behavior: How to behave if a BUILD file being parsed tries to use
import statements. Valid values: "allow", "warn", "error".
:type build_file_imports_behavior: string
"""
super(LegacyPythonCallbacksParser, self).__init__(symbol_table, aliases, build_file_imports_behavior)
self._build_file_imports_behavior = build_file_imports_behavior


def parse(self, filepath, filecontent, **kwargs):
python = filecontent.decode('utf-8') if PY3 else filecontent

# Mutate the parse context for the new path, then exec, and copy the resulting objects.
Expand Down
4 changes: 2 additions & 2 deletions src/python/pants/engine/mapper.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ class AddressMap(datatype(['path', 'objects_by_name'])):
"""

@classmethod
def parse(cls, filepath, filecontent, parser):
def parse(cls, filepath, filecontent, parser, **kwargs):
"""Parses a source for addressable Serializable objects.
No matter the parser used, the parsed and mapped addressable objects are all 'thin'; ie: any
Expand All @@ -50,7 +50,7 @@ def parse(cls, filepath, filecontent, parser):
:type parser: A :class:`pants.engine.parser.Parser`.
"""
try:
objects = parser.parse(filepath, filecontent)
objects = parser.parse(filepath, filecontent, **kwargs)
except Exception as e:
raise MappingError('Failed to parse {}:\n{}'.format(filepath, e))
objects_by_name = {}
Expand Down
2 changes: 1 addition & 1 deletion src/python/pants/engine/parser.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ def table(self):
class Parser(AbstractClass):

@abstractmethod
def parse(self, filepath, filecontent):
def parse(self, filepath, filecontent, **kwargs):
"""
:param string filepath: The name of the file being parsed. The parser should not assume
that the path is accessible, and should consume the filecontent.
Expand Down

0 comments on commit ebe652f

Please sign in to comment.