diff --git a/.darglint b/.darglint deleted file mode 100644 index c4fc6e68d10b6fed7a780ce68d56bc2f7ed8e9e0..0000000000000000000000000000000000000000 --- a/.darglint +++ /dev/null @@ -1,6 +0,0 @@ -# SPDX-FileCopyrightText: 2022 Georg-August-Universität Göttingen -# -# SPDX-License-Identifier: CC0-1.0 - -[darglint] -docstring_style=google diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 3c4237794fcf61a28a264ce3d717bc7f69d399cc..9b36534da42c2e33769237c1bfe4d9e8510327cd 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -17,7 +17,7 @@ debian unit tests: image: python:$PYTHON_VERSION-$PLATFORM before_script: - if command -v apk; then apk add g++ icu-dev linux-headers; fi - - pip install .[dev] + - pip install .[ci] - mkdir -p cobertura htmlcov script: - coverage run -m pytest --junitxml=report.xml @@ -41,7 +41,7 @@ alpine unit test: image: python:$PYTHON_VERSION-$PLATFORM before_script: - if command -v apk; then apk add g++ icu-dev linux-headers; fi - - pip install .[dev] + - pip install .[ci] - mkdir -p cobertura htmlcov script: - coverage run -m pytest --junitxml=report.xml diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 6b02abe4685d98620a23fdacddf993f71209cb60..293f5f879d04498345c4c6af6e65e628a5375b74 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -24,6 +24,7 @@ repos: repo: https://github.com/commitizen-tools/commitizen rev: v3.27.0 - hooks: - - id: darglint - repo: https://github.com/terrencepreilly/darglint - rev: v1.8.1 + - id: pydoclint + args: [--config=pyproject.toml] + repo: https://github.com/jsh9/pydoclint + rev: 0.4.2 diff --git a/pyproject.toml b/pyproject.toml index 7fcf336eaa05549924bacaffff335231d82067ec..d747ea954b18dd32ab2ce53c3caf78dd9883576f 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -28,3 +28,9 @@ convention = "google" [tool.ruff.format] quote-style = "single" + +[tool.pydoclint] +style = 'google' +skip-checking-raises = true +allow-init-docstring = true +check-return-types = false # TODO: check auth.py zeep return types diff --git a/setup.cfg b/setup.cfg index c231f065fe26c442e85bd1755416965c23abeb6a..a64cffba77e0774ab951bc6a0f0d913bfeae1a88 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,11 +47,11 @@ install_requires = dev = commitizen coverage - darglint ipykernel ipywidgets pip-tools pre-commit + pydoclint pytest requests-mock reuse @@ -70,6 +70,15 @@ docs = sphinx-book-theme sphinx-rtd-theme +# here are duplicates from dev-profile for running in ci pipeline as we want to keep python min version +# lower than some dev tools (pydoclint) require. https://github.com/pypa/setuptools/issues/1260 seems +# hacky so we repeat entries for now (until dropping python 3.7 support) +ci = + coverage + pytest + requests-mock + testbook + [options.packages.find] where = src diff --git a/src/tgclients/aggregator.py b/src/tgclients/aggregator.py index 0166953024f2d9b7f534dca16fbd71a4368343a5..ffdf46854d76bdc9c9728fa0f1e2e4a1d265a79a 100644 --- a/src/tgclients/aggregator.py +++ b/src/tgclients/aggregator.py @@ -38,7 +38,7 @@ class Aggregator: https://textgridlab.org/doc/services/submodules/aggregator/docs/zip.html Args: - textgrid_uris (List[str] or str): a single or a list of TextGrid URIs + textgrid_uris (Union[str, List[str]]): a single or a list of TextGrid URIs sid (Optional[str], optional): Session ID. Defaults to None. Returns: @@ -58,13 +58,13 @@ class Aggregator: @overload def text(self, textgrid_uris: List[str], sid: Optional[str] = None) -> Response: ... - # python 3.10 allows writinh Union as | + # python 3.10 allows writing Union as | # https://www.blog.pythonlibrary.org/2021/09/11/python-3-10-simplifies-unions-in-type-annotations/ def text(self, textgrid_uris: Union[str, List[str]], sid: Optional[str] = None) -> Response: """Download aggregated TextGrid objects as plain text file. Args: - textgrid_uris (List[str] or str): a single or a list of TextGrid URIs + textgrid_uris (Union[str, List[str]]): a single or a list of TextGrid URIs sid (Optional[str], optional): Session ID. Defaults to None. Returns: @@ -90,7 +90,7 @@ class Aggregator: """Download aggregated TextGrid objects as TEI corpus. Args: - textgrid_uris (List[str] or str): a single or a list of TextGrid URIs + textgrid_uris (Union[str, List[str]]): a single or a list of TextGrid URIs sid (Optional[str], optional): Session ID. Defaults to None. Returns: @@ -141,7 +141,7 @@ class Aggregator: see https://textgridlab.org/doc/services/submodules/aggregator/docs/html.html Args: - textgrid_uris (List[str] or str): a single or a list of TextGrid URIs + textgrid_uris (Union[str, List[str]]): a single or a list of TextGrid URIs sid (Optional[str], optional): Session ID. Defaults to None. stylesheet_uri (Optional[str], optional): alternative XSLT stylesheet to use. Must be a TextGrid URI. diff --git a/src/tgclients/auth.py b/src/tgclients/auth.py index 64ac167691f53df41aada32851f1e2072618872b..86ed7fd6042031aa3b704d7fe741b5a5ae6dd4ea 100644 --- a/src/tgclients/auth.py +++ b/src/tgclients/auth.py @@ -68,7 +68,7 @@ class TextgridAuth: TextgridAuthException: in case of transport exceptions Returns: - List: A list of project id strings + List[str]: A list of project id strings """ try: return self._client.service.tgAssignedProjects(sid) @@ -85,7 +85,7 @@ class TextgridAuth: is not needed as this information can be reviewed publicly. Returns: - list: list of each project with ID, name and description + List[str]: list of each project with ID, name and description """ # sid is optional, so we pass empty sid return self._client.service.getAllProjects('') @@ -110,7 +110,7 @@ class TextgridAuth: sid (str): TextGrid Session ID name (str): name of the project description (str): description for the project - default_owner_roles (bool, optional): whether to assign the default roles to the owner + default_owner_roles (Optional[bool]): whether to assign the default roles to the owner (editor, authority to delete). Defaults to True. Raises: diff --git a/src/tgclients/crud.py b/src/tgclients/crud.py index 92200f2f2a2117a3b0f48400d6d06e7b3d803d6a..b23c58590f32ab86c59d7746ce172080ac2f4a32 100644 --- a/src/tgclients/crud.py +++ b/src/tgclients/crud.py @@ -6,7 +6,7 @@ import logging from io import BytesIO -from typing import Optional +from typing import Optional, Any, IO, Union import requests from bs4 import BeautifulSoup @@ -55,7 +55,7 @@ class TextgridCrudRequest: sid (Optional[str]): Session ID. Defaults to None. Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: Response: HTTP response from service @@ -77,7 +77,7 @@ class TextgridCrudRequest: sid (Optional[str]): Session ID. Defaults to None. Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: Response: HTTP response from service @@ -90,17 +90,19 @@ class TextgridCrudRequest: ) return self._handle_response(response) - def create_resource(self, sid: str, project_id: str, data, metadata) -> Response: + def create_resource( + self, sid: str, project_id: str, data: Union[str, IO[Any]], metadata: Union[str, IO[Any]] + ) -> Response: """Create a TextGrid object. Args: sid (str): Session ID project_id (str): Project ID - data ([type]): the data - metadata ([type]): the metadata + data (Union[str, IO[Any]]): the data + metadata (Union[str, IO[Any]]): the metadata Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: Response: HTTP response from service with metadata from newly created object @@ -117,7 +119,12 @@ class TextgridCrudRequest: return self._handle_response(response) def create_revision( - self, sid: str, project_id: str, textgrid_uri: str, data, metadata: str + self, + sid: str, + project_id: str, + textgrid_uri: str, + data: Union[str, IO[Any]], + metadata: Union[str, IO[Any]], ) -> Response: """Create a TextGrid object revision. @@ -125,11 +132,11 @@ class TextgridCrudRequest: sid (str): Session ID project_id (str): Project ID textgrid_uri (str): Textgrid URI - data ([type]): the data - metadata (str): the metadata + data (Union[str, IO[Any]]): the data + metadata (Union[str, IO[Any]]): the metadata Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: Response: HTTP response from service with metadata from newly created object revision @@ -151,19 +158,24 @@ class TextgridCrudRequest: return self._handle_response(response) def update_resource( - self, sid: str, textgrid_uri: str, data, metadata, create_revision: bool = False + self, + sid: str, + textgrid_uri: str, + data: Union[str, IO[Any]], + metadata: Union[str, IO[Any]], + create_revision: bool = False, ) -> Response: """Update a TextGrid object. Args: sid (str): Session ID textgrid_uri (str): Textgrid URI - data ([type]): the data - metadata ([type]): the metadata + data (Union[str, IO[Any]]): the data + metadata (Union[str, IO[Any]]): the metadata create_revision (bool): If `True`, create new textgrid object revision. Default: `False` Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: Response: HTTP response from service with updated metadata @@ -184,13 +196,15 @@ class TextgridCrudRequest: ) return self._handle_response(response) - def update_metadata(self, sid: str, textgrid_uri: str, metadata) -> Response: + def update_metadata( + self, sid: str, textgrid_uri: str, metadata: Union[str, IO[Any]] + ) -> Response: """Update metadata for TextGrid object. Args: sid (str): Session ID textgrid_uri (str): Textgrid URI - metadata ([type]): the metadata + metadata (Union[str, IO[Any]]): the metadata Returns: Response: HTTP response from service with updated metadata @@ -214,7 +228,7 @@ class TextgridCrudRequest: textgrid_uri (str): Textgrid URI Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: Response: HTTP response from service @@ -249,17 +263,17 @@ class TextgridCrudRequest: return response @staticmethod - def _error_msg_from_html(html: str): + def _error_msg_from_html(html: str) -> str: """Extract error message from html. The text string for the error is in <meta name="description" content="error message">. Args: - html: an error response body from tgcrud + html (str): an error response body from tgcrud Returns: - Response: the content of the meta[name=description] tag + str: the content of the meta[name=description] tag """ # soup = BeautifulSoup(html, 'html.parser') @@ -271,7 +285,9 @@ class TextgridCrudRequest: return msg @staticmethod - def _prepare_multipart(metadata, data=None): + def _prepare_multipart( + metadata: Union[str, IO[Any]], data: Union[str, IO[Any]] = None + ) -> MultipartEncoder: """Create a streaming multipart object. Monitor the upload progress if log level is DEBUG. @@ -279,11 +295,11 @@ class TextgridCrudRequest: See also: https://toolbelt.readthedocs.io/en/latest/uploading-data.html Args: - metadata ([type]): the metadata - data ([type]): the data + metadata (Union[str, IO[Any]]): the metadata + data (Union[str, IO[Any]]): the data Returns: - [MultipartEncoder]: Multipart containing data and metadata + MultipartEncoder: Multipart containing data and metadata """ fields = {'tgObjectMetadata': ('tgObjectMetadata', metadata, 'text/xml')} if data: @@ -320,18 +336,18 @@ class TextgridCrud(TextgridCrudRequest): super().__init__(config, for_publication) def create_resource( - self, sid: str, project_id: str, data, metadata: MetadataContainerType + self, sid: str, project_id: str, data: Union[str, IO[Any]], metadata: MetadataContainerType ) -> MetadataContainerType: """Create a TextGrid object. Args: sid (str): Session ID project_id (str): Project ID - data ([type]): the data + data (Union[str, IO[Any]]): the data metadata (MetadataContainerType): the metadata Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: MetadataContainerType: metadata for newly created object @@ -341,7 +357,12 @@ class TextgridCrud(TextgridCrudRequest): return self._parser.parse(BytesIO(response.content), MetadataContainerType) def create_revision( - self, sid: str, project_id: str, textgrid_uri: str, data, metadata: MetadataContainerType + self, + sid: str, + project_id: str, + textgrid_uri: str, + data: Union[str, IO[Any]], + metadata: MetadataContainerType, ) -> MetadataContainerType: """Create a TextGrid object revision. @@ -349,11 +370,11 @@ class TextgridCrud(TextgridCrudRequest): sid (str): Session ID project_id (str): Project ID textgrid_uri (str): Textgrid URI - data ([type]): the data + data (Union[str, IO[Any]]): the data metadata (MetadataContainerType): the metadata Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: MetadataContainerType: metadata from newly created object revision @@ -370,7 +391,7 @@ class TextgridCrud(TextgridCrudRequest): sid (Optional[str]): Session ID. Defaults to ''. Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: MetadataContainerType: metadata for object @@ -399,7 +420,7 @@ class TextgridCrud(TextgridCrudRequest): self, sid: str, textgrid_uri: str, - data, + data: Union[str, IO[Any]], metadata: MetadataContainerType, create_revision: bool = False, ) -> MetadataContainerType: @@ -408,12 +429,12 @@ class TextgridCrud(TextgridCrudRequest): Args: sid (str): Session ID textgrid_uri (str): Textgrid URI - data ([type]): the data + data (Union[str, IO[Any]]): the data metadata (MetadataContainerType): the metadata create_revision (bool): If `True`, create a new textgrid object revision. Default: `False` Raises: - TextgridCrudException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridCrudException: if HTTP status code >= 400 Returns: MetadataContainerType: updated metadata diff --git a/src/tgclients/metadata.py b/src/tgclients/metadata.py index 7f7da54abc3c8bd2b6a7375fac6ac9aa9a055de5..e71d92b26e9e52c4a32aea140ba78c873daba977 100644 --- a/src/tgclients/metadata.py +++ b/src/tgclients/metadata.py @@ -148,7 +148,7 @@ class TextgridMetadata: metadata format field (e.g. text/xml) Returns: - str: a filename extension + Optional[str]: a filename extension """ if mimetype in self._file_extension_map: return self._file_extension_map[mimetype][0] diff --git a/src/tgclients/search.py b/src/tgclients/search.py index 40ea32771ba64060d455b3f7f9ca627f9eb9e4c0..0e9f65eae0761b6c66776dab59c571fb46718f57 100644 --- a/src/tgclients/search.py +++ b/src/tgclients/search.py @@ -40,7 +40,7 @@ class TextgridSearchRequest: sid (Optional[str]): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: Response: metadata for uri @@ -61,7 +61,7 @@ class TextgridSearchRequest: sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: Response: HTTP response from service, containing a list of textgrid metadata entries @@ -81,7 +81,7 @@ class TextgridSearchRequest: sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: Response: HTTP response from service, containing a list of textgrid metadata entries @@ -118,33 +118,33 @@ class TextgridSearchRequest: http://textgridlab.org/doc/services/submodules/tg-search/docs/api/search.html Args: - query (str, optional): Lucene search string. Defaults to '*'. - sid (str, optional): TextGrid SessionID from tgauth. Defaults to None. - target (str, optional): where to do fulltext-searches: one of 'structure', + query (Optional[str]): Lucene search string. Defaults to '*'. + sid (Optional[str]): TextGrid SessionID from tgauth. Defaults to None. + target (Optional[str]): where to do fulltext-searches: one of 'structure', 'metadata' and 'both'. Defaults to 'both'. - order (str, optional): key-value ascending (asc) or descending (desc) and metadata-field + order (Optional[str]): key-value ascending (asc) or descending (desc) and metadata-field like asc:title or desc:author. Defaults to 'relevance'. - start (int, optional): result number to start with.. Defaults to 0. - limit (int, optional): number of entries to return.. Defaults to 20. - kwic_width (int, optional): number of chars before and after a kwic match. + start (Optional[int]): result number to start with.. Defaults to 0. + limit (Optional[int]): number of entries to return.. Defaults to 20. + kwic_width (Optional[int]): number of chars before and after a kwic match. Defaults to 40. - word_distance (int, optional): max distance beetween two words in fulltext query. + word_distance (Optional[int]): max distance beetween two words in fulltext query. ignored if set to a number < 0, then for a hit all words must be contained in one document. Defaults to -1. - path (boo], optional): path of found result(work->edition->aggregations) should be + path (Optional[bool]): path of found result(work->edition->aggregations) should be applied to hit. Defaults to false. - all_projects (bool, optional): all Projects should be searched for public data, + all_projects (Optional[bool]): all Projects should be searched for public data, warning: this query may be slow, if many results found. Defaults to false. - sandbox (bool, optional): show sandboxed (not yet finally published) data. + sandbox (Optional[bool]): show sandboxed (not yet finally published) data. Defaults to false. - filters (List[str], optional): add filter on query results, e.g. for faceting. + filters (Optional[List[str]]): add filter on query results, e.g. for faceting. Defaults to None. - facet (List[str], optional): get facets for query results. Defaults to None. - facet_limit (int, optional): number of results to return for each facet. Defaults to 10. + facet (Optional[List[str]]): get facets for query results. Defaults to None. + facet_limit (Optional[int]): number of results to return for each facet. Defaults to 10. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: Response: HTTP response from service - a list of textgrid metadata entries, @@ -181,7 +181,7 @@ class TextgridSearchRequest: sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: Response: HTTP response from service - edition and work metadata for given object @@ -202,7 +202,7 @@ class TextgridSearchRequest: sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: Response: HTTP response from service - URIs for children of this @@ -255,7 +255,7 @@ class TextgridSearch(TextgridSearchRequest): sid (Optional[str]): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: SearchResponse: metadata for uri @@ -273,7 +273,7 @@ class TextgridSearch(TextgridSearchRequest): sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: SearchResponse: A list of textgrid metadata entries @@ -289,7 +289,7 @@ class TextgridSearch(TextgridSearchRequest): sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: SearchResponse: A list of textgrid metadata entries @@ -323,33 +323,33 @@ class TextgridSearch(TextgridSearchRequest): http://textgridlab.org/doc/services/submodules/tg-search/docs/api/search.html Args: - query (str, optional): Lucene search string. Defaults to '*'. - sid (str, optional): TextGrid SessionID from tgauth. Defaults to None. - target (str, optional): where to do fulltext-searches: one of 'structure', + query (Optional[str]): Lucene search string. Defaults to '*'. + sid (Optional[str]): TextGrid SessionID from tgauth. Defaults to None. + target (Optional[str]): where to do fulltext-searches: one of 'structure', 'metadata' and 'both'. Defaults to 'both'. - order (str, optional): key-value ascending (asc) or descending (desc) and metadata-field + order (Optional[str]): key-value ascending (asc) or descending (desc) and metadata-field like asc:title or desc:author. Defaults to 'relevance'. - start (int, optional): result number to start with.. Defaults to 0. - limit (int, optional): number of entries to return.. Defaults to 20. - kwic_width (int, optional): number of chars before and after a kwic match. + start (Optional[int]): result number to start with.. Defaults to 0. + limit (Optional[int]): number of entries to return.. Defaults to 20. + kwic_width (Optional[int]): number of chars before and after a kwic match. Defaults to 40. - word_distance (int, optional): max distance beetween two words in fulltext query. + word_distance (Optional[int]): max distance beetween two words in fulltext query. ignored if set to a number < 0, then for a hit all words must be contained in one document. Defaults to -1. - path (boo], optional): path of found result(work->edition->aggregations) should be + path (Optional[bool]): path of found result(work->edition->aggregations) should be applied to hit. Defaults to false. - all_projects (bool, optional): all Projects should be searched for public data, + all_projects (Optional[bool]): all Projects should be searched for public data, warning: this query may be slow, if many results found. Defaults to false. - sandbox (bool, optional): show sandboxed (not yet finally published) data. + sandbox (Optional[bool]): show sandboxed (not yet finally published) data. Defaults to false. - filters (List[str], optional): add filter on query results, e.g. for faceting. + filters (Optional[List[str]]): add filter on query results, e.g. for faceting. Defaults to None. - facet (List[str], optional): get facets for query results. Defaults to None. - facet_limit (int, optional): number of results to return for each facet. Defaults to 10. + facet (Optional[List[str]]): get facets for query results. Defaults to None. + facet_limit (Optional[int]): number of results to return for each facet. Defaults to 10. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: SearchResponse: a list of textgrid metadata entries, @@ -385,7 +385,7 @@ class TextgridSearch(TextgridSearchRequest): sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: SearchResponse: Edition and work metadata for given object @@ -402,7 +402,7 @@ class TextgridSearch(TextgridSearchRequest): sid (Optional[str], optional): Session ID. Defaults to None. Raises: - TextgridSearchException: if HTTP status code >= 400 (# noqa: DAR402) + TextgridSearchException: if HTTP status code >= 400 Returns: TextgridUris: URIs for children of this aggregation and its child aggregations diff --git a/src/tgclients/utils.py b/src/tgclients/utils.py index c8795141ca3d2472badbce4e3bcf4908371aa90c..2101a3bcf94ccc30b725e22dd4ce09aa69375bbc 100644 --- a/src/tgclients/utils.py +++ b/src/tgclients/utils.py @@ -20,7 +20,7 @@ class Utils: Args: textgrid_uri (str): textgrid URI of the aggregation to create - members (list[str]): list of textgrid URIs inside aggregation + members (List[str]): list of textgrid URIs inside aggregation Returns: str: XML for TextGrid Aggregation @@ -39,7 +39,7 @@ class Utils: xml (str): TextGrid aggregation XML Returns: - list[str]: TextGrid URIs from aggregation + List[str]: TextGrid URIs from aggregation """ res = [] root = ET.fromstring(xml)