diff --git a/Convention/Runtime/Config.py b/Convention/Runtime/Config.py index 350ec47..60afa60 100644 --- a/Convention/Runtime/Config.py +++ b/Convention/Runtime/Config.py @@ -8,7 +8,7 @@ import datetime try: from colorama import Fore as ConsoleFrontColor, Back as ConsoleBackgroundColor, Style as ConsoleStyle except: - print("colorama is not installed, using default colors") + print("colorama is not installed") class ConsoleFrontColor: RED = "" GREEN = "" @@ -60,7 +60,7 @@ def GetInternalDebug() -> bool: global INTERNAL_DEBUG return INTERNAL_DEBUG -def print_colorful(color:str, *args, is_reset:bool=True, **kwargs): +def PrintColorful(color:str, *args, is_reset:bool=True, **kwargs): with lock_guard(): if is_reset: print(color,*args,ConsoleStyle.RESET_ALL, **kwargs) diff --git a/Convention/Runtime/EasySave.py b/Convention/Runtime/EasySave.py index 1134ba3..41b1b46 100644 --- a/Convention/Runtime/EasySave.py +++ b/Convention/Runtime/EasySave.py @@ -180,14 +180,14 @@ class ESReader(BaseModel): ''' #module_name, _, class_name = type_label.split(",")[0].strip().rpartition('.') #if GetInternalEasySaveDebug(): - # print_colorful(ConsoleFrontColor.YELLOW, f"Prase __type label: {ConsoleFrontColor.RESET}{type_label}"\ + # PrintColorful(ConsoleFrontColor.YELLOW, f"Prase __type label: {ConsoleFrontColor.RESET}{type_label}"\ # f"{ConsoleFrontColor.YELLOW}, module_name: {ConsoleFrontColor.RESET}{module_name}"\ # f"{ConsoleFrontColor.YELLOW}, class_name: {ConsoleFrontColor.RESET}{class_name}") #typen_to = try_to_type(class_name, module_name=module_name) or to_type(class_name) #return TypeManager.GetInstance().CreateOrGetRefType(typen_to) typen, assembly_name = ReadAssemblyTypen(type_label) if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"Prase __type label: {ConsoleFrontColor.RESET}{type_label}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"Prase __type label: {ConsoleFrontColor.RESET}{type_label}"\ f"{ConsoleFrontColor.YELLOW}, typen: {ConsoleFrontColor.RESET}{typen}"\ f"{ConsoleFrontColor.YELLOW}, assembly_name: {ConsoleFrontColor.RESET}{assembly_name}") return TypeManager.GetInstance().CreateOrGetRefType(typen) @@ -235,7 +235,7 @@ class ESReader(BaseModel): if rtype is None: raise ValueError(f"{ConsoleFrontColor.RED}当前层不包含类型信息: {ConsoleFrontColor.RESET}{LimitStringLength(str(layer), 100)}") if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"layer: {ConsoleFrontColor.RESET}{LimitStringLength(str(layer), 100)}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"layer: {ConsoleFrontColor.RESET}{LimitStringLength(str(layer), 100)}"\ f"{ConsoleFrontColor.YELLOW}, rtype: {ConsoleFrontColor.RESET}{rtype.ToString()}") # 处理值类型 @@ -278,7 +278,7 @@ class ESReader(BaseModel): else: rinstance = rtype.CreateInstance() if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"rinstance rtype target: {ConsoleFrontColor.RESET}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"rinstance rtype target: {ConsoleFrontColor.RESET}"\ f"{rtype.Print2Str(verbose=True, flags=RefTypeFlag.Field|RefTypeFlag.Instance|RefTypeFlag.Public)}") fields:List[FieldInfo] = self._GetFields(rtype) for field in fields: @@ -289,19 +289,19 @@ class ESReader(BaseModel): if field.FieldType == list and field.ValueType.IsGeneric: field_rtype = TypeManager.GetInstance().CreateOrGetRefType(ListIndictaor(field.ValueType.GenericArgs[0])) if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}List<"\ f"{field_rtype.GenericArgs[0]}>") elif field.FieldType == set and field.ValueType.IsGeneric: field_rtype = TypeManager.GetInstance().CreateOrGetRefType(SetIndictaor(field.ValueType.GenericArgs[0])) if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}Set<"\ f"{field_rtype.GenericArgs[0]}>") elif field.FieldType == tuple and field.ValueType.IsGeneric: field_rtype = TypeManager.GetInstance().CreateOrGetRefType(TupleIndictaor(field.ValueType.GenericArgs[0])) if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}Tuple<"\ f"{field_rtype.GenericArgs[0]}>") elif field.FieldType == dict and field.ValueType.IsGeneric: @@ -309,13 +309,13 @@ class ESReader(BaseModel): DictIndictaor(field.ValueType.GenericArgs[0], field.ValueType.GenericArgs[1]) ) if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}Dict<"\ f"{field_rtype.GenericArgs[0]}, {field_rtype.GenericArgs[1]}>") else: field_rtype = TypeManager.GetInstance().CreateOrGetRefType(field.FieldType) if GetInternalEasySaveDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ + PrintColorful(ConsoleFrontColor.YELLOW, f"field: {ConsoleFrontColor.RESET}{field.FieldName}"\ f"{ConsoleFrontColor.YELLOW}, field_rtype: {ConsoleFrontColor.RESET}{field_rtype.RealType}"\ f"<{field_rtype.GenericArgs}>") field.SetValue(rinstance, dfs(field_rtype, layer[field.FieldName])) diff --git a/Convention/Runtime/File.py b/Convention/Runtime/File.py index 1fa1ebe..87b1b56 100644 --- a/Convention/Runtime/File.py +++ b/Convention/Runtime/File.py @@ -1,10 +1,7 @@ from .Config import * import json import shutil -import pandas as pd import os -import sys -import pickle import zipfile import tarfile import base64 @@ -14,21 +11,6 @@ import datetime import stat from typing import * from pathlib import Path -try: - from pydub import AudioSegment -except ImportError as e: - ImportingThrow(e, "File", ["pydub"]) -try: - from PIL import Image, ImageFile -except ImportError as e: - ImportingThrow(e, "File", ["Pillow"]) -try: - from docx import Document - from docx.document import Document as DocumentObject -except ImportError as e: - ImportingThrow(e, "File", ["python-docx"]) - -from .String import Bytes2String def GetExtensionName(file:str): return os.path.splitext(file)[1][1:] @@ -67,8 +49,10 @@ class PermissionError(FileOperationError): """权限操作异常""" pass -from pydantic import BaseModel, GetCoreSchemaHandler, Field -from pydantic_core import core_schema +try: + from pydantic import BaseModel +except ImportError as e: + ImportingThrow(e, "File", ["pydantic"]) class ToolFile(BaseModel): OriginFullPath:str @@ -100,6 +84,10 @@ class ToolFile(BaseModel): # 而我们需要的是 "E:/dev/analyze" first = self.GetFullPath().replace('/','\\').strip('\\') second = str(other).replace('/','\\') + if first == "./": + return ToolFile(f"{second}") + elif first == "../": + first = ToolFile(f"{os.path.abspath(first)}").BackToParentDir() return ToolFile(f"{first}\\{second}") def __idiv__(self, other): temp = self.__or__(other) @@ -192,16 +180,32 @@ class ToolFile(BaseModel): with open(self.OriginFullPath, 'r', encoding=encoding) as f: json_data = json.load(f, **kwargs) return json_data - def LoadAsCsv(self) -> pd.DataFrame: + def LoadAsCsv(self) -> "pandas.DataFrame": + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) with open(self.OriginFullPath, 'r') as f: return pd.read_csv(f) - def LoadAsXml(self) -> pd.DataFrame: + def LoadAsXml(self) -> "pandas.DataFrame": + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) with open(self.OriginFullPath, 'r') as f: return pd.read_xml(f) - def LoadAsDataframe(self) -> pd.DataFrame: + def LoadAsDataframe(self) -> "pandas.DataFrame": + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) with open(self.OriginFullPath, 'r') as f: return pd.read_csv(f) - def LoadAsExcel(self) -> pd.DataFrame: + def LoadAsExcel(self) -> "pandas.DataFrame": + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) with open(self.OriginFullPath, 'r') as f: return pd.read_excel(f) def LoadAsBinary(self) -> bytes: @@ -211,18 +215,59 @@ class ToolFile(BaseModel): with open(self.OriginFullPath, 'r') as f: return f.read() def LoadAsWav(self): + try: + from pydub import AudioSegment + except ImportError as e: + ImportingThrow(e, "File", ["pydub"]) return AudioSegment.from_wav(self.OriginFullPath) def LoadAsAudio(self): + try: + from pydub import AudioSegment + except ImportError as e: + ImportingThrow(e, "File", ["pydub"]) return AudioSegment.from_file(self.OriginFullPath) - def LoadAsImage(self) -> ImageFile.ImageFile: + def LoadAsImage(self): + try: + from PIL import Image + except ImportError as e: + ImportingThrow(e, "File", ["Pillow"]) return Image.open(self.OriginFullPath) - def LoadAsDocx(self) -> DocumentObject: + def LoadAsDocx(self) -> "docx.document.Document": + ''' + try: + from docx import Document + from docx.document import Document as DocumentObject + except ImportError as e: + ImportingThrow(e, "File", ["python-docx"]) + ''' + try: + from docx import Document + from docx.document import Document as DocumentObject + except ImportError as e: + ImportingThrow(e, "File", ["python-docx"]) return Document(self.OriginFullPath) def LoadAsUnknown(self, suffix:str) -> Any: return self.LoadAsText() - def LoadAsModel(self, model:type[BaseModel]) -> BaseModel: + def LoadAsModel(self, model:type["BaseModel"]) -> "BaseModel": return model.model_validate(self.LoadAsJson()) + def ReadLines(self): + with open(self.OriginFullPath, 'r') as f: + while True: + line = f.readline() + if not line or line == '': + break + yield line + + async def ReadLinesAsync(self): + import aiofiles + async with aiofiles.open(self.OriginFullPath, 'r') as f: + while True: + line = await f.readline() + if not line or line == '': + break + yield line + def SaveAsJson(self, json_data): try: from pydantic import BaseModel @@ -234,16 +279,40 @@ class ToolFile(BaseModel): with open(self.OriginFullPath, 'w', encoding='utf-8') as f: json.dump(json_data, f, indent=4) return self - def SaveAsCsv(self, csv_data:pd.DataFrame): + def SaveAsCsv(self, csv_data:"pandas.DataFrame"): + ''' + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) + ''' csv_data.to_csv(self.OriginFullPath) return self - def SaveAsXml(self, xml_data:pd.DataFrame): + def SaveAsXml(self, xml_data:"pandas.DataFrame"): + ''' + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) + ''' xml_data.to_xml(self.OriginFullPath) return self - def SaveAsDataframe(self, dataframe_data:pd.DataFrame): + def SaveAsDataframe(self, dataframe_data:"pandas.DataFrame"): + ''' + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) + ''' dataframe_data.to_csv(self.OriginFullPath) return self - def SaveAsExcel(self, excel_data:pd.DataFrame): + def SaveAsExcel(self, excel_data:"pandas.DataFrame"): + ''' + try: + import pandas as pd + except ImportError as e: + ImportingThrow(e, "File", ["pandas"]) + ''' excel_data.to_excel(self.OriginFullPath, index=False) return self def SaveAsBinary(self, binary_data:bytes): @@ -254,13 +323,32 @@ class ToolFile(BaseModel): with open(self.OriginFullPath, 'w') as f: f.writelines(text_data) return self - def SaveAsAudio(self, audio_data:AudioSegment): + def SaveAsAudio(self, audio_data:"pydub.AudioSegment"): + ''' + try: + from pydub import AudioSegment + except ImportError as e: + ImportingThrow(e, "File", ["pydub"]) + ''' audio_data.export(self.OriginFullPath, format=self.get_extension(self.OriginFullPath)) return self - def SaveAsImage(self, image_data:ImageFile.ImageFile): + def SaveAsImage(self, image_data:"PIL.ImageFile.ImageFile"): + ''' + try: + from PIL import Image, ImageFile + except ImportError as e: + ImportingThrow(e, "File", ["Pillow"]) + ''' image_data.save(self.OriginFullPath) return self - def SaveAsDocx(self, docx_data:DocumentObject): + def SaveAsDocx(self, docx_data:"docx.document.Document"): + ''' +try: + from docx import Document + from docx.document import Document as DocumentObject +except ImportError as e: + ImportingThrow(e, "File", ["python-docx"]) + ''' docx_data.save(self.OriginFullPath) return self def SaveAsUnknown(self, unknown_data:Any): diff --git a/Convention/Runtime/Reflection.py b/Convention/Runtime/Reflection.py index 967c656..2fb2f28 100644 --- a/Convention/Runtime/Reflection.py +++ b/Convention/Runtime/Reflection.py @@ -241,7 +241,7 @@ def ToType( type_module = module_name or (".".join(type_components[:-1]) if len(type_components) > 1 else None) type_final = type_components[-1] if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"type_module: {type_module}, type_final: {type_final}, "\ + PrintColorful(ConsoleFrontColor.YELLOW, f"type_module: {type_module}, type_final: {type_final}, "\ f"typen: {typen}, type_components: {type_components}") if type_module is not None: return sys.modules[type_module].__dict__[type_final] @@ -304,7 +304,7 @@ def DecayType( return type_hint if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"Decay: {type_hint}") + PrintColorful(ConsoleFrontColor.YELLOW, f"Decay: {type_hint}") result: type|List[type] = None @@ -333,7 +333,7 @@ def DecayType( raise ReflectionException(f"Invalid type: {type_hint}<{type_hint.__class__}>") if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"Result: {result}") + PrintColorful(ConsoleFrontColor.YELLOW, f"Result: {result}") return result def IsJustDefinedInCurrentClass(member_name:str, current_class:type) -> bool: @@ -456,7 +456,7 @@ class ValueInfo(BaseInfo): super().__init__(**kwargs) self._RealType = metaType if GetInternalReflectionDebug() and len(generic_args) > 0: - print_colorful(ConsoleFrontColor.YELLOW, f"Current ValueInfo Debug Frame: "\ + PrintColorful(ConsoleFrontColor.YELLOW, f"Current ValueInfo Debug Frame: "\ f"metaType={metaType}, generic_args={generic_args}") self._GenericArgs = generic_args if not isinstance(metaType, type): @@ -546,7 +546,7 @@ class ValueInfo(BaseInfo): **kwargs ) -> 'ValueInfo': if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.BLUE, f"Current ValueInfo.Create Frame: "\ + PrintColorful(ConsoleFrontColor.BLUE, f"Current ValueInfo.Create Frame: "\ f"metaType={metaType}, SelfType={SelfType}") if isinstance(metaType, type): if metaType is list: @@ -601,7 +601,7 @@ class FieldInfo(MemberInfo): selfType: type|Any|None = None ): if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.LIGHTBLUE_EX, f"Current Make FieldInfo: {ctype}."\ + PrintColorful(ConsoleFrontColor.LIGHTBLUE_EX, f"Current Make FieldInfo: {ctype}."\ f"{ConsoleFrontColor.RESET}{name} {ConsoleFrontColor.LIGHTBLUE_EX}{metaType} ") super().__init__( name = name, @@ -611,7 +611,7 @@ class FieldInfo(MemberInfo): ) self._MetaType = ValueInfo.Create(metaType, module_name=module_name, SelfType=selfType) if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.LIGHTBLUE_EX, f"Current RealType: {self.FieldType}"\ + PrintColorful(ConsoleFrontColor.LIGHTBLUE_EX, f"Current RealType: {self.FieldType}"\ f"{f'<{self.ValueType.GenericArgs}>' if self.ValueType.IsGeneric else ''}") @property @@ -746,7 +746,7 @@ class MethodInfo(MemberInfo): is_class_method: bool, ): if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"Current Make MethodInfo: "\ + PrintColorful(ConsoleFrontColor.YELLOW, f"Current Make MethodInfo: "\ f"{return_type} {ctype}.{name}({', '.join([p.ParameterName for p in parameters])})") MemberInfo.__init__(self, name, ctype, is_static, is_public) self._ReturnType = ValueInfo.Create(return_type, SelfType=self.ParentType) @@ -1143,12 +1143,12 @@ class RefType(ValueInfo): def dfs(currentType:RefType) -> Dict[str, Dict[str, Any]|Any]: if currentType.IsPrimitive: if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.RED, f"Current Tree DFS(IsPrimitive): "\ + PrintColorful(ConsoleFrontColor.RED, f"Current Tree DFS(IsPrimitive): "\ f"__type={currentType.RealType} __type.class={currentType.RealType.__class__}") return f"{currentType.RealType}" elif currentType.RealType in type_set: if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.RED, f"Current Tree DFS(Already): "\ + PrintColorful(ConsoleFrontColor.RED, f"Current Tree DFS(Already): "\ f"__type={currentType.RealType} __type.class={currentType.RealType.__class__}") return { "type": f"{currentType.RealType}", @@ -1156,13 +1156,13 @@ class RefType(ValueInfo): } else: if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.RED, f"Current Tree DFS(New): "\ + PrintColorful(ConsoleFrontColor.RED, f"Current Tree DFS(New): "\ f"__type={currentType.RealType} __type.class={currentType.RealType.__class__}") type_set.add(currentType.RealType) value = {} fields = currentType.GetFields() if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.RED, f"Current Tree DFS(Fields): {[field.FieldName for field in fields]}") + PrintColorful(ConsoleFrontColor.RED, f"Current Tree DFS(Fields): {[field.FieldName for field in fields]}") for field in fields: value[field.FieldName] = dfs(TypeManager.GetInstance().CreateOrGetRefType(field.FieldType)) return { @@ -1429,7 +1429,7 @@ class TypeManager(BaseModel): if data is None: raise ReflectionException("data is None") if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"Try Get RefType: {ConsoleFrontColor.RESET}{data}") + PrintColorful(ConsoleFrontColor.YELLOW, f"Try Get RefType: {ConsoleFrontColor.RESET}{data}") # 快速路径:如果是字符串并且在字符串缓存中,直接返回对应的类型 if isinstance(data, str) and data in self._string_to_type_cache: @@ -1454,7 +1454,7 @@ class TypeManager(BaseModel): # 添加到弱引用缓存 self._weak_refs[type_id] = weakref.ref(ref_type) if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.YELLOW, f"Get "\ + PrintColorful(ConsoleFrontColor.YELLOW, f"Get "\ f"{ConsoleFrontColor.RESET}{metaType}{ConsoleFrontColor.YELLOW} RefType: "\ f"{ConsoleFrontColor.RESET}{ref_type.ToString()}") return ref_type @@ -1507,7 +1507,7 @@ class TypeManager(BaseModel): try: ref_type = RefType(metaType) if GetInternalReflectionDebug(): - print_colorful(ConsoleFrontColor.RED, f"Create "\ + PrintColorful(ConsoleFrontColor.RED, f"Create "\ f"{ConsoleFrontColor.RESET}{metaType} "\ f"{ConsoleFrontColor.RED}RefType: {ConsoleFrontColor.RESET}{ref_type.ToString()}") self._RefTypes[metaType] = ref_type