-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #264 from demitryfly/some-refactorings-1
refactor utils, add tests, move exceptions into separate module
- Loading branch information
Showing
10 changed files
with
177 additions
and
80 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
__all__ = [ | ||
"SimpleDDLParserException", | ||
] | ||
|
||
|
||
class SimpleDDLParserException(Exception): | ||
""" Base exception in simple ddl parser library """ | ||
pass | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,61 +1,83 @@ | ||
import re | ||
from typing import List | ||
from typing import List, Tuple, Optional, Union, Any | ||
|
||
# Backward compatibility import | ||
from simple_ddl_parser.exception import SimpleDDLParserException | ||
|
||
def remove_par(p_list: List[str]) -> List[str]: | ||
remove_list = ["(", ")"] | ||
for symbol in remove_list: | ||
while symbol in p_list: | ||
p_list.remove(symbol) | ||
__all__ = [ | ||
"remove_par", | ||
"check_spec", | ||
"find_first_unpair_closed_par", | ||
"normalize_name", | ||
"get_table_id", | ||
"SimpleDDLParserException" | ||
] | ||
|
||
_parentheses = ('(', ')') | ||
|
||
|
||
def remove_par(p_list: List[Union[str, Any]]) -> List[Union[str, Any]]: | ||
""" | ||
Remove the parentheses from the given list | ||
Warn: p_list may contain unhashable types, such as 'dict'. | ||
""" | ||
j = 0 | ||
for i in range(len(p_list)): | ||
if p_list[i] not in _parentheses: | ||
p_list[j] = p_list[i] | ||
j += 1 | ||
while j < len(p_list): | ||
p_list.pop() | ||
return p_list | ||
|
||
|
||
spec_mapper = { | ||
_spec_mapper = { | ||
"'pars_m_t'": "'\t'", | ||
"'pars_m_n'": "'\n'", | ||
"'pars_m_dq'": '"', | ||
"pars_m_single": "'", | ||
} | ||
|
||
|
||
def check_spec(value: str) -> str: | ||
replace_value = spec_mapper.get(value) | ||
if not replace_value: | ||
for item in spec_mapper: | ||
if item in value: | ||
replace_value = value.replace(item, spec_mapper[item]) | ||
break | ||
else: | ||
replace_value = value | ||
return replace_value | ||
|
||
|
||
def find_first_unpair_closed_par(str_: str) -> int: | ||
stack = [] | ||
n = -1 | ||
for i in str_: | ||
n += 1 | ||
if i == ")": | ||
if not stack: | ||
return n | ||
else: | ||
stack.pop(-1) | ||
elif i == "(": | ||
stack.append(i) | ||
def check_spec(string: str) -> str: | ||
""" | ||
Replace escape tokens to their representation | ||
""" | ||
if string in _spec_mapper: | ||
return _spec_mapper[string] | ||
for replace_from, replace_to in _spec_mapper.items(): | ||
if replace_from in string: | ||
return string.replace(replace_from, replace_to) | ||
return string | ||
|
||
|
||
def find_first_unpair_closed_par(str_: str) -> Optional[int]: | ||
""" | ||
Returns index of first unpair close parentheses. | ||
Or returns None, if there is no one. | ||
""" | ||
count_open = 0 | ||
for i, char in enumerate(str_): | ||
if char == '(': | ||
count_open += 1 | ||
if char == ')': | ||
count_open -= 1 | ||
if count_open < 0: | ||
return i | ||
return None | ||
|
||
|
||
def normalize_name(name: str) -> str: | ||
# clean up [] and " symbols from names | ||
""" | ||
Clean up [] and " characters from the given name | ||
""" | ||
clean_up_re = r'[\[\]"]' | ||
return re.sub(clean_up_re, "", name).lower() | ||
|
||
|
||
def get_table_id(schema_name: str, table_name: str): | ||
def get_table_id(schema_name: str, table_name: str) -> Tuple[str, str]: | ||
table_name = normalize_name(table_name) | ||
if schema_name: | ||
schema_name = normalize_name(schema_name) | ||
return (table_name, schema_name) | ||
|
||
|
||
class SimpleDDLParserException(Exception): | ||
pass |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import pytest | ||
|
||
from simple_ddl_parser import utils | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"expression, expected_result", | ||
[ | ||
([], []), | ||
(["("], []), | ||
([")"], []), | ||
(["(", ")"], []), | ||
([")", "("], []), | ||
(["(", "A"], ["A"]), | ||
(["A", ")"], ["A"]), | ||
(["(", "A", ")"], ["A"]), | ||
(["A", ")", ")"], ["A"]), | ||
(["(", "(", "A"], ["A"]), | ||
(["A", "B", "C"], ["A", "B", "C"]), | ||
(["A", "(", "(", "B", "C", "("], ["A", "B", "C"]), | ||
(["A", ")", "B", ")", "(", "C"], ["A", "B", "C"]), | ||
(["(", "A", ")", "B", "C", ")"], ["A", "B", "C"]), | ||
([dict()], [dict()]), # Edge case (unhashable types) | ||
] | ||
) | ||
def test_remove_par(expression, expected_result): | ||
assert utils.remove_par(expression) == expected_result | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"expression, expected_result", | ||
[ | ||
("", ""), | ||
("simple", "simple"), | ||
("'pars_m_t'", "'\t'"), | ||
("'pars_m_n'", "'\n'"), | ||
("'pars_m_dq'", '"'), | ||
("pars_m_single", "'"), | ||
("STRING_'pars_m_t'STRING", "STRING_'\t'STRING"), | ||
("STRING_'pars_m_n'STRING", "STRING_'\n'STRING"), | ||
("STRING_'pars_m_dq'STRING", "STRING_\"STRING"), | ||
("STRING_pars_m_singleSTRING", "STRING_'STRING"), | ||
("pars_m_single pars_m_single", "' '"), | ||
("'pars_m_t''pars_m_n'", "'\t''pars_m_n'"), # determined by dict element order | ||
] | ||
) | ||
def test_check_spec(expression, expected_result): | ||
assert utils.check_spec(expression) == expected_result | ||
|
||
|
||
@pytest.mark.parametrize( | ||
"expression, expected_result", | ||
[ | ||
(")", 0), | ||
(")()", 0), | ||
("())", 2), | ||
("()())", 4), | ||
("", None), | ||
("text", None), | ||
("()", None), | ||
("(balanced) (brackets)", None), | ||
("(not)) (balanced) (brackets", 5) | ||
] | ||
) | ||
def test_find_first_unpair_closed_par(expression, expected_result): | ||
assert utils.find_first_unpair_closed_par(expression) == expected_result |