Skip to content

Commit

Permalink
Merge pull request #1426 from heinezen/lgtm
Browse files Browse the repository at this point in the history
Converter code cleanup
TheJJ authored Oct 15, 2021

Verified

This commit was signed with the committer’s verified signature.
sdispater Sébastien Eustace
2 parents 103bc3a + e684e76 commit bf0094c
Showing 16 changed files with 153 additions and 156 deletions.
6 changes: 4 additions & 2 deletions doc/ide/vscode.md
Original file line number Diff line number Diff line change
@@ -67,13 +67,15 @@ If you use a C/C++ language support extension, you need to add the path to the *

If you use a Python language support extension with `autopep8` formatting, you should add these settings to get the openage Python code style. Add these entries to the list of passed arguments:

* `--ignore E221,E241,E251,E501`
* `--ignore`
* `E221,E241,E251,E501`

Ignoring the `E221,E241,E251` errors allows placing multiple spaces around commas and before comments for alignment, while ignoring `E501` disables auto-formatting of overlong lines.

If you don't want to ignore `E501`, you should add this argument which increases the maximum line length to 100:

* `--line-length 100`
* `--max-line-length`
* `100`


## Add openage configure and build tasks
Original file line number Diff line number Diff line change
@@ -380,7 +380,7 @@ def extend_raw_member(self, name, push_value, origin):
member_origin = raw_member[2]

if name == member_name and member_origin == origin:
member_value = member_value.extend(push_value)
member_value.extend(push_value)
break

else:
16 changes: 0 additions & 16 deletions openage/convert/entity_object/conversion/stringresource.py
Original file line number Diff line number Diff line change
@@ -5,7 +5,6 @@
from collections import defaultdict

from ...entity_object.conversion.genie_structure import GenieStructure
from ...entity_object.export import data_definition


class StringResource(GenieStructure):
@@ -27,21 +26,6 @@ def get_tables(self):
"""
return self.strings

def dump(self, filename):
data = []

for lang, langstrings in self.strings.items():
for idx, text in langstrings.items():
entry = {
"id": idx,
"lang": lang,
"text": text,
}
data.append(entry)

data = sorted(data, key=lambda x: x["id"])
return [data_definition.DataDefinition(self, data, filename)]

@classmethod
def get_data_format_members(cls, game_version):
"""
Original file line number Diff line number Diff line change
@@ -4073,7 +4073,6 @@ def idle_ability(line):

if civ_animation_id != ability_animation_id:
# Find the corresponding graphics set
graphics_set_id = -1
for set_id, items in gset_lookup_dict.items():
if civ_id in items[0]:
graphics_set_id = set_id
@@ -6739,7 +6738,6 @@ def trade_ability(line):
# Trade route (use the trade route to the market)
trade_routes = []

trade_post_id = -1
unit_commands = current_unit["unit_commands"].get_value()
for command in unit_commands:
# Find the trade command and the trade post id
47 changes: 30 additions & 17 deletions openage/convert/processor/conversion/aoc/modifier_subprocessor.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,6 @@
# Copyright 2020-2021 the openage authors. See copying.md for legal info.
#
# pylint: disable=too-many-locals,too-many-branches,too-many-nested-blocks
#
# TODO:
# pylint: disable=line-too-long
# pylint: disable=too-many-locals,too-many-branches,too-many-nested-blocks,too-many-statements

"""
Derives and adds abilities to lines or civ groups. Subroutine of the
@@ -34,8 +31,12 @@ def elevation_attack_modifiers(converter_obj_group):
"""
dataset = converter_obj_group.data
modifiers = [
dataset.pregen_nyan_objects["util.modifier.elevation_difference.AttackHigh"].get_nyan_object(),
dataset.pregen_nyan_objects["util.modifier.elevation_difference.AttackLow"].get_nyan_object()
dataset.pregen_nyan_objects[
"util.modifier.elevation_difference.AttackHigh"
].get_nyan_object(),
dataset.pregen_nyan_objects[
"util.modifier.elevation_difference.AttackLow"
].get_nyan_object()
]

return modifiers
@@ -51,7 +52,9 @@ def flyover_effect_modifier(converter_obj_group):
:rtype: ...dataformat.forward_ref.ForwardRef
"""
dataset = converter_obj_group.data
modifier = dataset.pregen_nyan_objects["util.modifier.flyover_cliff.AttackFlyover"].get_nyan_object()
modifier = dataset.pregen_nyan_objects[
"util.modifier.flyover_cliff.AttackFlyover"
].get_nyan_object()

return modifier

@@ -89,14 +92,16 @@ def gather_rate_modifier(converter_obj_group):
# Find a gather ability.
type_id = command["type"].get_value()

if type_id not in (5, 110):
gather_task_ids = internal_name_lookups.get_gather_lookups(
dataset.game_version).keys()
if type_id not in gather_task_ids:
continue

work_value = command["work_value1"].get_value()

# Check if the work value is 1 (with some rounding error margin)
# if not we have to create a modifier
if work_value < 1.0001 or work_value > 0.9999:
# if not, we have to create a modifier
if 0.9999 < work_value < 1.0001:
continue

# Search for the lines with the matching class/unit id
@@ -118,6 +123,9 @@ def gather_rate_modifier(converter_obj_group):
if line.get_class_id() == class_id:
lines.append(line)

else:
raise Exception("Gather task has no valid target ID.")

# Create a modifier for each matching resource spot
for resource_line in lines:
head_unit_id = resource_line.get_head_unit_id()
@@ -135,22 +143,27 @@ def gather_rate_modifier(converter_obj_group):
modifier_raw_api_object = RawAPIObject(modifier_ref,
"%sGatheringRate",
dataset.nyan_api_objects)
modifier_raw_api_object.add_raw_parent("engine.modifier.multiplier.type.GatheringRate")
modifier_raw_api_object.add_raw_parent(
"engine.modifier.multiplier.type.GatheringRate")
modifier_location = ForwardRef(converter_obj_group, target_obj_name)
modifier_raw_api_object.set_location(modifier_location)

# Multiplier
modifier_raw_api_object.add_raw_member("multiplier",
work_value,
"engine.modifier.multiplier.MultiplierModifier")
modifier_raw_api_object.add_raw_member(
"multiplier",
work_value,
"engine.modifier.multiplier.MultiplierModifier"
)

# Resource spot
spot_ref = "%s.Harvestable.%sResourceSpot" % (resource_line_name,
resource_line_name)
spot_forward_ref = ForwardRef(resource_line, spot_ref)
modifier_raw_api_object.add_raw_member("resource_spot",
spot_forward_ref,
"engine.modifier.multiplier.type.GatheringRate")
modifier_raw_api_object.add_raw_member(
"resource_spot",
spot_forward_ref,
"engine.modifier.multiplier.type.GatheringRate"
)

converter_obj_group.add_raw_api_object(modifier_raw_api_object)
modifier_forward_ref = ForwardRef(converter_obj_group,
2 changes: 0 additions & 2 deletions openage/convert/processor/conversion/aoc/processor.py
Original file line number Diff line number Diff line change
@@ -511,7 +511,6 @@ def create_unit_lines(full_data_set):

# Search other_connections for the previous unit in line
connected_types = connection["other_connections"].get_value()
connected_index = -1
for index, _ in enumerate(connected_types):
connected_type = connected_types[index]["other_connection"].get_value()
if connected_type == 2:
@@ -645,7 +644,6 @@ def create_building_lines(full_data_set):
continue

# Find the previous building
connected_index = -1
for c_index, _ in enumerate(connected_types):
connected_type = connected_types[c_index]["other_connection"].get_value()
if connected_type == 1:
Original file line number Diff line number Diff line change
@@ -1719,7 +1719,6 @@ def trade_ability(line):
# Trade route (use the trade route o the market)
trade_routes = []

trade_post_id = -1
unit_commands = current_unit["unit_commands"].get_value()
for command in unit_commands:
# Find the trade command and the trade post id
2 changes: 0 additions & 2 deletions openage/convert/processor/conversion/swgbcc/processor.py
Original file line number Diff line number Diff line change
@@ -235,7 +235,6 @@ def create_unit_lines(full_data_set):

# Search other_connections for the previous unit in line
connected_types = connection["other_connections"].get_value()
connected_index = -1
for index, _ in enumerate(connected_types):
connected_type = connected_types[index]["other_connection"].get_value()
if connected_type == 2:
@@ -438,7 +437,6 @@ def create_building_lines(full_data_set):

# Search other_connections for the previous unit in line
connected_types = connection["other_connections"].get_value()
connected_index = -1
for index, _ in enumerate(connected_types):
connected_type = connected_types[index]["other_connection"].get_value()
if connected_type == 1:
62 changes: 37 additions & 25 deletions openage/convert/processor/export/media_exporter.py
Original file line number Diff line number Diff line change
@@ -4,14 +4,15 @@
"""
Converts media requested by export requests to files.
"""
import logging
import os

from openage.convert.entity_object.export.texture import Texture
from openage.convert.service import debug_info
from openage.convert.service.export.load_media_cache import load_media_cache
from openage.convert.value_object.read.media.blendomatic import Blendomatic
from openage.convert.value_object.read.media_types import MediaType
from openage.log import dbg
from openage.log import dbg, get_loglevel


class MediaExporter:
@@ -124,10 +125,12 @@ def _export_blend(export_request, sourcedir, exportdir, blend_mode_count=None):
f"{export_request.target_filename}{idx}.png"
)

MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, f"{export_request.target_filename}{idx}.png"]
)
if get_loglevel() <= logging.DEBUG:
MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir,
f"{export_request.target_filename}{idx}.png"]
)

@staticmethod
def _export_graphics(export_request, sourcedir, exportdir, palettes,
@@ -207,10 +210,12 @@ def _export_graphics(export_request, sourcedir, exportdir, palettes,
export_request.set_changed()
export_request.notify_observers(metadata)
export_request.clear_changed()
MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, export_request.target_filename]
)

if get_loglevel() <= logging.DEBUG:
MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, export_request.target_filename]
)

@staticmethod
def _export_interface(export_request, sourcedir, **kwargs):
@@ -268,10 +273,11 @@ def _export_sound(export_request, sourcedir, exportdir):
with export_file.open_w() as outfile:
outfile.write(soundata)

MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, export_request.target_filename]
)
if get_loglevel() <= logging.DEBUG:
MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, export_request.target_filename]
)

@staticmethod
def _export_terrain(export_request, sourcedir, exportdir, palettes,
@@ -337,10 +343,11 @@ def _export_terrain(export_request, sourcedir, exportdir, palettes,
compression_level,
)

MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, export_request.target_filename]
)
if get_loglevel() <= logging.DEBUG:
MediaExporter.log_fileinfo(
source_file,
exportdir[export_request.targetdir, export_request.target_filename]
)

@staticmethod
def _get_media_cache(export_request, sourcedir, palettes, compression_level):
@@ -466,18 +473,23 @@ def log_fileinfo(source_file, target_file):
source_format = source_file.suffix[1:].upper()
target_format = target_file.suffix[1:].upper()

with source_file.open('r') as src:
src.seek(0, os.SEEK_END)
source_size = src.tell()
source_path = source_file.resolve_native_path()
if source_path:
source_size = os.path.getsize(source_path)

else:
with source_file.open('r') as src:
src.seek(0, os.SEEK_END)
source_size = src.tell()

with target_file.open('r') as dest:
dest.seek(0, os.SEEK_END)
target_size = dest.tell()
target_path = target_file.resolve_native_path()
target_size = os.path.getsize(target_path)

log = ("Converted: "
f"{source_file.name} "
f" ({source_format}, {source_size}B) "
f"({source_format}, {source_size}B) "
f"-> {target_file.name} "
f"({target_format}, {target_size}B)")
f"({target_format}, {target_size}B | "
f"{(target_size / source_size * 100) - 100:+.1f}%)")

dbg(log)
24 changes: 0 additions & 24 deletions openage/convert/value_object/read/media/blendomatic.py
Original file line number Diff line number Diff line change
@@ -14,7 +14,6 @@

from .....log import dbg
from ....entity_object.conversion.genie_structure import GenieStructure
from ....entity_object.export.data_definition import DataDefinition


class BlendingTile:
@@ -254,32 +253,9 @@ def get_textures(self):
one atlas per blending mode is generated,
each atlas contains all blending masks merged on one texture
"""

from ....entity_object.export.texture import Texture
return [Texture(b_mode) for b_mode in self.blending_modes]

def dump(self, filename):
"""
Return a printable file.
"""
data = [
{"blend_mode": idx}
for idx, _ in enumerate(self.blending_modes)
]
return [DataDefinition(self, data, filename)]

def save(self, fslikeobj, path, compression_level):
"""
Save the blending mask textures to disk.
"""

for idx, texture in enumerate(self.get_textures()):
name = "mode%02d.png" % idx
dbg("saving blending mode %02d texture -> %s", idx, name)
texture.save(fslikeobj, path + '/' + name, compression_level)

dbg("blending masks successfully exported")

@classmethod
def get_data_format_members(cls, game_version):
"""
39 changes: 19 additions & 20 deletions openage/convert/value_object/read/media/colortable.py
Original file line number Diff line number Diff line change
@@ -8,7 +8,6 @@

from .....log import dbg
from ....entity_object.conversion.genie_structure import GenieStructure
from ....entity_object.export.data_definition import DataDefinition


class ColorTable(GenieStructure):
@@ -151,22 +150,6 @@ def get_ndarray(self):
def save_visualization(self, fileobj):
self.gen_image().save(fileobj, 'png')

def dump(self, filename):
data = list()

# dump all color entries
for idx, entry in enumerate(self.palette):
color_entry = {
"idx": idx,
"r": entry[0],
"g": entry[1],
"b": entry[2],
"a": 255,
}
data.append(color_entry)

return [DataDefinition(self, data, filename)]

@classmethod
def get_data_format_members(cls, game_version):
"""
@@ -183,7 +166,7 @@ def get_data_format_members(cls, game_version):
return data_format


class PlayerColorTable(ColorTable):
class PlayerColorTable(GenieStructure):
"""
this class represents stock player color values.
@@ -193,7 +176,8 @@ class PlayerColorTable(ColorTable):
__slots__ = ('header', 'version', 'palette')

def __init__(self, base_table):
# TODO pylint: disable=super-init-not-called
super().__init__()

if not isinstance(base_table, ColorTable):
raise Exception(f"no ColorTable supplied, instead: {type(base_table)}")

@@ -211,5 +195,20 @@ def __init__(self, base_table):
r, g, b = base_table[16 * i + subcol]
self.palette.append((r, g, b))

@classmethod
def get_data_format_members(cls, game_version):
"""
Return the members in this struct.
"""
data_format = (
(True, "idx", None, "int32_t"),
(True, "r", None, "uint8_t"),
(True, "g", None, "uint8_t"),
(True, "b", None, "uint8_t"),
(True, "a", None, "uint8_t"),
)

return data_format

def __repr__(self):
return "ColorTable<%d entries>" % len(self.palette)
return "PlayerColorTable<%d entries>" % len(self.palette)
6 changes: 3 additions & 3 deletions openage/log/__init__.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2014-2018 the openage authors. See copying.md for legal info.
# Copyright 2014-2021 the openage authors. See copying.md for legal info.

"""
Python logging.
@@ -8,18 +8,18 @@
"""

import logging
from logging import Handler
from os import environ

from ..util.math import clamp

PYTHON_TO_CPP_LOG_LEVEL = {}


class CppHandler(Handler):
class CppHandler(logging.Handler):
"""
CppHandler calls into the CPP logging system if the library has been loaded.
"""

def __init__(self):
super().__init__()

81 changes: 45 additions & 36 deletions openage/nyan/nyan_structs.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
# Copyright 2019-2021 the openage authors. See copying.md for legal info.
#
# pylint: disable=too-many-lines,too-many-arguments,too-many-return-statements,too-many-locals

"""
Nyan structs.
@@ -19,7 +21,7 @@


INDENT = " "
LINE_WIDTH = 130
MAX_LINE_WIDTH = 130


class NyanObject:
@@ -177,17 +179,19 @@ def get_member_by_name(self, member_name, origin=None):
Returns the NyanMember with the specified name.
"""
if origin and origin is not self:
# Inherited member: Search in the inheritance tree
for inherited_member in self._inherited_members:
if origin == inherited_member.get_origin():
if inherited_member.get_name() == member_name:
return inherited_member

raise Exception("%s has no member '%s' with origin '%s'"
% (self, member_name, origin))
else:
for member in self._members:
if member.get_name() == member_name:
return member

# Else: Member should be a direct member of this nyan object
for member in self._members:
if member.get_name() == member_name:
return member

raise Exception(f"{self} has no member '{member_name}'")

@@ -241,7 +245,8 @@ def is_abstract(self):
"""
return len(self.get_uninitialized_members()) > 0

def is_patch(self):
@staticmethod
def is_patch():
"""
Returns True if the object is a NyanPatch.
"""
@@ -719,38 +724,38 @@ def accepts_op(self, operator):
MemberOperator.DIVIDE):
return False

elif self._member_type is MemberType.TEXT\
if self._member_type is MemberType.TEXT\
and operator not in (MemberOperator.ASSIGN,
MemberOperator.ADD):
return False

elif self._member_type is MemberType.FILE\
if self._member_type is MemberType.FILE\
and operator is not MemberOperator.ASSIGN:
return False

elif self._member_type is MemberType.BOOLEAN\
if self._member_type is MemberType.BOOLEAN\
and operator not in (MemberOperator.ASSIGN,
MemberOperator.AND,
MemberOperator.OR):
return False

elif self._member_type is MemberType.SET\
if self._member_type is MemberType.SET\
and operator not in (MemberOperator.ASSIGN,
MemberOperator.ADD,
MemberOperator.SUBTRACT,
MemberOperator.AND,
MemberOperator.OR):
return False

elif self._member_type is MemberType.ORDEREDSET\
if self._member_type is MemberType.ORDEREDSET\
and operator not in (MemberOperator.ASSIGN,
MemberOperator.ADD,
MemberOperator.SUBTRACT,
MemberOperator.AND,
MemberOperator.OR):
return False

elif self._member_type is MemberType.DICT\
if self._member_type is MemberType.DICT\
and operator not in (MemberOperator.ASSIGN,
MemberOperator.ADD,
MemberOperator.SUBTRACT,
@@ -768,7 +773,7 @@ def accepts_value(self, value):
if value is MemberSpecialValue.NYAN_NONE:
return self._member_type is MemberType.OPTIONAL

elif self.is_modifier():
if self.is_modifier():
return self._element_types[0].accepts_value(value)

# inf is only used for ints and floats
@@ -799,12 +804,16 @@ def _sanity_check(self):
# element types of complex types cannot be complex
for elem_type in self._element_types:
if elem_type.is_real_complex():
raise Exception(f"{repr(self)}: element types cannot be complex but contains {elem_type}")
raise Exception(
f"{repr(self)}: element types cannot be complex "
f"but contains {elem_type}")

else:
# if the member is not a composite, the element types should be None
if self._element_types:
raise Exception(f"{repr(self)}: member type has element types but is not a composite")
raise Exception(
f"{repr(self)}: member type has element types "
"but is not a composite")

def dump(self, import_tree=None, namespace=None):
"""
@@ -813,7 +822,7 @@ def dump(self, import_tree=None, namespace=None):
if self.is_primitive():
return self._member_type.value

elif self.is_object():
if self.is_object():
if import_tree:
sfqon = ".".join(import_tree.get_alias_fqon(
self._member_type.get_fqon(),
@@ -924,12 +933,19 @@ def is_initialized(self):
"""
return self.value is not None

def is_inherited(self):
@staticmethod
def is_inherited():
"""
Returns True if the member is inherited from another object.
"""
return False

def has_value(self):
"""
Returns True if the member has a value.
"""
return self.value is not None

def set_value(self, value, operator=None):
"""
Set the value of the nyan member to the specified value and
@@ -1044,16 +1060,17 @@ def _type_conversion(self):
elif self._member_type.get_real_type() is MemberType.DICT:
self.value = dict(self.value)

def _get_primitive_value_str(self, member_type, value, import_tree=None, namespace=None):
@staticmethod
def _get_primitive_value_str(member_type, value, import_tree=None, namespace=None):
"""
Returns the nyan string representation of primitive values.
Subroutine of _get_value_str()
Subroutine of _get_value_str(..)
"""
if member_type.get_real_type() in (MemberType.TEXT, MemberType.FILE):
return f"\"{value}\""

elif member_type.is_real_object():
if member_type.is_real_object():
if import_tree:
sfqon = ".".join(import_tree.get_alias_fqon(
value.get_fqon(),
@@ -1067,7 +1084,8 @@ def _get_primitive_value_str(self, member_type, value, import_tree=None, namespa

return f"{value}"

def _get_complex_value_str(self, indent_depth, member_type, value, import_tree=None, namespace=None):
def _get_complex_value_str(self, indent_depth, member_type, value,
import_tree=None, namespace=None):
"""
Returns the nyan string representation of complex values.
@@ -1124,23 +1142,21 @@ def _get_complex_value_str(self, indent_depth, member_type, value, import_tree=N
f"{concat_values}"
))

if line_length < LINE_WIDTH:
if line_length < MAX_LINE_WIDTH:
output_str += concat_values

elif stored_values:
output_str += "\n"

# How much space is left per formatted line
space_left = LINE_WIDTH - len((indent_depth + 2) * INDENT)
space_left = MAX_LINE_WIDTH - len((indent_depth + 2) * INDENT)

# Find the longest value's length
longest_len = len(max(stored_values, key=len))

# How man values of that length fit in one line
values_per_line = space_left // longest_len

if values_per_line < 1:
values_per_line = 1
values_per_line = max(values_per_line, 1)

output_str += (indent_depth + 2) * INDENT

@@ -1187,7 +1203,7 @@ def _get_value_str(self, indent_depth, import_tree=None, namespace=None):
namespace=namespace
)

elif self.is_complex():
if self.is_complex():
return self._get_complex_value_str(
indent_depth,
self._member_type,
@@ -1196,11 +1212,10 @@ def _get_value_str(self, indent_depth, import_tree=None, namespace=None):
namespace=namespace
)

else:
raise Exception(f"{repr(self)} has no valid type")
raise Exception(f"{repr(self)} has no valid type")

def __str__(self):
return self._get_value_str()
return self._get_value_str(indent_depth=0)

def __repr__(self):
return f"NyanMember<{self.name}: {self._member_type}>"
@@ -1334,12 +1349,6 @@ def is_initialized(self):
return super().is_initialized() or\
self._parent.get_member_by_name(self.name, self._origin).is_initialized()

def has_value(self):
"""
Returns True if the inherited member has a value
"""
return self.value is not None

def dump(self, indent_depth, import_tree=None, namespace=None):
"""
Returns the string representation of the member.
4 changes: 2 additions & 2 deletions openage/util/context.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2015-2016 the openage authors. See copying.md for legal info.
# Copyright 2015-2021 the openage authors. See copying.md for legal info.

"""
Provides some utility context guards.
@@ -15,4 +15,4 @@ def __enter__():

@staticmethod
def __exit__(exc_type, exc_value, traceback):
del exc_type, exc_value, traceback # unused
pass
6 changes: 4 additions & 2 deletions openage/util/fslike/filecollection.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2015-2017 the openage authors. See copying.md for legal info.
# Copyright 2015-2021 the openage authors. See copying.md for legal info.

"""
Provides Filecollection, a utility class for combining multiple file-like
@@ -18,6 +18,7 @@ class FileCollection(FSLikeObject):
Uses lambdas to access files somewhere else on the fly.
"""

def __init__(self):
super().__init__()

@@ -212,13 +213,14 @@ def watch(self, parts, callback):
return False

def poll_watches(self):
del self # unused
pass


class FileCollectionPath(Path):
"""
Provides an additional method for adding a file at this path.
"""

def add_file(self, open_r=None, open_w=None, filesize=None, mtime=None):
"""
All parent directories are 'created', if needed.
9 changes: 8 additions & 1 deletion openage/util/fslike/wrapper.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2015-2020 the openage authors. See copying.md for legal info.
# Copyright 2015-2021 the openage authors. See copying.md for legal info.

"""
Provides
@@ -28,6 +28,7 @@ class Wrapper(FSLikeObject):
Inherit to override individual methods.
Pass a context guard to protect calls.
"""

def __init__(self, obj, contextguard=None):
if not isinstance(obj, Path):
raise TypeError(f"Path expected as obj, got '{type(obj)}'")
@@ -68,6 +69,9 @@ def resolve_r(self, parts):
def resolve_w(self, parts):
return self.obj.joinpath(parts) if self.writable(parts) else None

def get_native_path(self, parts):
return self.obj.joinpath(parts).resolve_native_path() if self.exists(parts) else None

def list(self, parts):
with self.contextguard:
return list(self.obj.joinpath(parts).list())
@@ -128,6 +132,7 @@ class WriteBlocker(ReadOnlyFSLikeObject, Wrapper):
All writing calls raise IOError, and writable returns False.
"""

def __repr__(self):
return f"WriteBlocker({repr(self.obj)})"

@@ -136,6 +141,7 @@ class Synchronizer(Wrapper):
"""
Wraps a FSLikeObject, securing all wrapped calls with a mutex.
"""

def __init__(self, obj):
self.lock = Lock()
super().__init__(obj, self.lock)
@@ -151,6 +157,7 @@ class GuardedFile(FileLikeObject):
Wraps file-like objects, protecting calls to their members with the given
context guard.
"""

def __init__(self, obj, guard):
super().__init__()
self.obj = obj

0 comments on commit bf0094c

Please sign in to comment.