Skip to content

Commit

Permalink
Adds missing __init__.py files [FC-0030] (#90)
Browse files Browse the repository at this point in the history
chore: adds missing __init__.py files and fixes resulting pylint issues
* fixes a number of translation-of-non-string
* fixes coverage for files in tests/
* fixes PytestCollectionWarnings
  • Loading branch information
pomegranited authored Oct 9, 2023
1 parent 909e3f8 commit 0934450
Show file tree
Hide file tree
Showing 17 changed files with 172 additions and 101 deletions.
Empty file.
8 changes: 4 additions & 4 deletions openedx_tagging/core/tagging/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from django.db import transaction
from django.db.models import F, QuerySet
from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext as _

from .models import ObjectTag, Tag, Taxonomy

Expand Down Expand Up @@ -196,11 +196,11 @@ def _check_new_tag_count(new_tag_count: int) -> None:

if current_count + new_tag_count > 100:
raise ValueError(
_(f"Cannot add more than 100 tags to ({object_id}).")
_("Cannot add more than 100 tags to ({object_id}).").format(object_id=object_id)
)

if not isinstance(tags, list):
raise ValueError(_(f"Tags must be a list, not {type(tags).__name__}."))
raise ValueError(_("Tags must be a list, not {type}.").format(type=type(tags).__name__))

ObjectTagClass = object_tag_class
taxonomy = taxonomy.cast() # Make sure we're using the right subclass. This is a no-op if we are already.
Expand All @@ -209,7 +209,7 @@ def _check_new_tag_count(new_tag_count: int) -> None:
_check_new_tag_count(len(tags))

if not taxonomy.allow_multiple and len(tags) > 1:
raise ValueError(_(f"Taxonomy ({taxonomy.name}) only allows one tag per object."))
raise ValueError(_("Taxonomy ({name}) only allows one tag per object.").format(name=taxonomy.name))

current_tags = list(
ObjectTagClass.objects.filter(taxonomy=taxonomy, object_id=object_id)
Expand Down
3 changes: 3 additions & 0 deletions openedx_tagging/core/tagging/import_export/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,4 @@
"""
Externally-facing import/export classes.
"""
from .parsers import ParserFormat
38 changes: 17 additions & 21 deletions openedx_tagging/core/tagging/import_export/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ def __init__(self, taxonomy: Taxonomy, tag, index: int):
self.index = index

def __repr__(self) -> str:
return str(_(f"Action {self.name} (index={self.index},id={self.tag.id})"))
return str(_("Action {name} (index={index},id={id})").format(name=self.name, index=self.index, id=self.tag.id))

def __str__(self) -> str:
return self.__repr__()
Expand Down Expand Up @@ -104,11 +104,10 @@ def _validate_parent(self, indexed_actions) -> ImportActionError | None:
):
return ImportActionError(
action=self,
tag_id=self.tag.id,
message=_(
f"Unknown parent tag ({self.tag.parent_id}). "
"Unknown parent tag ({parent_id}). "
"You need to add parent before the child in your file."
),
).format(parent_id=self.tag.parent_id),
)
return None

Expand All @@ -122,10 +121,9 @@ def _validate_value(self, indexed_actions) -> ImportActionError | None:
taxonomy_tag = self.taxonomy.tag_set.get(value=self.tag.value)
return ImportActionError(
action=self,
tag_id=self.tag.id,
message=_(
f"Duplicated tag value with tag in database (external_id={taxonomy_tag.external_id})."
),
"Duplicated tag value with tag in database (external_id={external_id})."
).format(external_id=taxonomy_tag.external_id)
)
except Tag.DoesNotExist:
# Validates value duplication on create actions
Expand All @@ -148,7 +146,6 @@ def _validate_value(self, indexed_actions) -> ImportActionError | None:
if action:
return ImportActionConflict(
action=self,
tag_id=self.tag.id,
conflict_action_index=action.index,
message=_("Duplicated tag value."),
)
Expand All @@ -175,9 +172,9 @@ def __str__(self) -> str:
return str(
_(
"Create a new tag with values "
f"(external_id={self.tag.id}, value={self.tag.value}, "
f"parent_id={self.tag.parent_id})."
)
"(external_id={external_id}, value={value}, "
"parent_id={parent_id})."
).format(external_id=self.tag.id, value=self.tag.value, parent_id=self.tag.parent_id)
)

@classmethod
Expand All @@ -199,7 +196,6 @@ def _validate_id(self, indexed_actions) -> ImportActionError | None:
if action:
return ImportActionConflict(
action=self,
tag_id=self.tag.id,
conflict_action_index=action.index,
message=_("Duplicated external_id tag."),
)
Expand Down Expand Up @@ -263,13 +259,13 @@ def __str__(self) -> str:
if not taxonomy_tag.parent:
from_str = _("from empty parent")
else:
from_str = _(f"from parent (external_id={taxonomy_tag.parent.external_id})")
from_str = _("from parent (external_id={external_id})").format(external_id=taxonomy_tag.parent.external_id)

return str(
_(
f"Update the parent of tag (external_id={taxonomy_tag.external_id}) "
f"{from_str} to parent (external_id={self.tag.parent_id})."
)
"Update the parent of tag (external_id={external_id}) "
"{from_str} to parent (external_id={parent_id})."
).format(external_id=taxonomy_tag.external_id, from_str=from_str, parent_id=self.tag.parent_id)
)

@classmethod
Expand Down Expand Up @@ -329,9 +325,9 @@ def __str__(self) -> str:
taxonomy_tag = self._get_tag()
return str(
_(
f"Rename tag value of tag (external_id={taxonomy_tag.external_id}) "
f"from '{taxonomy_tag.value}' to '{self.tag.value}'"
)
"Rename tag value of tag (external_id={external_id}) "
"from '{from_value}' to '{to_value}'"
).format(external_id=taxonomy_tag.external_id, from_value=taxonomy_tag.value, to_value=self.tag.value)
)

@classmethod
Expand Down Expand Up @@ -378,7 +374,7 @@ class DeleteTag(ImportAction):

def __str__(self) -> str:
taxonomy_tag = self._get_tag()
return str(_(f"Delete tag (external_id={taxonomy_tag.external_id})"))
return str(_("Delete tag (external_id={external_id})").format(external_id=taxonomy_tag.external_id))

name = "delete"

Expand Down Expand Up @@ -415,7 +411,7 @@ class WithoutChanges(ImportAction):
name = "without_changes"

def __str__(self) -> str:
return str(_(f"No changes needed for tag (external_id={self.tag.id})"))
return str(_("No changes needed for tag (external_id={external_id})").format(external_id=self.tag.id))

@classmethod
def applies_for(cls, taxonomy: Taxonomy, tag) -> bool:
Expand Down
15 changes: 9 additions & 6 deletions openedx_tagging/core/tagging/import_export/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,9 +46,10 @@

from io import BytesIO

from django.utils.translation import gettext_lazy as _
from django.utils.translation import gettext as _

from ..models import TagImportTask, TagImportTaskState, Taxonomy
from .exceptions import TagImportError
from .import_plan import TagImportPlan, TagImportTask
from .parsers import ParserFormat, get_parser

Expand Down Expand Up @@ -115,7 +116,7 @@ def import_tags(
tag_import_plan.execute(task)
task.end_success()
return True
except Exception as exception:
except (TagImportError, ValueError) as exception:
# Log any exception
task.log_exception(exception)
return False
Expand Down Expand Up @@ -159,8 +160,10 @@ def _check_unique_import_task(taxonomy: Taxonomy) -> bool:
if not last_task:
return True
return (
last_task.status == TagImportTaskState.SUCCESS.value
or last_task.status == TagImportTaskState.ERROR.value
last_task.status in {
TagImportTaskState.SUCCESS.value,
TagImportTaskState.ERROR.value
}
)


Expand Down Expand Up @@ -189,6 +192,6 @@ def _import_export_validations(taxonomy: Taxonomy):
if taxonomy.system_defined:
raise ValueError(
_(
f"Invalid taxonomy ({taxonomy.id}): You cannot import/export a system-defined taxonomy."
)
"Invalid taxonomy ({id}): You cannot import/export a system-defined taxonomy."
).format(id=taxonomy.id)
)
51 changes: 28 additions & 23 deletions openedx_tagging/core/tagging/import_export/exceptions.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,9 @@ class TagImportError(Exception):
Base exception for import
"""

def __init__(self, message: str = "", **kargs):
def __init__(self, message: str = ""):
super().__init__()
self.message = message
super().__init__(message, **kargs)

def __str__(self):
return str(self.message)
Expand All @@ -32,21 +32,21 @@ class TagParserError(TagImportError):
Base exception for parsers
"""

def __init__(self, tag: dict | None, **kargs):
def __init__(self, tag: dict | None, **kargs): # pylint: disable=unused-argument
super().__init__()
self.tag = tag
self.message = _(f"Import parser error on {tag}")
self.message = _("Import parser error on {tag}").format(tag=tag)


class ImportActionError(TagImportError):
"""
Base exception for actions
"""

def __init__(self, action: ImportAction, tag_id: str, message: str, **kargs):
def __init__(self, action: ImportAction, message: str, **kargs):
super().__init__(**kargs)
self.message = _(
f"Action error in '{action.name}' (#{action.index}): {message}"
)
"Action error in '{name}' (#{index}): {message}"
).format(name=action.name, index=action.index, message=message)


class ImportActionConflict(ImportActionError):
Expand All @@ -57,14 +57,19 @@ class ImportActionConflict(ImportActionError):
def __init__(
self,
action: ImportAction,
tag_id: str,
conflict_action_index: int,
message: str,
**kargs,
):
super().__init__(action, message, **kargs)
self.message = _(
f"Conflict with '{action.name}' (#{action.index}) "
f"and action #{conflict_action_index}: {message}"
"Conflict with '{action_name}' (#{action_index}) "
"and action #{conflict_action_index}: {message}"
).format(
action_name=action.name,
action_index=action.index,
conflict_action_index=conflict_action_index,
message=message,
)


Expand All @@ -73,36 +78,36 @@ class InvalidFormat(TagParserError):
Exception used when there is an error with the format
"""

def __init__(self, tag: dict | None, format: str, message: str, **kargs):
super().__init__(tag)
self.message = _(f"Invalid '{format}' format: {message}")
def __init__(self, tag: dict | None, input_format: str, message: str, **kargs):
super().__init__(tag, **kargs)
self.message = _("Invalid '{format}' format: {message}").format(format=input_format, message=message)


class FieldJSONError(TagParserError):
"""
Exception used when missing a required field on the .json
"""

def __init__(self, tag: dict | None, field, **kargs):
super().__init__(tag)
self.message = _(f"Missing '{field}' field on {tag}")
def __init__(self, tag: dict | None, field: str, **kargs):
super().__init__(tag, **kargs)
self.message = _("Missing '{field}' field on {tag}").format(field=field, tag=tag)


class EmptyJSONField(TagParserError):
"""
Exception used when a required field is empty on the .json
"""

def __init__(self, tag, field, **kargs):
self.tag = tag
self.message = _(f"Empty '{field}' field on {tag}")
def __init__(self, tag: dict | None, field: str, **kargs):
super().__init__(tag, **kargs)
self.message = _("Empty '{field}' field on {tag}").format(field=field, tag=tag)


class EmptyCSVField(TagParserError):
"""
Exception used when a required field is empty on the .csv
"""

def __init__(self, tag, field, row, **kargs):
self.tag = tag
self.message = _(f"Empty '{field}' field on the row {row}")
def __init__(self, tag: dict | None, field: str, row: int, **kargs):
super().__init__(tag, **kargs)
self.message = _("Empty '{field}' field on the row {row}").format(field=field, row=row)
10 changes: 5 additions & 5 deletions openedx_tagging/core/tagging/import_export/parsers.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,13 +212,13 @@ def _load_data(cls, file: BytesIO) -> tuple[list[dict], list[TagParserError]]:
tags_data = json.load(file)
except json.JSONDecodeError as error:
return [], [
InvalidFormat(tag=None, format=cls.format.value, message=str(error))
InvalidFormat(tag=None, input_format=cls.format.value, message=str(error))
]
if "tags" not in tags_data:
return [], [
InvalidFormat(
tag=None,
format=cls.format.value,
input_format=cls.format.value,
message=_("Missing 'tags' field on the .json file"),
)
]
Expand Down Expand Up @@ -298,8 +298,8 @@ def _verify_header(cls, header_fields: list[str]) -> list[TagParserError]:
errors.append(
InvalidFormat(
tag=None,
format=cls.format.value,
message=_(f"Missing '{req_field}' field on CSV headers"),
input_format=cls.format.value,
message=_("Missing '{req_field}' field on CSV headers").format(req_field=req_field),
)
)
return errors
Expand All @@ -319,4 +319,4 @@ def get_parser(parser_format: ParserFormat) -> type[Parser]:
if parser_format == parser.format:
return parser

raise ValueError(_(f"Parser not found for format {parser_format}"))
raise ValueError(_("Parser not found for format {parser_format}").format(parser_format=parser_format))
Loading

0 comments on commit 0934450

Please sign in to comment.