Return-Path: X-Original-To: archive-asf-public-internal@cust-asf2.ponee.io Delivered-To: archive-asf-public-internal@cust-asf2.ponee.io Received: from cust-asf.ponee.io (cust-asf.ponee.io [163.172.22.183]) by cust-asf2.ponee.io (Postfix) with ESMTP id 4EE9A200D0E for ; Mon, 11 Sep 2017 21:33:50 +0200 (CEST) Received: by cust-asf.ponee.io (Postfix) id 4D7271609C5; Mon, 11 Sep 2017 19:33:50 +0000 (UTC) Delivered-To: archive-asf-public@cust-asf.ponee.io Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by cust-asf.ponee.io (Postfix) with SMTP id 1D51F1609B7 for ; Mon, 11 Sep 2017 21:33:48 +0200 (CEST) Received: (qmail 36990 invoked by uid 500); 11 Sep 2017 19:33:47 -0000 Mailing-List: contact commits-help@ariatosca.incubator.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@ariatosca.incubator.apache.org Delivered-To: mailing list commits@ariatosca.incubator.apache.org Received: (qmail 36980 invoked by uid 99); 11 Sep 2017 19:33:47 -0000 Received: from pnap-us-west-generic-nat.apache.org (HELO spamd2-us-west.apache.org) (209.188.14.142) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 11 Sep 2017 19:33:47 +0000 Received: from localhost (localhost [127.0.0.1]) by spamd2-us-west.apache.org (ASF Mail Server at spamd2-us-west.apache.org) with ESMTP id 9778C1A65AB for ; Mon, 11 Sep 2017 19:33:46 +0000 (UTC) X-Virus-Scanned: Debian amavisd-new at spamd2-us-west.apache.org X-Spam-Flag: NO X-Spam-Score: -4.222 X-Spam-Level: X-Spam-Status: No, score=-4.222 tagged_above=-999 required=6.31 tests=[KAM_ASCII_DIVIDERS=0.8, RCVD_IN_DNSWL_HI=-5, RCVD_IN_MSPIKE_H3=-0.01, RCVD_IN_MSPIKE_WL=-0.01, RP_MATCHES_RCVD=-0.001, SPF_PASS=-0.001] autolearn=disabled Received: from mx1-lw-eu.apache.org ([10.40.0.8]) by localhost (spamd2-us-west.apache.org [10.40.0.9]) (amavisd-new, port 10024) with ESMTP id AuzoRqXL_kVw for ; Mon, 11 Sep 2017 19:33:40 +0000 (UTC) Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by mx1-lw-eu.apache.org (ASF Mail Server at mx1-lw-eu.apache.org) with SMTP id B90D660EF5 for ; Mon, 11 Sep 2017 19:33:38 +0000 (UTC) Received: (qmail 36774 invoked by uid 99); 11 Sep 2017 19:33:38 -0000 Received: from git1-us-west.apache.org (HELO git1-us-west.apache.org) (140.211.11.23) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 11 Sep 2017 19:33:38 +0000 Received: by git1-us-west.apache.org (ASF Mail Server at git1-us-west.apache.org, from userid 33) id 283FEF564D; Mon, 11 Sep 2017 19:33:36 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit From: emblemparade@apache.org To: commits@ariatosca.incubator.apache.org Date: Mon, 11 Sep 2017 19:33:46 -0000 Message-Id: <505d16ff1ab0462298c63998ceecbab9@git.apache.org> In-Reply-To: <5d92b90ac3e74ef48534afa1a573b75a@git.apache.org> References: <5d92b90ac3e74ef48534afa1a573b75a@git.apache.org> X-Mailer: ASF-Git Admin Mailer Subject: [12/14] incubator-ariatosca git commit: Use YAML C library archived-at: Mon, 11 Sep 2017 19:33:50 -0000 Use YAML C library Project: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/commit/195000ad Tree: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/tree/195000ad Diff: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/diff/195000ad Branch: refs/heads/ARIA-1-parser-test-suite Commit: 195000ad1390760189a85e2ae95d4d3451bbaf82 Parents: 39518ca Author: Tal Liron Authored: Thu Aug 31 18:20:03 2017 -0500 Committer: Tal Liron Committed: Mon Sep 11 13:58:30 2017 -0500 ---------------------------------------------------------------------- .travis.yml | 2 + appveyor.yml | 3 +- aria/parser/reading/yaml.py | 6 +- .../aria_extension_tosca/simple_v1_0/data.py | 16 +- .../templates/test_template_parameters.py | 275 ++++++++++++++----- .../simple_v1_0/templates/test_templates.py | 33 +-- tox.ini | 7 + 7 files changed, 248 insertions(+), 94 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/.travis.yml ---------------------------------------------------------------------- diff --git a/.travis.yml b/.travis.yml index 919c3b4..e57ddc9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,6 +48,8 @@ env: - PYTEST_PROCESSES=1 TOX_ENV=py26extensions - PYTEST_PROCESSES=1 TOX_ENV=py27ssh - PYTEST_PROCESSES=1 TOX_ENV=py26ssh + - PYTEST_PROCESSES=1 TOX_ENV=pylint_code + - PYTEST_PROCESSES=1 TOX_ENV=pylint_tests - PYTEST_PROCESSES=1 TOX_ENV=docs before_install: http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/appveyor.yml ---------------------------------------------------------------------- diff --git a/appveyor.yml b/appveyor.yml index a03b180..89e735a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -34,8 +34,7 @@ before_test: - virtualenv env - 'env\Scripts\activate.bat' - pip install tox + - tox --version test_script: - - pip --version - - tox --version - tox -e %TOX_ENV% http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/aria/parser/reading/yaml.py ---------------------------------------------------------------------- diff --git a/aria/parser/reading/yaml.py b/aria/parser/reading/yaml.py index f5eac43..0148d3a 100644 --- a/aria/parser/reading/yaml.py +++ b/aria/parser/reading/yaml.py @@ -82,7 +82,11 @@ class YamlReader(Reader): # see issue here: # https://bitbucket.org/ruamel/yaml/issues/61/roundtriploader-causes-exceptions-with #yaml_loader = yaml.RoundTripLoader(data) - yaml_loader = yaml.SafeLoader(data) + try: + # Faster C-based loader, might not be available on all platforms + yaml_loader = yaml.CSafeLoader(data) + except BaseException: + yaml_loader = yaml.SafeLoader(data) try: node = yaml_loader.get_single_node() locator = YamlLocator(self.loader.location, 0, 0) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/tests/extensions/aria_extension_tosca/simple_v1_0/data.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py index d428668..7310ed9 100644 --- a/tests/extensions/aria_extension_tosca/simple_v1_0/data.py +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/data.py @@ -30,13 +30,19 @@ TYPE_NAME_PLURAL = { 'policy': 'policies' } PRIMITIVE_TYPE_NAMES = ('string', 'integer', 'float', 'boolean') +PARAMETER_SECTION_NAMES = ('properties', 'attributes') TEMPLATE_NAMES = ('node', 'group', 'policy') -TEMPLATE_NAME_SECTION = { +TEMPLATE_NAME_SECTIONS = { 'node': 'node_templates', 'group': 'groups', 'policy': 'policies' } -PARAMETER_SECTION_NAMES = ('properties', 'attributes') +TEMPLATE_PARAMETER_SECTIONS = ( + ('node', 'properties'), + ('node', 'attributes'), + ('group', 'properties'), + ('policy', 'properties') +) PARAMETER_SECTIONS = ( ('artifact', 'properties'), ('data', 'properties'), @@ -83,10 +89,12 @@ STATUSES = ('supported', 'unsupported', 'experimental', 'deprecated') ENTRY_SCHEMA_VALUES = ( ('string', 'a string', 'another string'), ('integer', '1', '2'), - ('float', '1.1', '2.2') + ('float', '1.1', '2.2'), + ('MyType', '{my_field: a string}', '{}') ) ENTRY_SCHEMA_VALUES_BAD = ( ('string', 'a string', '1'), ('integer', '1', 'a string'), - ('float', '1.1', 'a string') + ('float', '1.1', 'a string'), + ('MyType', '{my_field1: a string}', 'a string') ) http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_template_parameters.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_template_parameters.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_template_parameters.py index 67731b3..48087d0 100644 --- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_template_parameters.py +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_template_parameters.py @@ -21,149 +21,296 @@ import pytest from .. import data +# Required properties + +@pytest.mark.skip(reason='fixed in ARIA-351') +@pytest.mark.parametrize('name', data.TEMPLATE_NAMES) +def test_template_property_required(parser, name): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +{{ name }}_types: + MyType: + properties: + my_property: + type: string +topology_template: + {{ section }}: + my_template: + type: MyType +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure() + + +@pytest.mark.parametrize('name', data.TEMPLATE_NAMES) +def test_template_property_not_required(parser, name): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +{{ name }}_types: + MyType: + properties: + my_property: + type: string + required: false +topology_template: + {{ section }}: + my_template: + type: MyType +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success() + + +@pytest.mark.parametrize('name', data.TEMPLATE_NAMES) +def test_template_property_required_with_default(parser, name): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +{{ name }}_types: + MyType: + properties: + my_property: + type: string + default: a string +topology_template: + {{ section }}: + my_template: + type: MyType +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success() + + # Entry schema -@pytest.mark.parametrize('section,values', itertools.product( - data.PARAMETER_SECTION_NAMES, - data.ENTRY_SCHEMA_VALUES -)) -def test_node_type_parameter_map(parser, section, values): +@pytest.mark.parametrize( + 'name,parameter_section,values', + ((s[0], s[1], v) + for s, v in itertools.product( + data.TEMPLATE_PARAMETER_SECTIONS, + data.ENTRY_SCHEMA_VALUES)) +) +def test_template_parameter_map(parser, name, parameter_section, values): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: + MyType: + properties: + my_field: + type: string + default: default value +{{ name }}_types: MyType: - {{ section }}: + {{ parameter_section }}: my_parameter: type: map entry_schema: {{ values[0] }} topology_template: - node_templates: + {{ section }}: my_template: type: MyType - {{ section }}: + {{ parameter_section }}: my_parameter: key1: {{ values[1] }} key2: {{ values[2] }} -""", dict(section=section, values=values)).assert_success() +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section, + values=values)).assert_success() -@pytest.mark.parametrize('section,values', itertools.product( - data.PARAMETER_SECTION_NAMES, - data.ENTRY_SCHEMA_VALUES_BAD -)) -def test_node_type_parameter_map_bad(parser, section, values): +@pytest.mark.parametrize( + 'name,parameter_section,values', + ((s[0], s[1], v) + for s, v in itertools.product( + data.TEMPLATE_PARAMETER_SECTIONS, + data.ENTRY_SCHEMA_VALUES_BAD)) +) +def test_template_parameter_map_bad(parser, name, parameter_section, values): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: MyType: - {{ section }}: + properties: + my_field: + type: string + default: default value +{{ name }}_types: + MyType: + {{ parameter_section }}: my_parameter: type: map entry_schema: {{ values[0] }} topology_template: - node_templates: + {{ section }}: my_template: type: MyType - {{ section }}: + {{ parameter_section }}: my_parameter: key1: {{ values[1] }} key2: {{ values[2] }} -""", dict(section=section, values=values)).assert_failure() +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section, + values=values)).assert_failure() + + +@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS) +def test_template_parameter_map_required_field(parser, name, parameter_section): + parser.parse_literal(""" +tosca_definitions_version: tosca_simple_yaml_1_0 +data_types: + MyType: + properties: + my_field: + type: string +{{ name }}_types: + MyType: + {{ parameter_section }}: + my_parameter: + type: map + entry_schema: MyType +topology_template: + {{ section }}: + my_template: + type: MyType + {{ parameter_section }}: + my_parameter: + key: {my_field: a value} +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], + parameter_section=parameter_section)).assert_success() -@pytest.mark.parametrize('section,values', itertools.product( - data.PARAMETER_SECTION_NAMES, - data.ENTRY_SCHEMA_VALUES -)) -def test_node_type_parameter_list(parser, section, values): +@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS) +def test_template_parameter_map_required_field_bad(parser, name, parameter_section): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: MyType: - {{ section }}: + properties: + my_field: + type: string +{{ name }}_types: + MyType: + {{ parameter_section }}: my_parameter: - type: list - entry_schema: {{ values[0] }} + type: map + entry_schema: MyType topology_template: - node_templates: + {{ section }}: my_template: type: MyType - {{ section }}: + {{ parameter_section }}: my_parameter: - - {{ values[1] }} - - {{ values[2] }} -""", dict(section=section, values=values)).assert_success() + key: {} +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], + parameter_section=parameter_section)).assert_failure() -@pytest.mark.parametrize('section,values', itertools.product( - data.PARAMETER_SECTION_NAMES, - data.ENTRY_SCHEMA_VALUES_BAD -)) -def test_node_type_parameter_list_bad(parser, section, values): +@pytest.mark.parametrize( + 'name,parameter_section,values', + ((s[0], s[1], v) + for s, v in itertools.product( + data.TEMPLATE_PARAMETER_SECTIONS, + data.ENTRY_SCHEMA_VALUES)) +) +def test_template_parameter_list(parser, name, parameter_section, values): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: + MyType: + properties: + my_field: + type: string + default: default value +{{ name }}_types: MyType: - {{ section }}: + {{ parameter_section }}: my_parameter: type: list entry_schema: {{ values[0] }} topology_template: - node_templates: + {{ section }}: my_template: type: MyType - {{ section }}: + {{ parameter_section }}: my_parameter: - {{ values[1] }} - {{ values[2] }} -""", dict(section=section, values=values)).assert_failure() +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section, + values=values)).assert_success() -# Required - -@pytest.mark.skip(reason='fixed in ARIA-351') -def test_node_type_property_required(parser): +@pytest.mark.parametrize( + 'name,parameter_section,values', + ((s[0], s[1], v) + for s, v in itertools.product( + data.TEMPLATE_PARAMETER_SECTIONS, + data.ENTRY_SCHEMA_VALUES_BAD)) +) +def test_template_parameter_list_bad(parser, name, parameter_section, values): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: MyType: properties: - my_property: + my_field: type: string + default: default value +{{ name }}_types: + MyType: + {{ parameter_section }}: + my_parameter: + type: list + entry_schema: {{ values[0] }} topology_template: - node_templates: + {{ section }}: my_template: type: MyType -""").assert_failure() + {{ parameter_section }}: + my_parameter: + - {{ values[1] }} + - {{ values[2] }} +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], parameter_section=parameter_section, + values=values)).assert_failure() -def test_node_type_property_not_required(parser): +@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS) +def test_template_parameter_list_required_field(parser, name, parameter_section): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: MyType: properties: - my_property: + my_field: type: string - required: false +{{ name }}_types: + MyType: + {{ parameter_section }}: + my_parameter: + type: list + entry_schema: MyType topology_template: - node_templates: + {{ section }}: my_template: type: MyType -""").assert_success() + {{ parameter_section }}: + my_parameter: + - {my_field: a value} +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], + parameter_section=parameter_section)).assert_success() -def test_node_type_property_required_with_default(parser): +@pytest.mark.parametrize('name,parameter_section', data.TEMPLATE_PARAMETER_SECTIONS) +def test_template_parameter_list_required_field_bad(parser, name, parameter_section): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -node_types: +data_types: MyType: properties: - my_property: + my_field: type: string - default: a string +{{ name }}_types: + MyType: + {{ parameter_section }}: + my_parameter: + type: list + entry_schema: MyType topology_template: - node_templates: + {{ section }}: my_template: type: MyType -""").assert_success() + {{ parameter_section }}: + my_parameter: + - {} +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name], + parameter_section=parameter_section)).assert_failure() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_templates.py ---------------------------------------------------------------------- diff --git a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_templates.py b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_templates.py index 98f06ca..bcd232a 100644 --- a/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_templates.py +++ b/tests/extensions/aria_extension_tosca/simple_v1_0/templates/test_templates.py @@ -31,7 +31,7 @@ topology_template: {{ value }} """, dict(value=value)).assert_failure() -def test_topology_template_emtpy(parser): +def test_topology_template_empty(parser): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 topology_template: {} @@ -47,7 +47,7 @@ def test_template_section_wrong_yaml_type(parser, name, value): tosca_definitions_version: tosca_simple_yaml_1_0 topology_template: {{ section }}: {{ value }} -""", dict(section=data.TEMPLATE_NAME_SECTION[name], value=value)).assert_failure() +""", dict(section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure() @pytest.mark.parametrize('name,value', itertools.product( @@ -61,7 +61,7 @@ topology_template: {{ section }}: my_template: type: {{ value }} -""", dict(section=data.TEMPLATE_NAME_SECTION[name], value=value)).assert_failure() +""", dict(section=data.TEMPLATE_NAME_SECTIONS[name], value=value)).assert_failure() # Common fields @@ -70,32 +70,18 @@ topology_template: def test_template_fields(parser, name): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 -topology_template: - {{ section }}: - my_template: - type: tosca.{{ plural }}.Root - description: a description -""", dict(section=data.TEMPLATE_NAME_SECTION[name], - plural=data.TYPE_NAME_PLURAL[name])).assert_success() - - -# Of types - -@pytest.mark.parametrize('name', data.TEMPLATE_NAMES) -def test_template_of_type(parser, name): - parser.parse_literal(""" -tosca_definitions_version: tosca_simple_yaml_1_0 {{ name }}_types: MyType: {} topology_template: {{ section }}: my_template: type: MyType -""", dict(name=name, section=data.TEMPLATE_NAME_SECTION[name])).assert_success() + description: a description +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success() @pytest.mark.parametrize('name', data.TEMPLATE_NAMES) -def test_template_of_type_unicode(parser, name): +def test_template_fields_unicode(parser, name): parser.parse_literal(""" tosca_definitions_version: tosca_simple_yaml_1_0 {{ name }}_types: @@ -104,7 +90,8 @@ topology_template: {{ section }}: 模板: type: 類型 -""", dict(name=name, section=data.TEMPLATE_NAME_SECTION[name])).assert_success() + description: 描述 +""", dict(name=name, section=data.TEMPLATE_NAME_SECTIONS[name])).assert_success() @pytest.mark.parametrize('name', data.TEMPLATE_NAMES) @@ -115,7 +102,7 @@ topology_template: {{ section }}: my_template: type: UnknownType -""", dict(section=data.TEMPLATE_NAME_SECTION[name])).assert_failure() +""", dict(section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure() @pytest.mark.parametrize('name', data.TEMPLATE_NAMES) @@ -126,4 +113,4 @@ topology_template: {{ section }}: my_template: type: null -""", dict(section=data.TEMPLATE_NAME_SECTION[name])).assert_failure() +""", dict(section=data.TEMPLATE_NAME_SECTIONS[name])).assert_failure() http://git-wip-us.apache.org/repos/asf/incubator-ariatosca/blob/195000ad/tox.ini ---------------------------------------------------------------------- diff --git a/tox.ini b/tox.ini index 7c11787..c061abe 100644 --- a/tox.ini +++ b/tox.ini @@ -13,8 +13,13 @@ [tox] envlist=py27,py26,py27e2e,py26e2e,py27extensions,py26extensions,py27ssh,py26ssh,pywin,pylint_code,pylint_tests,docs processes={env:PYTEST_PROCESSES:auto} +<<<<<<< HEAD py27={env:PY27:python2.7} py26={env:PY26:python2.6} +======= +py26={env:PY26:python2.6} +py27={env:PY27:python2.7} +>>>>>>> Use YAML C library [testenv] whitelist_externals= @@ -118,12 +123,14 @@ commands= [testenv:pylint_code] commands= pylint aria extensions/aria_extension_tosca \ + -j 0 \ --rcfile=aria/.pylintrc \ --disable=fixme,missing-docstring [testenv:pylint_tests] commands= pylint tests \ + -j 0 \ --rcfile=tests/.pylintrc \ --disable=fixme,missing-docstring