Skip to content

Commit

Permalink
First draft for parse_all. #20
Browse files Browse the repository at this point in the history
  • Loading branch information
Dmitry Dygalo committed Sep 30, 2015
1 parent 0e241f4 commit a257368
Show file tree
Hide file tree
Showing 5 changed files with 66 additions and 14 deletions.
1 change: 1 addition & 0 deletions pyanyapi/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ def inner(key):

def attach_attribute(target, name, attr):
attr.__name__ = name
attr._attached = True
setattr(target, name, attr)


Expand Down
16 changes: 16 additions & 0 deletions pyanyapi/interfaces.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,16 @@ def perform_parsing(self):
def parse(self, query):
raise NotImplementedError

def parse_all(self):
"""
Processes all available properties and returns results as dictionary.
"""
return dict(
(key, getattr(self, key, self.empty_result))
for key, attr in self.__class__.__dict__.items()
if hasattr(attr, '_attached') and type(attr).__name__ == 'cached_property'
)


# Uses as fallback. None - can be obtained from JSON's null, any string also can be, so unique object is a best choice
EMPTY_RESULT = object()
Expand Down Expand Up @@ -82,6 +92,12 @@ def walk(self, item):
except (AttributeError, ResponseParseError):
pass

def parse_all(self):
result = super(CombinedInterface, self).parse_all()
for parser in self.parsers:
result.update(parser.parse_all(self.content))
return result


class XPathInterface(BaseInterface):
"""
Expand Down
3 changes: 3 additions & 0 deletions pyanyapi/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@ class Interface(self.interface_class):

return Interface(**init_kwargs)

def parse_all(self, content=''):
return self.parse(content).parse_all()

def get_interface_kwargs(self):
return {'content': self.content}

Expand Down
43 changes: 30 additions & 13 deletions tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,23 +39,23 @@ def empty_values_parser():
return EmptyValuesParser()


class DummyParser(CombinedParser):
parsers = (
JSONParser({'success': 'container > test'}),
RegExpParser({'test': 'href=\'(.*)\''}),
)
@pytest.fixture
def dummy_parser():

@interface_property
def combined(self):
return '123-' + self.success
class DummyParser(CombinedParser):
parsers = (
JSONParser({'success': 'container > test'}),
RegExpParser({'test': 'href=\'(.*)\''}),
)

@interface_method
def method(self, value):
return self.success + value
@interface_property
def combined(self):
return '123-' + self.success

@interface_method
def method(self, value):
return self.success + value

@pytest.fixture
def dummy_parser():
return DummyParser()


Expand All @@ -73,6 +73,23 @@ class ChildParser(ParentParser):
'child2': 'test4'
}


class SimpleParser(RegExpParser):
settings = {
'test': '\d+.\d+',
'test2': '\d+',
'test3': 'a',
}

@interface_property
def test4(self):
return self.test2 + '_4'

@interface_method
def test_5(self, value):
return 'Will not be included'


PYPY3 = hasattr(sys, 'pypy_translation_info') and sys.version_info[0] == 3
JYTHON = platform.system() == 'Java'

Expand Down
17 changes: 16 additions & 1 deletion tests/test_parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
import pytest

from ._compat import patch
from .conftest import ChildParser, lxml_is_supported, lxml_is_not_supported
from .conftest import ChildParser, SimpleParser, lxml_is_supported, lxml_is_not_supported
from pyanyapi import XMLObjectifyParser, XMLParser, JSONParser, YAMLParser, RegExpParser, AJAXParser
from pyanyapi.exceptions import ResponseParseError

Expand Down Expand Up @@ -252,3 +252,18 @@ def test_parse_memoization():
def test_regexp_settings():
assert RegExpParser({'test': '\d+.\d+'}).parse(MULTILINE_CONTENT).test == '123'
assert RegExpParser({'test': '\d+.\d+'}, flags=re.DOTALL).parse(MULTILINE_CONTENT).test == '123\n234'


def test_parse_all():
expected = {'test': '123\n234', 'test2': '123', 'test3': None, 'test4': '123_4'}
parser = SimpleParser(flags=re.DOTALL)
assert parser.parse(MULTILINE_CONTENT).parse_all() == expected
assert parser.parse_all(MULTILINE_CONTENT) == expected


def test_parse_all_combined_parser(dummy_parser):
assert dummy_parser.parse(JSON_CONTENT).parse_all() == {
'success': 'value',
'combined': '123-value',
'test': None
}

0 comments on commit a257368

Please sign in to comment.