This repository has been archived by the owner on Jan 14, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
#59: Add rkd.api.parsing.SyntaxParsing interface
- Loading branch information
1 parent
b5668df
commit 6bc8a8d
Showing
7 changed files
with
133 additions
and
83 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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
import importlib | ||
from types import FunctionType | ||
from typing import List | ||
from ..exception import ParsingException | ||
from .syntax import TaskDeclaration | ||
|
||
|
||
class SyntaxParsing(object): | ||
@staticmethod | ||
def parse_imports_by_list_of_classes(classes_or_modules: List[str]) -> List[TaskDeclaration]: | ||
""" | ||
Parses a List[str] of imports, like in YAML syntax. | ||
Produces a List[TaskDeclaration] with imported list of tasks. | ||
Could be used to import & validate RKD tasks. | ||
Examples: | ||
- rkd.standardlib | ||
- rkd.standardlib.jinja.FileRendererTask | ||
:raises ParsingException | ||
:return: | ||
""" | ||
|
||
parsed: List[TaskDeclaration] = [] | ||
|
||
for import_str in classes_or_modules: | ||
parts = import_str.split('.') | ||
class_name = parts[-1] | ||
import_path = '.'.join(parts[:-1]) | ||
|
||
# importing just a full module name eg. "rkd_python" | ||
if len(parts) == 1: | ||
import_path = import_str | ||
class_name = 'imports' | ||
# Test if it's not a class name | ||
# In this case we treat is as a module and import an importing method imports() | ||
elif class_name.lower() == class_name: | ||
import_path += '.' + class_name | ||
class_name = 'imports' | ||
|
||
try: | ||
module = importlib.import_module(import_path) | ||
except ImportError as e: | ||
raise ParsingException.from_import_error(import_str, class_name, e) | ||
|
||
if class_name not in dir(module): | ||
raise ParsingException.from_class_not_found_in_module_error(import_str, class_name, import_path) | ||
|
||
if isinstance(module.__getattribute__(class_name), FunctionType): | ||
parsed += module.__getattribute__(class_name)() | ||
else: | ||
parsed.append(TaskDeclaration(module.__getattribute__(class_name)())) | ||
|
||
return parsed |
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 |
---|---|---|
@@ -0,0 +1,46 @@ | ||
#!/usr/bin/env python3 | ||
|
||
from rkd.api.testing import BasicTestingCase | ||
from rkd.api.parsing import SyntaxParsing | ||
from rkd.exception import DeclarationException, ParsingException | ||
|
||
|
||
class TestApiParsing(BasicTestingCase): | ||
def test_parse_imports_successful_case_single_task(self): | ||
imported = SyntaxParsing.parse_imports_by_list_of_classes(['rkd.standardlib.jinja.RenderDirectoryTask']) | ||
|
||
self.assertEqual(':j2:directory-to-directory', imported[0].to_full_name()) | ||
|
||
def test_parse_imports_successful_case_module(self): | ||
imported = SyntaxParsing.parse_imports_by_list_of_classes(['rkd.standardlib.jinja']) | ||
|
||
names_of_imported_tasks = [] | ||
|
||
for task in imported: | ||
names_of_imported_tasks.append(task.to_full_name()) | ||
|
||
self.assertIn(':j2:render', names_of_imported_tasks) | ||
self.assertIn(':j2:directory-to-directory', names_of_imported_tasks) | ||
|
||
def test_parse_imports_wrong_class_type_but_existing(self): | ||
def test(): | ||
SyntaxParsing.parse_imports_by_list_of_classes(['rkd.exception.ContextException']) | ||
|
||
self.assertRaises(DeclarationException, test) | ||
|
||
def test_parse_imports_cannot_import_non_existing_class(self): | ||
def test(): | ||
SyntaxParsing.parse_imports_by_list_of_classes(['rkd.standardlib.python.WRONG_NAME']) | ||
|
||
self.assertRaises(ParsingException, test) | ||
|
||
def test_parse_imports_importing_whole_module_without_submodules(self): | ||
imported = SyntaxParsing.parse_imports_by_list_of_classes(['rkd_python']) | ||
|
||
names_of_imported_tasks = [] | ||
|
||
for task in imported: | ||
names_of_imported_tasks.append(task.to_full_name()) | ||
|
||
self.assertIn(':py:build', names_of_imported_tasks) | ||
self.assertIn(':py:publish', names_of_imported_tasks) |
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