mirror of
https://github.com/galaxyproject/galaxy.git
synced 2026-09-01 15:37:32 +08:00
Merge pull request #13519 from jmchilton/no_implicit_optional
Disable implicit optional types.
This commit is contained in:
@@ -7,6 +7,7 @@ import os
|
||||
from typing import (
|
||||
Dict,
|
||||
List,
|
||||
Optional,
|
||||
Type,
|
||||
TypeVar,
|
||||
)
|
||||
@@ -526,7 +527,7 @@ class _UnflattenedMetadataDatasetAssociationSerializer(base.ModelSerializer[T],
|
||||
# because of that: we need to add a few keys that will use the default serializer
|
||||
self.serializable_keyset.update(["name", "state", "tool_version", "extension", "visible", "dbkey"])
|
||||
|
||||
def _proxy_to_dataset(self, serializer: base.Serializer = None, proxy_key=None):
|
||||
def _proxy_to_dataset(self, serializer: Optional[base.Serializer] = None, proxy_key: Optional[str] = None):
|
||||
# dataset associations are (rough) proxies to datasets - access their serializer using this remapping fn
|
||||
# remapping done by either kwarg key: IOW dataset attr key (e.g. uuid)
|
||||
# or by kwarg serializer: a function that's passed in (e.g. permissions)
|
||||
|
||||
@@ -8,6 +8,7 @@ galaxy-data.
|
||||
import os
|
||||
import shutil
|
||||
import tempfile
|
||||
from typing import Optional
|
||||
|
||||
from galaxy import (
|
||||
model,
|
||||
@@ -76,7 +77,7 @@ class GalaxyDataTestApp:
|
||||
model: GalaxyModelMapping
|
||||
security_agent: GalaxyRBACAgent
|
||||
|
||||
def __init__(self, config: GalaxyDataTestConfig = None, **kwd):
|
||||
def __init__(self, config: Optional[GalaxyDataTestConfig] = None, **kwd):
|
||||
config = config or GalaxyDataTestConfig(**kwd)
|
||||
self.config = config
|
||||
self.security = config.security
|
||||
|
||||
@@ -8,7 +8,10 @@ import shlex
|
||||
import shutil
|
||||
import sys
|
||||
import tempfile
|
||||
from typing import List
|
||||
from typing import (
|
||||
List,
|
||||
Optional,
|
||||
)
|
||||
|
||||
import packaging.version
|
||||
|
||||
@@ -305,7 +308,7 @@ class CondaContext(installable.InstallableContext):
|
||||
stdout_path = "/dev/null"
|
||||
return self.exec_command("clean", clean_args, stdout_path=stdout_path)
|
||||
|
||||
def exec_search(self, args: List[str], json: bool = False, offline: bool = False, platform: str = None):
|
||||
def exec_search(self, args: List[str], json: bool = False, offline: bool = False, platform: Optional[str] = None):
|
||||
"""
|
||||
Search conda channels for a package
|
||||
|
||||
@@ -513,7 +516,9 @@ def cleanup_failed_install(conda_target, conda_context=None):
|
||||
cleanup_failed_install_of_environment(conda_target.install_environment, conda_context=conda_context)
|
||||
|
||||
|
||||
def best_search_result(conda_target, conda_context: CondaContext, offline: bool = False, platform: str = None):
|
||||
def best_search_result(
|
||||
conda_target, conda_context: CondaContext, offline: bool = False, platform: Optional[str] = None
|
||||
):
|
||||
"""Find best "conda search" result for specified target.
|
||||
|
||||
Return ``None`` if no results match.
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
"""This module contains a linting functions for tool tests."""
|
||||
import typing
|
||||
from inspect import (
|
||||
Parameter,
|
||||
signature,
|
||||
@@ -118,12 +119,16 @@ def _check_asserts(test_idx, assertions, lint_ctx):
|
||||
if attrib not in assert_function_sig.parameters:
|
||||
lint_ctx.error(f"Test {test_idx}: unknown attribute '{attrib}' for '{a.tag}'", node=a)
|
||||
continue
|
||||
if assert_function_sig.parameters[attrib].annotation is not Parameter.empty:
|
||||
annotation = assert_function_sig.parameters[attrib].annotation
|
||||
annotation = _handle_optionals(annotation)
|
||||
if annotation is not Parameter.empty:
|
||||
try:
|
||||
assert_function_sig.parameters[attrib].annotation(a.attrib[attrib])
|
||||
annotation(a.attrib[attrib])
|
||||
except TypeError:
|
||||
raise Exception(f"Faild to instantiate {attrib} for {assert_function_name}")
|
||||
except ValueError:
|
||||
lint_ctx.error(
|
||||
f"Test {test_idx}: attribute '{attrib}' for '{a.tag}' needs to be '{assert_function_sig.parameters[attrib].annotation.__name__}' got '{a.attrib[attrib]}'",
|
||||
f"Test {test_idx}: attribute '{attrib}' for '{a.tag}' needs to be '{annotation.__name__}' got '{a.attrib[attrib]}'",
|
||||
node=a,
|
||||
)
|
||||
# check missing required attributes
|
||||
@@ -141,6 +146,13 @@ def _check_asserts(test_idx, assertions, lint_ctx):
|
||||
lint_ctx.error(f"Test {test_idx}: '{a.tag}' needs to specify 'n', 'min', or 'max'", node=a)
|
||||
|
||||
|
||||
def _handle_optionals(annotation):
|
||||
as_dict = annotation.__dict__
|
||||
if "__origin__" in as_dict and as_dict["__origin__"] == typing.Union:
|
||||
return as_dict["__args__"][0]
|
||||
return annotation
|
||||
|
||||
|
||||
def _collect_output_names(tool_xml):
|
||||
output_data_names = []
|
||||
output_collection_names = []
|
||||
|
||||
@@ -3,6 +3,7 @@ import re
|
||||
import tarfile
|
||||
import tempfile
|
||||
import zipfile
|
||||
from typing import Optional
|
||||
|
||||
from galaxy.util import asbool
|
||||
from ._util import _assert_presence_number
|
||||
@@ -55,10 +56,10 @@ def assert_has_archive_member(
|
||||
verify_assertions_function,
|
||||
children,
|
||||
all="false",
|
||||
n: int = None,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: int = None,
|
||||
max: int = None,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Recursively checks the specified children assertions against the text of
|
||||
|
||||
@@ -1,8 +1,15 @@
|
||||
from typing import Optional
|
||||
|
||||
from ._util import _assert_number
|
||||
|
||||
|
||||
def assert_has_size(
|
||||
output_bytes, value: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False
|
||||
output_bytes,
|
||||
value: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""
|
||||
Asserts the specified output has a size of the specified value,
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from ._util import _assert_number
|
||||
|
||||
@@ -18,7 +19,14 @@ def get_first_line(output, comment):
|
||||
|
||||
|
||||
def assert_has_n_columns(
|
||||
output, n: int = None, delta: int = 0, min: int = None, max: int = None, sep="\t", comment="", negate: bool = False
|
||||
output,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
sep="\t",
|
||||
comment="",
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts the tabular output contains n columns. The optional
|
||||
sep argument specifies the column seperator used to determine the
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from ._util import (
|
||||
_assert_number,
|
||||
@@ -7,7 +8,13 @@ from ._util import (
|
||||
|
||||
|
||||
def assert_has_text(
|
||||
output, text, n: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False
|
||||
output,
|
||||
text,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts specified output contains the substring specified by
|
||||
the argument text. The exact number of occurrences can be
|
||||
@@ -37,7 +44,13 @@ def assert_not_has_text(output, text):
|
||||
|
||||
|
||||
def assert_has_line(
|
||||
output, line, n: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False
|
||||
output,
|
||||
line,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts the specified output contains the line specified by the
|
||||
argument line. The exact number of occurrences can be optionally
|
||||
@@ -59,7 +72,14 @@ def assert_has_line(
|
||||
)
|
||||
|
||||
|
||||
def assert_has_n_lines(output, n: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False):
|
||||
def assert_has_n_lines(
|
||||
output,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts the specified output contains ``n`` lines allowing
|
||||
for a difference in the number of lines (delta)
|
||||
or relative differebce in the number of lines"""
|
||||
@@ -78,7 +98,13 @@ def assert_has_n_lines(output, n: int = None, delta: int = 0, min: int = None, m
|
||||
|
||||
|
||||
def assert_has_text_matching(
|
||||
output, expression, n: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False
|
||||
output,
|
||||
expression,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts the specified output contains text matching the
|
||||
regular expression specified by the argument expression.
|
||||
@@ -102,7 +128,13 @@ def assert_has_text_matching(
|
||||
|
||||
|
||||
def assert_has_line_matching(
|
||||
output, expression, n: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False
|
||||
output,
|
||||
expression,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts the specified output contains a line matching the
|
||||
regular expression specified by the argument expression. If n is given
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import re
|
||||
from typing import Optional
|
||||
|
||||
from lxml.etree import XMLSyntaxError
|
||||
|
||||
@@ -28,7 +29,13 @@ def assert_has_element_with_path(output, path, negate: bool = False):
|
||||
|
||||
|
||||
def assert_has_n_elements_with_path(
|
||||
output, path, n: int = None, delta: int = 0, min: int = None, max: int = None, negate: bool = False
|
||||
output,
|
||||
path,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""Asserts the specified output has exactly n elements matching the
|
||||
path specified."""
|
||||
@@ -74,10 +81,10 @@ def assert_xml_element(
|
||||
children=None,
|
||||
attribute=None,
|
||||
all=False,
|
||||
n: int = None,
|
||||
n: Optional[int] = None,
|
||||
delta: int = 0,
|
||||
min: int = None,
|
||||
max: int = None,
|
||||
min: Optional[int] = None,
|
||||
max: Optional[int] = None,
|
||||
negate: bool = False,
|
||||
):
|
||||
"""
|
||||
|
||||
@@ -11,6 +11,7 @@ import urllib.parse
|
||||
import zipfile
|
||||
from json import dumps
|
||||
from logging import getLogger
|
||||
from typing import Optional
|
||||
|
||||
import requests
|
||||
from packaging.version import parse as parse_version
|
||||
@@ -810,7 +811,12 @@ class GalaxyInteractorApi:
|
||||
return urllib.parse.urljoin(f"{self.api_url}/", path)
|
||||
|
||||
def _prepare_request_params(
|
||||
self, data=None, files=None, as_json: bool = False, params: dict = None, headers: dict = None
|
||||
self,
|
||||
data=None,
|
||||
files=None,
|
||||
as_json: bool = False,
|
||||
params: Optional[dict] = None,
|
||||
headers: Optional[dict] = None,
|
||||
):
|
||||
"""Handle some Galaxy conventions and work around requests issues.
|
||||
|
||||
|
||||
@@ -998,7 +998,9 @@ class HistoryContentsController(BaseGalaxyAPIController, UsesLibraryMixinItems,
|
||||
# return self.hda_manager.serialize_dataset_association_roles(trans, hda)
|
||||
|
||||
@expose_api
|
||||
def update_permissions(self, trans, history_id, history_content_id, payload: Dict[str, Any] = None, **kwd):
|
||||
def update_permissions(
|
||||
self, trans, history_id, history_content_id, payload: Optional[Dict[str, Any]] = None, **kwd
|
||||
):
|
||||
"""
|
||||
Set permissions of the given library dataset to the given role ids.
|
||||
|
||||
|
||||
@@ -303,7 +303,9 @@ class LibrariesController(BaseGalaxyAPIController):
|
||||
return self.service.update(trans, id, update_payload)
|
||||
|
||||
@expose_api
|
||||
def delete(self, trans: ProvidesUserContext, id: EncodedDatabaseIdField, payload: Dict[str, Any] = None, **kwd):
|
||||
def delete(
|
||||
self, trans: ProvidesUserContext, id: EncodedDatabaseIdField, payload: Optional[Dict[str, Any]] = None, **kwd
|
||||
):
|
||||
"""
|
||||
* DELETE /api/libraries/{id}
|
||||
marks the library with the given ``id`` as `deleted` (or removes the `deleted` mark if the `undelete` param is true)
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
from typing import List
|
||||
from typing import (
|
||||
List,
|
||||
Optional,
|
||||
)
|
||||
|
||||
from galaxy_test.base.populators import DatasetPopulator
|
||||
from ._framework import ApiTestCase
|
||||
@@ -9,7 +12,7 @@ class GroupRolesApiTestCase(ApiTestCase):
|
||||
super().setUp()
|
||||
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
|
||||
|
||||
def test_index(self, group_name: str = None):
|
||||
def test_index(self, group_name: Optional[str] = None):
|
||||
group_name = group_name or "test-group_roles"
|
||||
group = self._create_group(group_name)
|
||||
encoded_group_id = group["id"]
|
||||
@@ -109,7 +112,7 @@ class GroupRolesApiTestCase(ApiTestCase):
|
||||
delete_response = self._delete(f"groups/{encoded_group_id}/roles/{encoded_role_id}", admin=True)
|
||||
self._assert_status_code_is(delete_response, 400)
|
||||
|
||||
def _create_group(self, group_name: str, encoded_role_ids: List[str] = None):
|
||||
def _create_group(self, group_name: str, encoded_role_ids: Optional[List[str]] = None):
|
||||
if encoded_role_ids is None:
|
||||
encoded_role_ids = [self.dataset_populator.user_private_role_id()]
|
||||
role_ids = encoded_role_ids
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
from typing import List
|
||||
from typing import (
|
||||
List,
|
||||
Optional,
|
||||
)
|
||||
|
||||
from galaxy_test.base.populators import DatasetPopulator
|
||||
from ._framework import ApiTestCase
|
||||
@@ -9,7 +12,7 @@ class GroupUsersApiTestCase(ApiTestCase):
|
||||
super().setUp()
|
||||
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
|
||||
|
||||
def test_index(self, group_name: str = None):
|
||||
def test_index(self, group_name: Optional[str] = None):
|
||||
group_name = group_name or "test-group_users"
|
||||
group = self._create_group(group_name)
|
||||
encoded_group_id = group["id"]
|
||||
@@ -109,7 +112,7 @@ class GroupUsersApiTestCase(ApiTestCase):
|
||||
delete_response = self._delete(f"groups/{encoded_group_id}/users/{encoded_user_id}", admin=True)
|
||||
self._assert_status_code_is(delete_response, 400)
|
||||
|
||||
def _create_group(self, group_name: str, encoded_user_ids: List[str] = None):
|
||||
def _create_group(self, group_name: str, encoded_user_ids: Optional[List[str]] = None):
|
||||
if encoded_user_ids is None:
|
||||
encoded_user_ids = [self.dataset_populator.user_id()]
|
||||
user_ids = encoded_user_ids
|
||||
|
||||
@@ -1,3 +1,5 @@
|
||||
from typing import Optional
|
||||
|
||||
from galaxy_test.base.populators import DatasetPopulator
|
||||
from ._framework import ApiTestCase
|
||||
|
||||
@@ -7,7 +9,7 @@ class GroupsApiTestCase(ApiTestCase):
|
||||
super().setUp()
|
||||
self.dataset_populator = DatasetPopulator(self.galaxy_interactor)
|
||||
|
||||
def test_create_valid(self, group_name: str = None):
|
||||
def test_create_valid(self, group_name: Optional[str] = None):
|
||||
payload = self._build_valid_group_payload(group_name)
|
||||
response = self._post("groups", payload, admin=True, json=True)
|
||||
self._assert_status_code_is(response, 200)
|
||||
@@ -102,7 +104,7 @@ class GroupsApiTestCase(ApiTestCase):
|
||||
if assert_id is not None:
|
||||
assert group["id"] == assert_id
|
||||
|
||||
def _build_valid_group_payload(self, name: str = None):
|
||||
def _build_valid_group_payload(self, name: Optional[str] = None):
|
||||
name = name or self.dataset_populator.get_random_name()
|
||||
user_id = self.dataset_populator.user_id()
|
||||
role_id = self.dataset_populator.user_private_role_id()
|
||||
|
||||
@@ -19,6 +19,7 @@ check_untyped_defs = True
|
||||
exclude = lib/galaxy/tools/bundled|test/functional
|
||||
pretty = True
|
||||
no_implicit_reexport = True
|
||||
no_implicit_optional = True
|
||||
|
||||
[mypy-galaxy.util.oset]
|
||||
# lots of tricky code in here...
|
||||
@@ -221,7 +222,6 @@ disallow_untyped_defs = True
|
||||
disallow_incomplete_defs = True
|
||||
check_untyped_defs = True
|
||||
disallow_untyped_decorators = True
|
||||
no_implicit_optional = True
|
||||
warn_unused_ignores = True
|
||||
warn_return_any = True
|
||||
strict_equality = True
|
||||
|
||||
Reference in New Issue
Block a user