chore: Optimize code
This commit is contained in:
parent
5bbb5605f1
commit
7e9131d966
@ -24,4 +24,3 @@ if __name__ == '__main__':
|
||||
# 记录启动信息
|
||||
start_time_ns = time.time_ns()
|
||||
start_time_perf_ns = time.perf_counter_ns()
|
||||
|
@ -10,6 +10,8 @@ mail: 3695888@qq.com
|
||||
github: @shenjackyuanjie
|
||||
gitee: @shenjackyuanjie
|
||||
"""
|
||||
|
||||
import contextlib
|
||||
# import ctypes
|
||||
import sys
|
||||
import logging
|
||||
@ -72,14 +74,14 @@ class _DR_option(Options):
|
||||
gui_scale: float = 1.0 # default 1.0 2.0 -> 2x 3 -> 3x
|
||||
|
||||
def init(self, **kwargs):
|
||||
if not sys.platform == 'darwin': # MacOS 的测试只能在 Macos 上跑
|
||||
if sys.platform != 'darwin': # MacOS 的测试只能在 Macos 上跑
|
||||
self.pyglet_macosx_dev_test = False
|
||||
try:
|
||||
from libs.Difficult_Rocket_rs import test_call, get_version_str
|
||||
test_call(self)
|
||||
print(f'DR_rust available: {get_version_str()}')
|
||||
except ImportError:
|
||||
if not __name__ == '__main__':
|
||||
if __name__ != '__main__':
|
||||
traceback.print_exc()
|
||||
self.DR_rust_available = False
|
||||
self.use_DR_rust = self.use_DR_rust and self.DR_rust_available
|
||||
@ -119,15 +121,13 @@ class _DR_runtime(Options):
|
||||
default_language: str = 'zh-CN'
|
||||
|
||||
def init(self, **kwargs) -> None:
|
||||
try:
|
||||
with contextlib.suppress(ImportError):
|
||||
from libs.Difficult_Rocket_rs import get_version_str
|
||||
self.DR_Rust_get_version = Version(get_version_str())
|
||||
if self.DR_Rust_get_version != self.DR_Rust_version:
|
||||
relationship = 'larger' if self.DR_Rust_version > self.DR_Rust_get_version else 'smaller'
|
||||
warnings.warn(f'DR_rust builtin version is {self.DR_Rust_version} but true version is {get_version_str()}.\n'
|
||||
f'Builtin version {relationship} than true version')
|
||||
except ImportError:
|
||||
pass
|
||||
|
||||
def __init__(self, **kwargs):
|
||||
self.__options = {'language': self.language}
|
||||
|
@ -118,9 +118,7 @@ class SR1PartTexture:
|
||||
|
||||
@classmethod
|
||||
def get_textures_from_type(cls, name: str) -> Union[None, str]:
|
||||
if name not in cls.part_type_sprite:
|
||||
return None
|
||||
return cls.part_type_sprite[name]
|
||||
return None if name not in cls.part_type_sprite else cls.part_type_sprite[name]
|
||||
|
||||
|
||||
class SR1Rotation(Options):
|
||||
@ -145,15 +143,8 @@ def xml_bool(bool_like: Union[str, int, bool, None]) -> bool:
|
||||
if isinstance(bool_like, bool):
|
||||
return bool_like
|
||||
if isinstance(bool_like, int):
|
||||
if bool_like == 0:
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
if bool_like == '0':
|
||||
return False
|
||||
if bool_like.lower() == 'false':
|
||||
return False
|
||||
return True
|
||||
return bool_like != 0
|
||||
return False if bool_like == '0' else bool_like.lower() != 'false'
|
||||
|
||||
#
|
||||
#
|
||||
|
@ -71,7 +71,7 @@ class Options:
|
||||
if hasattr(self, 'load_file'):
|
||||
try:
|
||||
self.load_file()
|
||||
except:
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
self.flush_option()
|
||||
|
||||
@ -138,7 +138,7 @@ class Options:
|
||||
max_len_value_t = 1
|
||||
option_list = []
|
||||
for key, value in options.items():
|
||||
value_t = type(value) if not isinstance(value, Type) else value
|
||||
value_t = value if isinstance(value, Type) else type(value)
|
||||
max_len_key = max(max_len_key, len(key))
|
||||
max_len_value = max(max_len_value, len(str(value)))
|
||||
max_len_value_t = max(max_len_value_t, len(str(value_t)))
|
||||
@ -154,8 +154,7 @@ class Options:
|
||||
|
||||
@staticmethod
|
||||
def init_option(options_class: 'Options'.__class__, init_value: Optional[dict] = None) -> 'Options':
|
||||
options_class_instance = options_class(**init_value if init_value is not None else {})
|
||||
return options_class_instance
|
||||
return options_class(**init_value if init_value is not None else {})
|
||||
|
||||
|
||||
class Fonts(Options):
|
||||
|
@ -76,9 +76,9 @@ class Client:
|
||||
self.process_pid = os.getpid()
|
||||
self.net_mode = net_mode
|
||||
self.caption = DR_runtime.format(self.config['window']['caption'])
|
||||
file_drop = True
|
||||
if pyglet.compat_platform == 'darwin' and not DR_option.pyglet_macosx_dev_test:
|
||||
file_drop = False
|
||||
file_drop = bool(
|
||||
pyglet.compat_platform != 'darwin' or DR_option.pyglet_macosx_dev_test
|
||||
)
|
||||
self.window = ClientWindow(net_mode=self.net_mode,
|
||||
width=int(self.config['window']['width']),
|
||||
height=int(self.config['window']['height']),
|
||||
@ -117,7 +117,7 @@ def _call_screen_after(func: Callable) -> Callable:
|
||||
if hasattr(a_screen, func.__name__):
|
||||
try:
|
||||
getattr(a_screen, func.__name__)(*args, **kwargs)
|
||||
except:
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
return result
|
||||
|
||||
@ -132,7 +132,7 @@ def _call_screen_before(func: Callable) -> Callable:
|
||||
if hasattr(a_screen, func.__name__):
|
||||
try:
|
||||
getattr(a_screen, func.__name__)(*args, **kwargs)
|
||||
except:
|
||||
except Exception:
|
||||
traceback.print_exc()
|
||||
result = func(self, *args, **kwargs)
|
||||
return result
|
||||
@ -354,13 +354,19 @@ class ClientWindow(Window):
|
||||
|
||||
@_call_screen_after
|
||||
def on_mouse_press(self, x, y, button, modifiers) -> None:
|
||||
self.logger.debug(tr.lang('window', 'mouse.press').format([x, y], tr.lang('window', 'mouse.{}'.format(
|
||||
mouse.buttons_string(button)))))
|
||||
self.logger.debug(
|
||||
tr.lang('window', 'mouse.press').format(
|
||||
[x, y], tr.lang('window', f'mouse.{mouse.buttons_string(button)}')
|
||||
)
|
||||
)
|
||||
|
||||
@_call_screen_after
|
||||
def on_mouse_release(self, x, y, button, modifiers) -> None:
|
||||
self.logger.debug(tr.lang('window', 'mouse.release').format([x, y], tr.lang('window', 'mouse.{}'.format(
|
||||
mouse.buttons_string(button)))))
|
||||
self.logger.debug(
|
||||
tr.lang('window', 'mouse.release').format(
|
||||
[x, y], tr.lang('window', f'mouse.{mouse.buttons_string(button)}')
|
||||
)
|
||||
)
|
||||
|
||||
@_call_screen_after
|
||||
def on_key_press(self, symbol, modifiers) -> None:
|
||||
|
@ -35,11 +35,10 @@ class FpsLogger:
|
||||
tick: Decimal):
|
||||
if pyglet_fps != 0:
|
||||
self.fps_list.append(pyglet_fps)
|
||||
else:
|
||||
if tick != 0:
|
||||
self.fps_list.append(float(1 / tick))
|
||||
else:
|
||||
elif tick == 0:
|
||||
self.fps_list.append(1)
|
||||
else:
|
||||
self.fps_list.append(float(1 / tick))
|
||||
if len(self.fps_list) > self.count:
|
||||
self.fps_list = self.fps_list[-self.count + 1:] # 整个列表往前挪一位
|
||||
if len(self.get_fps_list) > self.count:
|
||||
|
@ -205,10 +205,13 @@ class SingleTextStyle:
|
||||
输出字体样式的HTML字符
|
||||
:return: HTML 格式字符
|
||||
"""
|
||||
if not suffix:
|
||||
return self.HTML_bold() + self.HTML_italic() + self.HTML_font()
|
||||
else:
|
||||
return font_HTML_end + (bold_HTML_end if self.bold else '') + (italic_HTML_end if self.italic else '')
|
||||
return (
|
||||
(font_HTML_end
|
||||
+ (bold_HTML_end if self.bold else '')
|
||||
+ (italic_HTML_end if self.italic else ''))
|
||||
if suffix
|
||||
else self.HTML_bold() + self.HTML_italic() + self.HTML_font()
|
||||
)
|
||||
|
||||
|
||||
# [\u4e00-\u9fa5] 中文字符
|
||||
@ -267,11 +270,11 @@ italic_HTML_end = '</i>'
|
||||
def decode_text2HTML(text: str,
|
||||
configs=None,
|
||||
show_style: bool = False) -> str:
|
||||
if text == '':
|
||||
if not text:
|
||||
return ''
|
||||
if configs is None:
|
||||
configs = default_fonts_config
|
||||
style_list = [SingleTextStyle(text=text[x]) for x in range(0, len(text))]
|
||||
style_list = [SingleTextStyle(text=text[x]) for x in range(len(text))]
|
||||
|
||||
# 根据输入的配置对每一个字符进行样式设定
|
||||
for config in configs:
|
||||
@ -312,9 +315,7 @@ def decode_text2HTML(text: str,
|
||||
style_list[0].prefix += style_list[0].HTML() # 不管怎么说都要在最前面加一个字符标识
|
||||
for style_index in range(1, len(style_list)):
|
||||
if style_list[style_index].show: # 如果这个字符显示
|
||||
if not style_list[style_index - 1].show: # 如果前面一个字符不显示(且这个字符显示)
|
||||
style_list[style_index].prefix += style_list[style_index].HTML() # 那么就直接给这个字符的前缀添加
|
||||
else: # 开始根据前面的情况处理每种单独的标签
|
||||
if style_list[style_index - 1].show: # 开始根据前面的情况处理每种单独的标签
|
||||
if not style_list[style_index - 1].same_font(style_list[style_index]):
|
||||
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML_font(suffix=True)
|
||||
style_list[style_index].prefix += style_list[style_index].HTML_font()
|
||||
@ -324,17 +325,17 @@ def decode_text2HTML(text: str,
|
||||
if not style_list[style_index - 1].same_italic(style_list[style_index]):
|
||||
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML_italic(suffix=True)
|
||||
style_list[style_index].prefix += style_list[style_index].HTML_italic()
|
||||
else: # 如果这个字符不显示
|
||||
if style_list[style_index - 1].show: # 如果前面一个字符显示(且这个字符不显示)
|
||||
else: # 如果前面一个字符不显示(且这个字符显示)
|
||||
style_list[style_index].prefix += style_list[style_index].HTML() # 那么就直接给这个字符的前缀添加
|
||||
elif style_list[style_index - 1].show: # 如果前面一个字符显示(且这个字符不显示)
|
||||
style_list[style_index - 1].suffix += style_list[style_index - 1].HTML(suffix=True)
|
||||
# 如果前面一个字符也不显示那就直接 pass
|
||||
if style_list[-1].show:
|
||||
style_list[-1].suffix += style_list[-1].HTML(suffix=True)
|
||||
|
||||
# 输出最终的 HTML 文本
|
||||
formatted_HTML_text = '' # 初始化一下
|
||||
for style in style_list: # 每一个样式
|
||||
if style.show: # 如果这个字符显示
|
||||
formatted_HTML_text += style.prefix + style.text + style.suffix # 文本的后面附加一下
|
||||
formatted_HTML_text = ''.join(
|
||||
style.prefix + style.text + style.suffix
|
||||
for style in style_list
|
||||
if style.show
|
||||
)
|
||||
del style_list # 主动删掉 style_list 释放内存
|
||||
return formatted_HTML_text # 返回,DONE!
|
||||
|
@ -4,7 +4,6 @@
|
||||
# All rights reserved
|
||||
# -------------------------------
|
||||
|
||||
import random
|
||||
from xml.etree import ElementTree
|
||||
from xml.etree.ElementTree import Element
|
||||
from typing import List, TYPE_CHECKING, Union, Dict, Optional
|
||||
@ -55,11 +54,10 @@ def get_sr1_part(part_xml: Element) -> Optional[SR1PartData]:
|
||||
# f'angle: {part_angle} angle_v: {part_angle_v} editor_angle: {part_editor_angle} '
|
||||
# f'flip_x: {part_flip_x} flip_y: {part_flip_y} explode: {part_explode} '
|
||||
# f'textures: {SR1PartTexture.get_textures_from_type(part_type)}')
|
||||
part_data = SR1PartData(x=part_x, y=part_y, id=part_id, type_=part_type,
|
||||
return SR1PartData(x=part_x, y=part_y, id=part_id, type_=part_type,
|
||||
active=part_activate, angle=part_angle, angle_v=part_angle_v,
|
||||
editor_angle=part_editor_angle, flip_x=part_flip_x,
|
||||
flip_y=part_flip_y, explode=part_explode, textures=part_textures)
|
||||
return part_data
|
||||
|
||||
|
||||
class _SR1ShipRender_Option(Options):
|
||||
@ -125,7 +123,7 @@ class SR1ShipRender(BaseScreen):
|
||||
self.xml_doc = cache_doc
|
||||
self.xml_root = self.xml_doc.getroot()
|
||||
return True
|
||||
except:
|
||||
except Exception:
|
||||
return False
|
||||
|
||||
def load_textures(self):
|
||||
@ -234,7 +232,7 @@ class SR1ShipRender(BaseScreen):
|
||||
mouse_dx = x - (self.window_pointer.width / 2)
|
||||
mouse_dy = y - (self.window_pointer.height / 2)
|
||||
self.debug_mouse_line.x2, self.debug_mouse_line.y2 = x, y
|
||||
if not self.scale * (0.5 ** scroll_y) >= 10:
|
||||
if self.scale * (0.5**scroll_y) < 10:
|
||||
self.scale = self.scale * (0.5 ** scroll_y)
|
||||
self.dx += (mouse_dx - self.dx) * (1 - (0.5 ** scroll_y))
|
||||
self.dy += (mouse_dy - self.dy) * (1 - (0.5 ** scroll_y))
|
||||
|
@ -43,10 +43,12 @@ class DRDEBUGScreen(BaseScreen):
|
||||
|
||||
def update_label(self):
|
||||
now_FPS = get_frequency()
|
||||
self.fps_label.text = f'FPS: {self.window_pointer.fps_log.fps: >5.1f}(' \
|
||||
f'{self.window_pointer.fps_log.middle_fps: >5.1f})[{now_FPS: >.7f}]\n ' \
|
||||
f'{self.window_pointer.fps_log.max_fps: >7.1f} ' \
|
||||
self.fps_label.text = (
|
||||
f'FPS: {self.window_pointer.fps_log.fps: >5.1f}('
|
||||
f'{self.window_pointer.fps_log.middle_fps: >5.1f})[{now_FPS: >.7f}]\n '
|
||||
f'{self.window_pointer.fps_log.max_fps: >7.1f} '
|
||||
f'{self.window_pointer.fps_log.min_fps:>5.1f}'
|
||||
)
|
||||
|
||||
def on_resize(self, width, height):
|
||||
self.fps_label.y = height - 10
|
||||
|
@ -43,15 +43,10 @@ class CommandText:
|
||||
i += 1
|
||||
|
||||
def find(self, text: str) -> Union[str, bool]:
|
||||
finding = re.match(text, self.text)
|
||||
if finding:
|
||||
return finding.group()
|
||||
else:
|
||||
return False
|
||||
return finding.group() if (finding := re.match(text, self.text)) else False
|
||||
|
||||
def re_match(self, text: str) -> bool:
|
||||
finding = re.match(text, self.text)
|
||||
if finding: # 如果找到了
|
||||
if finding := re.match(text, self.text):
|
||||
try:
|
||||
next_find = self.text[finding.span()[1]]
|
||||
# 这里try因为可能匹配到的是字符串末尾
|
||||
@ -64,8 +59,6 @@ class CommandText:
|
||||
return True
|
||||
# 将匹配到的字符串,和最后一个匹配字符后面的字符删除(相当暴力的操作)
|
||||
return False
|
||||
else:
|
||||
return False
|
||||
|
||||
def int_value(self, name: Optional[str]):
|
||||
...
|
||||
|
@ -65,7 +65,7 @@ class CommandLine(widgets.WidgetBase):
|
||||
|
||||
# normal values
|
||||
self.length = length
|
||||
self._command_list = ['' for line in range(length)]
|
||||
self._command_list = ['' for _ in range(length)]
|
||||
self._command_text = command_text
|
||||
self._text_position = 0
|
||||
self._command_view = 0
|
||||
@ -249,7 +249,7 @@ class CommandLine(widgets.WidgetBase):
|
||||
|
||||
# view move motion
|
||||
elif motion == key.MOTION_DOWN:
|
||||
if not self.command_view == -1:
|
||||
if self.command_view != -1:
|
||||
self.command_view -= 1
|
||||
else:
|
||||
pass
|
||||
|
@ -65,8 +65,8 @@ def markdown_line_handler(string: Optional[str or bool or int or float], code: b
|
||||
lvl = '- ' * level
|
||||
f_string = string
|
||||
if code:
|
||||
f_string = '`{}`'.format(f_string)
|
||||
return '{}{}{}'.format(lvl, f_string, end)
|
||||
f_string = f'`{f_string}`'
|
||||
return f'{lvl}{f_string}{end}'
|
||||
|
||||
|
||||
def to_code(string: str):
|
||||
@ -89,9 +89,19 @@ def create_crash_report(info: str = None) -> None:
|
||||
if 'crash_report' not in os.listdir('./'):
|
||||
os.mkdir('./crash_report')
|
||||
date_time = time.strftime('%Y-%m-%d %H-%M-%S', time.gmtime(time.time()))
|
||||
filename = 'crash-{}.md'.format(date_time)
|
||||
filename = f'crash-{date_time}.md'
|
||||
cache_stream = io.StringIO()
|
||||
try:
|
||||
_extracted_from_create_crash_report_10(cache_stream, crash_info)
|
||||
finally:
|
||||
get_cache = cache_stream.getvalue()
|
||||
cache_stream.close()
|
||||
with open(f'./crash_report/{filename}', 'w+', encoding='utf-8') as crash_file:
|
||||
crash_file.write(get_cache)
|
||||
|
||||
|
||||
# TODO Rename this here and in `create_crash_report`
|
||||
def _extracted_from_create_crash_report_10(cache_stream, crash_info):
|
||||
# 开头信息
|
||||
cache_stream.write(Head_message.format(now_time=time.strftime('%Y/%m/%d %H:%M:%S', time.gmtime(time.time()))))
|
||||
# 崩溃信息
|
||||
@ -102,14 +112,16 @@ def create_crash_report(info: str = None) -> None:
|
||||
cache_stream.write(markdown_line_handler(f'DR Version: {Difficult_Rocket.game_version}', level=1))
|
||||
cache_stream.write(markdown_line_handler(f'DR language: {DR_runtime.language}', level=1))
|
||||
cache_stream.write(markdown_line_handler(f'Running Dir: {Path(os.curdir).resolve()}', level=1))
|
||||
option_with_len = DR_runtime.option_with_len()
|
||||
write_markdown_tablet(crash_file=cache_stream, tablet=option_with_len)
|
||||
# # DR 的游戏设置
|
||||
cache_stream.write(DR_configs)
|
||||
option_with_len = DR_option.option_with_len()
|
||||
write_markdown_tablet(crash_file=cache_stream, tablet=option_with_len)
|
||||
# 多进程信息
|
||||
cache_stream.write(Process_message)
|
||||
option_with_len = (
|
||||
_extracted_from__extracted_from_create_crash_report_10_19(
|
||||
DR_runtime, cache_stream, DR_configs
|
||||
)
|
||||
)
|
||||
option_with_len = (
|
||||
_extracted_from__extracted_from_create_crash_report_10_19(
|
||||
DR_option, cache_stream, Process_message
|
||||
)
|
||||
)
|
||||
for process in all_process:
|
||||
process: multiprocessing.Process
|
||||
cache_stream.write(markdown_line_handler(f'{process.name}', code=True))
|
||||
@ -138,11 +150,15 @@ def create_crash_report(info: str = None) -> None:
|
||||
cache_stream.write(markdown_line_handler(f'processor: {to_code(platform.processor())}', level=1))
|
||||
cache_stream.write(markdown_line_handler(f'release: {to_code(platform.release())}', level=1))
|
||||
cache_stream.write(markdown_line_handler(f'version: {to_code(platform.version())}', level=1))
|
||||
finally:
|
||||
get_cache = cache_stream.getvalue()
|
||||
cache_stream.close()
|
||||
with open('./crash_report/{}'.format(filename), 'w+', encoding='utf-8') as crash_file:
|
||||
crash_file.write(get_cache)
|
||||
|
||||
|
||||
# TODO Rename this here and in `create_crash_report`
|
||||
def _extracted_from__extracted_from_create_crash_report_10_19(arg0, cache_stream, arg2):
|
||||
result = arg0.option_with_len()
|
||||
write_markdown_tablet(crash_file=cache_stream, tablet=result)
|
||||
# # DR 的游戏设置
|
||||
cache_stream.write(arg2)
|
||||
return result
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
@ -59,10 +59,10 @@ class Game:
|
||||
self.server = server.Server(net_mode='local')
|
||||
|
||||
def python_version_check(self) -> None: # best 3.8+ and write at 3.8.10
|
||||
self.logger.info('{} {}'.format(tr['main']['version.now_on'], self.on_python_v))
|
||||
self.logger.info(f"{tr['main']['version.now_on']} {self.on_python_v}")
|
||||
if self.on_python_v_info[0] == 2:
|
||||
self.logger.critical('%s' % tr['main']['version.need3+'])
|
||||
raise SystemError('%s' % tr['main']['version.need3+'])
|
||||
self.logger.critical(f"{tr['main']['version.need3+']}")
|
||||
raise SystemError(f"{tr['main']['version.need3+']}")
|
||||
elif self.on_python_v_info[1] < 8:
|
||||
warning = tools.name_handler(tr['main']['version.best3.8+'])
|
||||
self.logger.warning(warning)
|
||||
@ -75,7 +75,7 @@ class Game:
|
||||
game_process = multiprocessing.Process(target=self.client.start(), name='pyglet app')
|
||||
game_process.start()
|
||||
game_process.join()
|
||||
except:
|
||||
except Exception:
|
||||
return -1
|
||||
else:
|
||||
return 1
|
||||
|
@ -1,6 +1,8 @@
|
||||
#!/usr/bin/env python
|
||||
"""Makes working with XML feel like you are working with JSON"""
|
||||
|
||||
|
||||
import contextlib
|
||||
try:
|
||||
from defusedexpat import pyexpat as expat
|
||||
except ImportError:
|
||||
@ -78,15 +80,16 @@ class _DictSAXHandler(object):
|
||||
return full_name
|
||||
namespace, name = full_name[:i], full_name[i+1:]
|
||||
short_namespace = self.namespaces.get(namespace, namespace)
|
||||
if not short_namespace:
|
||||
return name
|
||||
else:
|
||||
return self.namespace_separator.join((short_namespace, name))
|
||||
return (
|
||||
self.namespace_separator.join((short_namespace, name))
|
||||
if short_namespace
|
||||
else name
|
||||
)
|
||||
|
||||
def _attrs_to_dict(self, attrs):
|
||||
if isinstance(attrs, dict):
|
||||
return attrs
|
||||
return self.dict_constructor(zip(attrs[0::2], attrs[1::2]))
|
||||
return self.dict_constructor(zip(attrs[::2], attrs[1::2]))
|
||||
|
||||
def startNamespaceDecl(self, prefix, uri):
|
||||
self.namespace_declarations[prefix or ''] = uri
|
||||
@ -121,15 +124,21 @@ class _DictSAXHandler(object):
|
||||
if len(self.path) == self.item_depth:
|
||||
item = self.item
|
||||
if item is None:
|
||||
item = (None if not self.data
|
||||
else self.cdata_separator.join(self.data))
|
||||
item = self.cdata_separator.join(self.data) if self.data else None
|
||||
|
||||
should_continue = self.item_callback(self.path, item)
|
||||
if not should_continue:
|
||||
raise ParsingInterrupted()
|
||||
if len(self.stack):
|
||||
data = (None if not self.data
|
||||
else self.cdata_separator.join(self.data))
|
||||
self._extracted_from_endElement_13(name)
|
||||
else:
|
||||
self.item = None
|
||||
self.data = []
|
||||
self.path.pop()
|
||||
|
||||
# TODO Rename this here and in `endElement`
|
||||
def _extracted_from_endElement_13(self, name):
|
||||
data = self.cdata_separator.join(self.data) if self.data else None
|
||||
item = self.item
|
||||
self.item, self.data = self.stack.pop()
|
||||
if self.strip_whitespace and data:
|
||||
@ -142,10 +151,6 @@ class _DictSAXHandler(object):
|
||||
self.item = self.push_data(self.item, name, item)
|
||||
else:
|
||||
self.item = self.push_data(self.item, name, data)
|
||||
else:
|
||||
self.item = None
|
||||
self.data = []
|
||||
self.path.pop()
|
||||
|
||||
def characters(self, data):
|
||||
if not self.data:
|
||||
@ -168,10 +173,7 @@ class _DictSAXHandler(object):
|
||||
else:
|
||||
item[key] = [value, data]
|
||||
except KeyError:
|
||||
if self._should_force_list(key, data):
|
||||
item[key] = [data]
|
||||
else:
|
||||
item[key] = data
|
||||
item[key] = [data] if self._should_force_list(key, data) else data
|
||||
return item
|
||||
|
||||
def _should_force_list(self, key, value):
|
||||
@ -301,11 +303,8 @@ def parse(xml_input, encoding=None, expat=expat, process_namespaces=False,
|
||||
encoding,
|
||||
namespace_separator
|
||||
)
|
||||
try:
|
||||
with contextlib.suppress(AttributeError):
|
||||
parser.ordered_attributes = True
|
||||
except AttributeError:
|
||||
# Jython's expat does not support ordered_attributes
|
||||
pass
|
||||
parser.StartNamespaceDeclHandler = handler.startNamespaceDecl
|
||||
parser.StartElementHandler = handler.startElement
|
||||
parser.EndElementHandler = handler.endElement
|
||||
@ -338,9 +337,11 @@ def _process_namespace(name, namespaces, ns_sep=':', attr_prefix='@'):
|
||||
pass
|
||||
else:
|
||||
ns_res = namespaces.get(ns.strip(attr_prefix))
|
||||
name = '{}{}{}{}'.format(
|
||||
attr_prefix if ns.startswith(attr_prefix) else '',
|
||||
ns_res, ns_sep, name) if ns_res else name
|
||||
name = (
|
||||
f"{attr_prefix if ns.startswith(attr_prefix) else ''}{ns_res}{ns_sep}{name}"
|
||||
if ns_res
|
||||
else name
|
||||
)
|
||||
return name
|
||||
|
||||
|
||||
@ -361,9 +362,9 @@ def _emit(key, value, content_handler,
|
||||
if result is None:
|
||||
return
|
||||
key, value = result
|
||||
if (not hasattr(value, '__iter__')
|
||||
or isinstance(value, _basestring)
|
||||
or isinstance(value, dict)):
|
||||
if not hasattr(value, '__iter__') or isinstance(
|
||||
value, (_basestring, dict)
|
||||
):
|
||||
value = [value]
|
||||
for index, v in enumerate(value):
|
||||
if full_document and depth == 0 and index > 0:
|
||||
@ -371,10 +372,7 @@ def _emit(key, value, content_handler,
|
||||
if v is None:
|
||||
v = OrderedDict()
|
||||
elif isinstance(v, bool):
|
||||
if v:
|
||||
v = _unicode('true')
|
||||
else:
|
||||
v = _unicode('false')
|
||||
v = _unicode('true') if v else _unicode('false')
|
||||
elif not isinstance(v, dict):
|
||||
v = _unicode(v)
|
||||
if isinstance(v, _basestring):
|
||||
@ -391,7 +389,7 @@ def _emit(key, value, content_handler,
|
||||
attr_prefix)
|
||||
if ik == '@xmlns' and isinstance(iv, dict):
|
||||
for k, v in iv.items():
|
||||
attr = 'xmlns{}'.format(':{}'.format(k) if k else '')
|
||||
attr = f"xmlns{f':{k}' if k else ''}"
|
||||
attrs[attr] = _unicode(v)
|
||||
continue
|
||||
if not isinstance(iv, _unicode):
|
||||
@ -454,10 +452,8 @@ def unparse(input_dict, output=None, encoding='utf-8', full_document=True,
|
||||
content_handler.endDocument()
|
||||
if must_return:
|
||||
value = output.getvalue()
|
||||
try: # pragma no cover
|
||||
with contextlib.suppress(AttributeError):
|
||||
value = value.decode(encoding)
|
||||
except AttributeError: # pragma no cover
|
||||
pass
|
||||
return value
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user