From 519e508e4826683b2af5e3ac6888b74794c1bf63 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Thu, 9 Nov 2023 19:02:13 +0800 Subject: [PATCH 01/12] Add type annotations and import typing module to xml.py --- minio/xml.py | 46 ++++++++++++++++++++++++++++++---------------- 1 file changed, 30 insertions(+), 16 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index b2727e01..171c8c78 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -16,17 +16,17 @@ """XML utility module.""" -from __future__ import absolute_import - +from __future__ import absolute_import, annotations +from typing import Type, TypeVar, Protocol import io from xml.etree import ElementTree as ET _S3_NAMESPACE = "http://s3.amazonaws.com/doc/2006-03-01/" -def Element(tag, namespace=_S3_NAMESPACE): # pylint: disable=invalid-name +def Element(tag: str, namespace=_S3_NAMESPACE): # pylint: disable=invalid-name """Create ElementTree.Element with tag and namespace.""" - return ET.Element(tag, {'xmlns': namespace} if namespace else {}) + return ET.Element(tag, {"xmlns": namespace} if namespace else {}) def SubElement(parent, tag, text=None): # pylint: disable=invalid-name @@ -37,7 +37,7 @@ def SubElement(parent, tag, text=None): # pylint: disable=invalid-name return element -def _get_namespace(element): +def _get_namespace(element: ET.Element): """Exact namespace if found.""" start = element.tag.find("{") if start < 0: @@ -49,7 +49,7 @@ def _get_namespace(element): return element.tag[start:end] -def findall(element, name): +def findall(element: ET.Element, name: str) -> list[ET.Element]: """Namespace aware ElementTree.Element.findall().""" namespace = _get_namespace(element) return element.findall( @@ -58,7 +58,7 @@ def findall(element, name): ) -def find(element, name): +def find(element: ET.Element, name: str): """Namespace aware ElementTree.Element.find().""" namespace = _get_namespace(element) return element.find( @@ -67,7 +67,7 @@ def find(element, name): ) -def findtext(element, name, strict=False): +def findtext(element: ET.Element, name: str, strict: bool = False) -> str | None: """ Namespace aware ElementTree.Element.findtext() with strict flag raises ValueError if element name not exist. @@ -80,20 +80,34 @@ def findtext(element, name, strict=False): return element.text or "" -def unmarshal(cls, xmlstring): +K = TypeVar("K") + + +class IFromXML(Protocol): + @classmethod + def fromxml(cls: Type[K], s: ET.Element) -> K: + ... + + +T = TypeVar("T", bound=IFromXML) + + +def unmarshal(cls: Type[T], xmlstring: str) -> T: """Unmarshal given XML string to an object of passed class.""" return cls.fromxml(ET.fromstring(xmlstring)) -def getbytes(element): +def getbytes(element) -> bytes: """Convert ElementTree.Element to bytes.""" - data = io.BytesIO() - ET.ElementTree(element).write( - data, encoding=None, xml_declaration=False, - ) - return data.getvalue() + with io.BytesIO() as data: + ET.ElementTree(element).write( + data, + encoding=None, + xml_declaration=False, + ) + return data.getvalue() -def marshal(obj): +def marshal(obj) -> bytes: """Get XML data as bytes of ElementTree.Element.""" return getbytes(obj.toxml(None)) From 5dd80fa566331a7078b4e9e071aa7c16be77e2d2 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Fri, 10 Nov 2023 00:02:38 +0800 Subject: [PATCH 02/12] type more --- minio/xml.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index 171c8c78..c60b067e 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -97,7 +97,7 @@ def unmarshal(cls: Type[T], xmlstring: str) -> T: return cls.fromxml(ET.fromstring(xmlstring)) -def getbytes(element) -> bytes: +def getbytes(element: ET.Element) -> bytes: """Convert ElementTree.Element to bytes.""" with io.BytesIO() as data: ET.ElementTree(element).write( @@ -108,6 +108,12 @@ def getbytes(element) -> bytes: return data.getvalue() -def marshal(obj) -> bytes: +class IToXML(Protocol): + @classmethod + def toxml(cls, s: ET.Element | None) -> ET.Element: + ... + + +def marshal(obj: IToXML) -> bytes: """Get XML data as bytes of ElementTree.Element.""" return getbytes(obj.toxml(None)) From 3e47c5b721d01811b263d42986287256f2bbe660 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:04:30 +0800 Subject: [PATCH 03/12] use typing-extensions for Protocol --- minio/xml.py | 4 +++- setup.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index c60b067e..13fb363a 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -17,10 +17,12 @@ """XML utility module.""" from __future__ import absolute_import, annotations -from typing import Type, TypeVar, Protocol +from typing import Type, TypeVar import io from xml.etree import ElementTree as ET +from typing_extensions import Protocol + _S3_NAMESPACE = "http://s3.amazonaws.com/doc/2006-03-01/" diff --git a/setup.py b/setup.py index 28b01e8e..9aca6e80 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,7 @@ long_description_content_type="text/markdown", package_dir={"minio": "minio"}, packages=["minio", "minio.credentials"], - install_requires=["certifi", "urllib3", "argon2-cffi", "pycryptodome"], + install_requires=["certifi", "urllib3", "argon2-cffi", "pycryptodome", "typing-extensions"], tests_require=[], license="Apache-2.0", classifiers=[ From 1518522ceb0fc75da643eafe7e850d31f0b81ce0 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:10:12 +0800 Subject: [PATCH 04/12] fix lint error --- minio/xml.py | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index 13fb363a..4bdcec7c 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -69,7 +69,11 @@ def find(element: ET.Element, name: str): ) -def findtext(element: ET.Element, name: str, strict: bool = False) -> str | None: +def findtext( + element: ET.Element, + name: str, + strict: bool = False, +) -> str | None: """ Namespace aware ElementTree.Element.findtext() with strict flag raises ValueError if element name not exist. @@ -86,9 +90,11 @@ def findtext(element: ET.Element, name: str, strict: bool = False) -> str | None class IFromXML(Protocol): + """typing stub for class with `fromxml` method""" + @classmethod - def fromxml(cls: Type[K], s: ET.Element) -> K: - ... + def fromxml(cls: Type[K], element: ET.Element) -> K: + """Create python object with values from XML element.""" T = TypeVar("T", bound=IFromXML) @@ -111,9 +117,10 @@ def getbytes(element: ET.Element) -> bytes: class IToXML(Protocol): - @classmethod - def toxml(cls, s: ET.Element | None) -> ET.Element: - ... + """typing stub for class with `toxml` method""" + + def toxml(self, element: ET.Element | None) -> ET.Element: + """Convert python object to ElementTree.Element.""" def marshal(obj: IToXML) -> bytes: From 3f9c62678d075fefc91d9a881808f8fa8f5c12f0 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:13:30 +0800 Subject: [PATCH 05/12] fix missing module --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index fc137565..47638e55 100644 --- a/Makefile +++ b/Makefile @@ -3,7 +3,7 @@ default: tests getdeps: @echo "Installing required dependencies" - @pip install --user --upgrade autopep8 certifi pytest pylint urllib3 argon2-cffi pycryptodome + @pip install --user --upgrade autopep8 certifi pytest pylint urllib3 argon2-cffi pycryptodome typing-extensions check: getdeps @echo "Running checks" From e56d5cbcbeba98bef0e85dfac089d731a4024366 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:17:19 +0800 Subject: [PATCH 06/12] fix lint --- setup.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 9aca6e80..4a888ffe 100644 --- a/setup.py +++ b/setup.py @@ -43,7 +43,8 @@ long_description_content_type="text/markdown", package_dir={"minio": "minio"}, packages=["minio", "minio.credentials"], - install_requires=["certifi", "urllib3", "argon2-cffi", "pycryptodome", "typing-extensions"], + install_requires=["certifi", "urllib3", "argon2-cffi", + "pycryptodome", "typing-extensions"], tests_require=[], license="Apache-2.0", classifiers=[ From 54d4de121ab9bc4f088bcb28e239e02a8ad7841e Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:20:28 +0800 Subject: [PATCH 07/12] fix lint error --- minio/xml.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/minio/xml.py b/minio/xml.py index 4bdcec7c..eba8fc2b 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -17,8 +17,9 @@ """XML utility module.""" from __future__ import absolute_import, annotations -from typing import Type, TypeVar + import io +from typing import Type, TypeVar from xml.etree import ElementTree as ET from typing_extensions import Protocol From c52846cc84971f2c295c3257a26896a761ad2ccd Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:22:02 +0800 Subject: [PATCH 08/12] typing --- minio/xml.py | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index eba8fc2b..c3cd5b36 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -27,12 +27,18 @@ _S3_NAMESPACE = "http://s3.amazonaws.com/doc/2006-03-01/" -def Element(tag: str, namespace=_S3_NAMESPACE): # pylint: disable=invalid-name +def Element( # pylint: disable=invalid-name + tag: str, + namespace: str = _S3_NAMESPACE +) -> ET.Element: """Create ElementTree.Element with tag and namespace.""" return ET.Element(tag, {"xmlns": namespace} if namespace else {}) -def SubElement(parent, tag, text=None): # pylint: disable=invalid-name +def SubElement( # pylint: disable=invalid-name + parent: ET.Element, tag: str, + text: str | None = None +) -> ET.Element: """Create ElementTree.SubElement on parent with tag and text.""" element = ET.SubElement(parent, tag) if text is not None: From 31645201ffba6d2be868597f543ccb5219cbb851 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Mon, 20 Nov 2023 23:24:44 +0800 Subject: [PATCH 09/12] more typing --- minio/xml.py | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index c3cd5b36..afa965ce 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -28,16 +28,15 @@ def Element( # pylint: disable=invalid-name - tag: str, - namespace: str = _S3_NAMESPACE + tag: str, + namespace: str = _S3_NAMESPACE, ) -> ET.Element: """Create ElementTree.Element with tag and namespace.""" return ET.Element(tag, {"xmlns": namespace} if namespace else {}) def SubElement( # pylint: disable=invalid-name - parent: ET.Element, tag: str, - text: str | None = None + parent: ET.Element, tag: str, text: str | None = None ) -> ET.Element: """Create ElementTree.SubElement on parent with tag and text.""" element = ET.SubElement(parent, tag) @@ -46,7 +45,7 @@ def SubElement( # pylint: disable=invalid-name return element -def _get_namespace(element: ET.Element): +def _get_namespace(element: ET.Element) -> str: """Exact namespace if found.""" start = element.tag.find("{") if start < 0: @@ -67,7 +66,7 @@ def findall(element: ET.Element, name: str) -> list[ET.Element]: ) -def find(element: ET.Element, name: str): +def find(element: ET.Element, name: str) -> ET.Element | None: """Namespace aware ElementTree.Element.find().""" namespace = _get_namespace(element) return element.find( @@ -77,9 +76,9 @@ def find(element: ET.Element, name: str): def findtext( - element: ET.Element, - name: str, - strict: bool = False, + element: ET.Element, + name: str, + strict: bool = False, ) -> str | None: """ Namespace aware ElementTree.Element.findtext() with strict flag From 2848f7e8871933e2f22dd7580dc5794794043036 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 21 Nov 2023 19:30:04 +0800 Subject: [PATCH 10/12] rename interface --- minio/xml.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index afa965ce..9106214f 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -95,7 +95,7 @@ def findtext( K = TypeVar("K") -class IFromXML(Protocol): +class InterfaceFromXML(Protocol): """typing stub for class with `fromxml` method""" @classmethod @@ -103,7 +103,7 @@ def fromxml(cls: Type[K], element: ET.Element) -> K: """Create python object with values from XML element.""" -T = TypeVar("T", bound=IFromXML) +T = TypeVar("T", bound=InterfaceFromXML) def unmarshal(cls: Type[T], xmlstring: str) -> T: @@ -122,13 +122,13 @@ def getbytes(element: ET.Element) -> bytes: return data.getvalue() -class IToXML(Protocol): +class InterfaceToXML(Protocol): """typing stub for class with `toxml` method""" def toxml(self, element: ET.Element | None) -> ET.Element: """Convert python object to ElementTree.Element.""" -def marshal(obj: IToXML) -> bytes: +def marshal(obj: InterfaceToXML) -> bytes: """Get XML data as bytes of ElementTree.Element.""" return getbytes(obj.toxml(None)) From a9e00d6c5c68602f74b6f990b17be84f978d2962 Mon Sep 17 00:00:00 2001 From: Trim21 Date: Tue, 21 Nov 2023 19:32:01 +0800 Subject: [PATCH 11/12] rename interface --- minio/xml.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/minio/xml.py b/minio/xml.py index 9106214f..14174353 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -95,7 +95,7 @@ def findtext( K = TypeVar("K") -class InterfaceFromXML(Protocol): +class FromXmlType(Protocol): """typing stub for class with `fromxml` method""" @classmethod @@ -103,7 +103,7 @@ def fromxml(cls: Type[K], element: ET.Element) -> K: """Create python object with values from XML element.""" -T = TypeVar("T", bound=InterfaceFromXML) +T = TypeVar("T", bound=FromXmlType) def unmarshal(cls: Type[T], xmlstring: str) -> T: @@ -122,13 +122,13 @@ def getbytes(element: ET.Element) -> bytes: return data.getvalue() -class InterfaceToXML(Protocol): +class ToXmlType(Protocol): """typing stub for class with `toxml` method""" def toxml(self, element: ET.Element | None) -> ET.Element: """Convert python object to ElementTree.Element.""" -def marshal(obj: InterfaceToXML) -> bytes: +def marshal(obj: ToXmlType) -> bytes: """Get XML data as bytes of ElementTree.Element.""" return getbytes(obj.toxml(None)) From 4a589926187bb7ceba7fd965d861be49cc0d972f Mon Sep 17 00:00:00 2001 From: Trim21 Date: Wed, 22 Nov 2023 11:10:08 +0800 Subject: [PATCH 12/12] Update minio/xml.py --- minio/xml.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/minio/xml.py b/minio/xml.py index 14174353..667f6e00 100644 --- a/minio/xml.py +++ b/minio/xml.py @@ -37,7 +37,7 @@ def Element( # pylint: disable=invalid-name def SubElement( # pylint: disable=invalid-name parent: ET.Element, tag: str, text: str | None = None -) -> ET.Element: +) -> ET.SubElement: """Create ElementTree.SubElement on parent with tag and text.""" element = ET.SubElement(parent, tag) if text is not None: