mirror of
https://github.com/ansible-collections/community.general.git
synced 2024-09-14 20:13:21 +02:00
New Plugins #8594 (#8595)
* Implement #8594
* Fix lint and BOTMETA entries.
* Fix BOTMETA
* Consolidate argument check, code simplification, and formatting. Remove test vars.
* Fix lint.
* retrigger checks
* Update plugins/plugin_utils/ansible_type.py
Co-authored-by: Felix Fontein <felix@fontein.de>
* Update plugins/test/ansible_type.py
Co-authored-by: Felix Fontein <felix@fontein.de>
---------
Co-authored-by: Felix Fontein <felix@fontein.de>
(cherry picked from commit 8990f97b45
)
Co-authored-by: Vladimir Botka <vbotka@gmail.com>
This commit is contained in:
parent
92dcf1e0b2
commit
086b4e4fb8
10 changed files with 847 additions and 0 deletions
6
.github/BOTMETA.yml
vendored
6
.github/BOTMETA.yml
vendored
|
@ -176,6 +176,8 @@ files:
|
||||||
maintainers: vbotka
|
maintainers: vbotka
|
||||||
$filters/replace_keys.py:
|
$filters/replace_keys.py:
|
||||||
maintainers: vbotka
|
maintainers: vbotka
|
||||||
|
$filters/reveal_ansible_type.py:
|
||||||
|
maintainers: vbotka
|
||||||
$filters/time.py:
|
$filters/time.py:
|
||||||
maintainers: resmo
|
maintainers: resmo
|
||||||
$filters/to_days.yml:
|
$filters/to_days.yml:
|
||||||
|
@ -1425,12 +1427,16 @@ files:
|
||||||
ignore: matze
|
ignore: matze
|
||||||
labels: zypper
|
labels: zypper
|
||||||
maintainers: $team_suse
|
maintainers: $team_suse
|
||||||
|
$plugin_utils/ansible_type.py:
|
||||||
|
maintainers: vbotka
|
||||||
$plugin_utils/keys_filter.py:
|
$plugin_utils/keys_filter.py:
|
||||||
maintainers: vbotka
|
maintainers: vbotka
|
||||||
$plugin_utils/unsafe.py:
|
$plugin_utils/unsafe.py:
|
||||||
maintainers: felixfontein
|
maintainers: felixfontein
|
||||||
$tests/a_module.py:
|
$tests/a_module.py:
|
||||||
maintainers: felixfontein
|
maintainers: felixfontein
|
||||||
|
$tests/ansible_type.py:
|
||||||
|
maintainers: vbotka
|
||||||
$tests/fqdn_valid.py:
|
$tests/fqdn_valid.py:
|
||||||
maintainers: vbotka
|
maintainers: vbotka
|
||||||
#########################
|
#########################
|
||||||
|
|
134
plugins/filter/reveal_ansible_type.py
Normal file
134
plugins/filter/reveal_ansible_type.py
Normal file
|
@ -0,0 +1,134 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
# Copyright (c) 2024 Vladimir Botka <vbotka@gmail.com>
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
name: reveal_ansible_type
|
||||||
|
short_description: Return input type
|
||||||
|
version_added: "9.2.0"
|
||||||
|
author: Vladimir Botka (@vbotka)
|
||||||
|
description: This filter returns input type.
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: Input data.
|
||||||
|
type: raw
|
||||||
|
required: true
|
||||||
|
alias:
|
||||||
|
description: Data type aliases.
|
||||||
|
default: {}
|
||||||
|
type: dictionary
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
# Substitution converts str to AnsibleUnicode
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
# String. AnsibleUnicode.
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
# result => AnsibleUnicode
|
||||||
|
|
||||||
|
# String. AnsibleUnicode alias str.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
# result => str
|
||||||
|
|
||||||
|
# List. All items are AnsibleUnicode.
|
||||||
|
data: ["a", "b", "c"]
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
# result => list[AnsibleUnicode]
|
||||||
|
|
||||||
|
# Dictionary. All keys are AnsibleUnicode. All values are AnsibleUnicode.
|
||||||
|
data: {"a": "foo", "b": "bar", "c": "baz"}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
# result => dict[AnsibleUnicode, AnsibleUnicode]
|
||||||
|
|
||||||
|
# No substitution and no alias. Type of strings is str
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
# String
|
||||||
|
result: '{{ "abc" | community.general.reveal_ansible_type }}'
|
||||||
|
# result => str
|
||||||
|
|
||||||
|
# Integer
|
||||||
|
result: '{{ 123 | community.general.reveal_ansible_type }}'
|
||||||
|
# result => int
|
||||||
|
|
||||||
|
# Float
|
||||||
|
result: '{{ 123.45 | community.general.reveal_ansible_type }}'
|
||||||
|
# result => float
|
||||||
|
|
||||||
|
# Boolean
|
||||||
|
result: '{{ true | community.general.reveal_ansible_type }}'
|
||||||
|
# result => bool
|
||||||
|
|
||||||
|
# List. All items are strings.
|
||||||
|
result: '{{ ["a", "b", "c"] | community.general.reveal_ansible_type }}'
|
||||||
|
# result => list[str]
|
||||||
|
|
||||||
|
# List of dictionaries.
|
||||||
|
result: '{{ [{"a": 1}, {"b": 2}] | community.general.reveal_ansible_type }}'
|
||||||
|
# result => list[dict]
|
||||||
|
|
||||||
|
# Dictionary. All keys are strings. All values are integers.
|
||||||
|
result: '{{ {"a": 1} | community.general.reveal_ansible_type }}'
|
||||||
|
# result => dict[str, int]
|
||||||
|
|
||||||
|
# Dictionary. All keys are strings. All values are integers.
|
||||||
|
result: '{{ {"a": 1, "b": 2} | community.general.reveal_ansible_type }}'
|
||||||
|
# result => dict[str, int]
|
||||||
|
|
||||||
|
# Type of strings is AnsibleUnicode or str
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
|
# Dictionary. The keys are integers or strings. All values are strings.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {1: 'a', 'b': 'b'}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
# result => dict[int|str, str]
|
||||||
|
|
||||||
|
# Dictionary. All keys are integers. All values are keys.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {1: 'a', 2: 'b'}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
# result => dict[int, str]
|
||||||
|
|
||||||
|
# Dictionary. All keys are strings. Multiple types values.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {'a': 1, 'b': 1.1, 'c': 'abc', 'd': True, 'e': ['x', 'y', 'z'], 'f': {'x': 1, 'y': 2}}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
# result => dict[str, bool|dict|float|int|list|str]
|
||||||
|
|
||||||
|
# List. Multiple types items.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: [1, 2, 1.1, 'abc', True, ['x', 'y', 'z'], {'x': 1, 'y': 2}]
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
# result => list[bool|dict|float|int|list|str]
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
_value:
|
||||||
|
description: Type of the data.
|
||||||
|
type: str
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible_collections.community.general.plugins.plugin_utils.ansible_type import _ansible_type
|
||||||
|
|
||||||
|
|
||||||
|
def reveal_ansible_type(data, alias=None):
|
||||||
|
"""Returns data type"""
|
||||||
|
|
||||||
|
return _ansible_type(data, alias)
|
||||||
|
|
||||||
|
|
||||||
|
class FilterModule(object):
|
||||||
|
|
||||||
|
def filters(self):
|
||||||
|
return {
|
||||||
|
'reveal_ansible_type': reveal_ansible_type
|
||||||
|
}
|
47
plugins/plugin_utils/ansible_type.py
Normal file
47
plugins/plugin_utils/ansible_type.py
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
# Copyright (c) 2024 Vladimir Botka <vbotka@gmail.com>
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleFilterError
|
||||||
|
from ansible.module_utils.common._collections_compat import Mapping
|
||||||
|
|
||||||
|
|
||||||
|
def _atype(data, alias):
|
||||||
|
"""
|
||||||
|
Returns the name of the type class.
|
||||||
|
"""
|
||||||
|
|
||||||
|
data_type = type(data).__name__
|
||||||
|
return alias.get(data_type, data_type)
|
||||||
|
|
||||||
|
|
||||||
|
def _ansible_type(data, alias):
|
||||||
|
"""
|
||||||
|
Returns the Ansible data type.
|
||||||
|
"""
|
||||||
|
|
||||||
|
if alias is None:
|
||||||
|
alias = {}
|
||||||
|
|
||||||
|
if not isinstance(alias, Mapping):
|
||||||
|
msg = "The argument alias must be a dictionary. %s is %s"
|
||||||
|
raise AnsibleFilterError(msg % (alias, type(alias)))
|
||||||
|
|
||||||
|
data_type = _atype(data, alias)
|
||||||
|
|
||||||
|
if data_type == 'list' and len(data) > 0:
|
||||||
|
items = [_atype(i, alias) for i in data]
|
||||||
|
items_type = '|'.join(sorted(set(items)))
|
||||||
|
return ''.join((data_type, '[', items_type, ']'))
|
||||||
|
|
||||||
|
if data_type == 'dict' and len(data) > 0:
|
||||||
|
keys = [_atype(i, alias) for i in data.keys()]
|
||||||
|
vals = [_atype(i, alias) for i in data.values()]
|
||||||
|
keys_type = '|'.join(sorted(set(keys)))
|
||||||
|
vals_type = '|'.join(sorted(set(vals)))
|
||||||
|
return ''.join((data_type, '[', keys_type, ', ', vals_type, ']'))
|
||||||
|
|
||||||
|
return data_type
|
203
plugins/test/ansible_type.py
Normal file
203
plugins/test/ansible_type.py
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
# Copyright (c) 2024 Vladimir Botka <vbotka@gmail.com>
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
from __future__ import (absolute_import, division, print_function)
|
||||||
|
__metaclass__ = type
|
||||||
|
|
||||||
|
DOCUMENTATION = '''
|
||||||
|
name: ansible_type
|
||||||
|
short_description: Validate input type
|
||||||
|
version_added: "9.2.0"
|
||||||
|
author: Vladimir Botka (@vbotka)
|
||||||
|
description: This test validates input type.
|
||||||
|
options:
|
||||||
|
_input:
|
||||||
|
description: Input data.
|
||||||
|
type: raw
|
||||||
|
required: true
|
||||||
|
dtype:
|
||||||
|
description: A single data type, or a data types list to be validated.
|
||||||
|
type: raw
|
||||||
|
required: true
|
||||||
|
alias:
|
||||||
|
description: Data type aliases.
|
||||||
|
default: {}
|
||||||
|
type: dictionary
|
||||||
|
'''
|
||||||
|
|
||||||
|
EXAMPLES = '''
|
||||||
|
|
||||||
|
# Substitution converts str to AnsibleUnicode
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
# String. AnsibleUnicode.
|
||||||
|
dtype: AnsibleUnicode
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# String. AnsibleUnicode alias str.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
dtype: str
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# List. All items are AnsibleUnicode.
|
||||||
|
dtype: list[AnsibleUnicode]
|
||||||
|
data: ["a", "b", "c"]
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Dictionary. All keys are AnsibleUnicode. All values are AnsibleUnicode.
|
||||||
|
dtype: dict[AnsibleUnicode, AnsibleUnicode]
|
||||||
|
data: {"a": "foo", "b": "bar", "c": "baz"}
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# No substitution and no alias. Type of strings is str
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
# String
|
||||||
|
dtype: str
|
||||||
|
result: '{{ "abc" is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Integer
|
||||||
|
dtype: int
|
||||||
|
result: '{{ 123 is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Float
|
||||||
|
dtype: float
|
||||||
|
result: '{{ 123.45 is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Boolean
|
||||||
|
dtype: bool
|
||||||
|
result: '{{ true is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# List. All items are strings.
|
||||||
|
dtype: list[str]
|
||||||
|
result: '{{ ["a", "b", "c"] is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# List of dictionaries.
|
||||||
|
dtype: list[dict]
|
||||||
|
result: '{{ [{"a": 1}, {"b": 2}] is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Dictionary. All keys are strings. All values are integers.
|
||||||
|
dtype: dict[str, int]
|
||||||
|
result: '{{ {"a": 1} is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Dictionary. All keys are strings. All values are integers.
|
||||||
|
dtype: dict[str, int]
|
||||||
|
result: '{{ {"a": 1, "b": 2} is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Type of strings is AnsibleUnicode or str
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
|
# Dictionary. The keys are integers or strings. All values are strings.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
dtype: dict[int|str, str]
|
||||||
|
data: {1: 'a', 'b': 'b'}
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Dictionary. All keys are integers. All values are keys.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
dtype: dict[int, str]
|
||||||
|
data: {1: 'a', 2: 'b'}
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Dictionary. All keys are strings. Multiple types values.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
dtype: dict[str, bool|dict|float|int|list|str]
|
||||||
|
data: {'a': 1, 'b': 1.1, 'c': 'abc', 'd': True, 'e': ['x', 'y', 'z'], 'f': {'x': 1, 'y': 2}}
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# List. Multiple types items.
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
dtype: list[bool|dict|float|int|list|str]
|
||||||
|
data: [1, 2, 1.1, 'abc', True, ['x', 'y', 'z'], {'x': 1, 'y': 2}]
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Option dtype is list
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
# AnsibleUnicode or str
|
||||||
|
dtype: ['AnsibleUnicode', 'str']
|
||||||
|
data: abc
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# float or int
|
||||||
|
dtype: ['float', 'int']
|
||||||
|
data: 123
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# float or int
|
||||||
|
dtype: ['float', 'int']
|
||||||
|
data: 123.45
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# Multiple alias
|
||||||
|
# --------------
|
||||||
|
|
||||||
|
# int alias number
|
||||||
|
alias: {"int": "number", "float": "number"}
|
||||||
|
dtype: number
|
||||||
|
data: 123
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
|
||||||
|
# float alias number
|
||||||
|
alias: {"int": "number", "float": "number"}
|
||||||
|
dtype: number
|
||||||
|
data: 123.45
|
||||||
|
result: '{{ data is community.general.ansible_type(dtype, alias) }}'
|
||||||
|
# result => true
|
||||||
|
'''
|
||||||
|
|
||||||
|
RETURN = '''
|
||||||
|
_value:
|
||||||
|
description: Whether the data type is valid.
|
||||||
|
type: bool
|
||||||
|
'''
|
||||||
|
|
||||||
|
from ansible.errors import AnsibleFilterError
|
||||||
|
from ansible.module_utils.common._collections_compat import Sequence
|
||||||
|
from ansible_collections.community.general.plugins.plugin_utils.ansible_type import _ansible_type
|
||||||
|
|
||||||
|
|
||||||
|
def ansible_type(data, dtype, alias=None):
|
||||||
|
"""Validates data type"""
|
||||||
|
|
||||||
|
if not isinstance(dtype, Sequence):
|
||||||
|
msg = "The argument dtype must be a string or a list. dtype is %s."
|
||||||
|
raise AnsibleFilterError(msg % (dtype, type(dtype)))
|
||||||
|
|
||||||
|
if isinstance(dtype, str):
|
||||||
|
data_types = [dtype]
|
||||||
|
else:
|
||||||
|
data_types = dtype
|
||||||
|
|
||||||
|
return _ansible_type(data, alias) in data_types
|
||||||
|
|
||||||
|
|
||||||
|
class TestModule(object):
|
||||||
|
|
||||||
|
def tests(self):
|
||||||
|
return {
|
||||||
|
'ansible_type': ansible_type
|
||||||
|
}
|
|
@ -0,0 +1,5 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
azp/posix/2
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
- name: Integration tests
|
||||||
|
import_tasks: tasks.yml
|
|
@ -0,0 +1,185 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
# Substitution converts str to AnsibleUnicode
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
- name: String. AnsibleUnicode.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: 'AnsibleUnicode'
|
||||||
|
|
||||||
|
- name: String. AnsibleUnicode alias str.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: 'str'
|
||||||
|
|
||||||
|
- name: List. All items are AnsibleUnicode.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '["a", "b", "c"] is {{ dtype }}'
|
||||||
|
fail_msg: '["a", "b", "c"] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: ["a", "b", "c"]
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: 'list[AnsibleUnicode]'
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are AnsibleUnicode. All values are AnsibleUnicode.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '{"a": "foo", "b": "bar", "c": "baz"} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": "foo", "b": "bar", "c": "baz"} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: {"a": "foo", "b": "bar", "c": "baz"}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: 'dict[AnsibleUnicode, AnsibleUnicode]'
|
||||||
|
|
||||||
|
# No substitution and no alias. Type of strings is str
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
- name: String
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ "abc" | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: str
|
||||||
|
|
||||||
|
- name: Integer
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '123 is {{ dtype }}'
|
||||||
|
fail_msg: '123 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ 123 | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: int
|
||||||
|
|
||||||
|
- name: Float
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '123.45 is {{ dtype }}'
|
||||||
|
fail_msg: '123.45 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ 123.45 | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: float
|
||||||
|
|
||||||
|
- name: Boolean
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: 'true is {{ dtype }}'
|
||||||
|
fail_msg: 'true is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ true | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: bool
|
||||||
|
|
||||||
|
- name: List. All items are strings.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '["a", "b", "c"] is {{ dtype }}'
|
||||||
|
fail_msg: '["a", "b", "c"] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ ["a", "b", "c"] | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: list[str]
|
||||||
|
|
||||||
|
- name: List of dictionaries.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '[{"a": 1}, {"b": 2}] is {{ dtype }}'
|
||||||
|
fail_msg: '[{"a": 1}, {"b": 2}] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ [{"a": 1}, {"b": 2}] | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: list[dict]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are strings. All values are integers.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '{"a": 1} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": 1} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ {"a": 1} | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: dict[str, int]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are strings. All values are integers.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: '{"a": 1, "b": 2} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": 1, "b": 2} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ {"a": 1, "b": 2} | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: dict[str, int]
|
||||||
|
|
||||||
|
# Type of strings is AnsibleUnicode or str
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
|
- name: Dictionary. The keys are integers or strings. All values are strings.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: 'data is {{ dtype }}'
|
||||||
|
fail_msg: 'data is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {1: 'a', 'b': 'b'}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: dict[int|str, str]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are integers. All values are keys.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: 'data is {{ dtype }}'
|
||||||
|
fail_msg: 'data is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {1: 'a', 2: 'b'}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: dict[int, str]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are strings. Multiple types values.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: 'data is {{ dtype }}'
|
||||||
|
fail_msg: 'data is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {'a': 1, 'b': 1.1, 'c': 'abc', 'd': True, 'e': ['x', 'y', 'z'], 'f': {'x': 1, 'y': 2}}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: dict[str, bool|dict|float|int|list|str]
|
||||||
|
|
||||||
|
- name: List. Multiple types items.
|
||||||
|
assert:
|
||||||
|
that: result == dtype
|
||||||
|
success_msg: 'data is {{ dtype }}'
|
||||||
|
fail_msg: 'data is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: [1, 2, 1.1, 'abc', True, ['x', 'y', 'z'], {'x': 1, 'y': 2}]
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: list[bool|dict|float|int|list|str]
|
5
tests/integration/targets/test_ansible_type/aliases
Normal file
5
tests/integration/targets/test_ansible_type/aliases
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
azp/posix/2
|
|
@ -0,0 +1,7 @@
|
||||||
|
---
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
- name: Integration tests
|
||||||
|
import_tasks: tasks.yml
|
248
tests/integration/targets/test_ansible_type/tasks/tasks.yml
Normal file
248
tests/integration/targets/test_ansible_type/tasks/tasks.yml
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
# Copyright (c) Ansible Project
|
||||||
|
# GNU General Public License v3.0+ (see LICENSES/GPL-3.0-or-later.txt or https://www.gnu.org/licenses/gpl-3.0.txt)
|
||||||
|
# SPDX-License-Identifier: GPL-3.0-or-later
|
||||||
|
|
||||||
|
# Substitution converts str to AnsibleUnicode
|
||||||
|
# -------------------------------------------
|
||||||
|
|
||||||
|
- name: String. AnsibleUnicode.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype)
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: 'AnsibleUnicode'
|
||||||
|
|
||||||
|
- name: String. AnsibleUnicode alias str.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: "abc"
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: 'str'
|
||||||
|
|
||||||
|
- name: List. All items are AnsibleUnicode.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype)
|
||||||
|
success_msg: '["a", "b", "c"] is {{ dtype }}'
|
||||||
|
fail_msg: '["a", "b", "c"] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: ["a", "b", "c"]
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: 'list[AnsibleUnicode]'
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are AnsibleUnicode. All values are AnsibleUnicode.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype)
|
||||||
|
success_msg: '{"a": "foo", "b": "bar", "c": "baz"} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": "foo", "b": "bar", "c": "baz"} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: {"a": "foo", "b": "bar", "c": "baz"}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: 'dict[AnsibleUnicode, AnsibleUnicode]'
|
||||||
|
|
||||||
|
# No substitution and no alias. Type of strings is str
|
||||||
|
# ----------------------------------------------------
|
||||||
|
|
||||||
|
- name: String
|
||||||
|
assert:
|
||||||
|
that: '"abc" is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ "abc" | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: str
|
||||||
|
|
||||||
|
- name: Integer
|
||||||
|
assert:
|
||||||
|
that: '123 is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '123 is {{ dtype }}'
|
||||||
|
fail_msg: '123 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ 123 | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: int
|
||||||
|
|
||||||
|
- name: Float
|
||||||
|
assert:
|
||||||
|
that: '123.45 is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '123.45 is {{ dtype }}'
|
||||||
|
fail_msg: '123.45 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ 123.45 | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: float
|
||||||
|
|
||||||
|
- name: Boolean
|
||||||
|
assert:
|
||||||
|
that: 'true is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: 'true is {{ dtype }}'
|
||||||
|
fail_msg: 'true is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ true | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: bool
|
||||||
|
|
||||||
|
- name: List. All items are strings.
|
||||||
|
assert:
|
||||||
|
that: '["a", "b", "c"] is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '["a", "b", "c"] is {{ dtype }}'
|
||||||
|
fail_msg: '["a", "b", "c"] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ ["a", "b", "c"] | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: list[str]
|
||||||
|
|
||||||
|
- name: List of dictionaries.
|
||||||
|
assert:
|
||||||
|
that: '[{"a": 1}, {"b": 2}] is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '[{"a": 1}, {"b": 2}] is {{ dtype }}'
|
||||||
|
fail_msg: '[{"a": 1}, {"b": 2}] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ [{"a": 1}, {"b": 2}] | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: list[dict]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are strings. All values are integers.
|
||||||
|
assert:
|
||||||
|
that: '{"a": 1} is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '{"a": 1} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": 1} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ {"a": 1} | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: dict[str, int]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are strings. All values are integers.
|
||||||
|
assert:
|
||||||
|
that: '{"a": 1, "b": 2} is community.general.ansible_type(dtype)'
|
||||||
|
success_msg: '{"a": 1, "b": 2} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": 1, "b": 2} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
result: '{{ {"a": 1, "b": 2} | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: dict[str, int]
|
||||||
|
|
||||||
|
# Type of strings is AnsibleUnicode or str
|
||||||
|
# ----------------------------------------
|
||||||
|
|
||||||
|
- name: Dictionary. The keys are integers or strings. All values are strings.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '{"1": "a", "b": "b"} is {{ dtype }}'
|
||||||
|
fail_msg: '{"1": "a", "b": "b"} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {1: 'a', 'b': 'b'}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: dict[int|str, str]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are integers. All values are keys.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '{"1": "a", "2": "b"} is {{ dtype }}'
|
||||||
|
fail_msg: '{"1": "a", "2": "b"} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {1: 'a', 2: 'b'}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: dict[int, str]
|
||||||
|
|
||||||
|
- name: Dictionary. All keys are strings. Multiple types values.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '{"a": 1, "b": 1.1, "c": "abc", "d": true, "e": ["x", "y", "z"], "f": {"x": 1, "y": 2}} is {{ dtype }}'
|
||||||
|
fail_msg: '{"a": 1, "b": 1.1, "c": "abc", "d": true, "e": ["x", "y", "z"], "f": {"x": 1, "y": 2}} is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: {'a': 1, 'b': 1.1, 'c': 'abc', 'd': True, 'e': ['x', 'y', 'z'], 'f': {'x': 1, 'y': 2}}
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: dict[str, bool|dict|float|int|list|str]
|
||||||
|
|
||||||
|
- name: List. Multiple types items.
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '[1, 2, 1.1, "abc", true, ["x", "y", "z"], {"x": 1, "y": 2}] is {{ dtype }}'
|
||||||
|
fail_msg: '[1, 2, 1.1, "abc", true, ["x", "y", "z"], {"x": 1, "y": 2}] is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"AnsibleUnicode": "str"}
|
||||||
|
data: [1, 2, 1.1, 'abc', True, ['x', 'y', 'z'], {'x': 1, 'y': 2}]
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: list[bool|dict|float|int|list|str]
|
||||||
|
|
||||||
|
# Option dtype is list
|
||||||
|
# --------------------
|
||||||
|
|
||||||
|
- name: AnsibleUnicode or str
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype)
|
||||||
|
success_msg: '"abc" is {{ dtype }}'
|
||||||
|
fail_msg: '"abc" is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: abc
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: ['AnsibleUnicode', 'str']
|
||||||
|
|
||||||
|
- name: float or int
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype)
|
||||||
|
success_msg: '123 is {{ dtype }}'
|
||||||
|
fail_msg: '123 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: 123
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: ['float', 'int']
|
||||||
|
|
||||||
|
- name: float or int
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype)
|
||||||
|
success_msg: '123.45 is {{ dtype }}'
|
||||||
|
fail_msg: '123.45 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
data: 123.45
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type }}'
|
||||||
|
dtype: ['float', 'int']
|
||||||
|
|
||||||
|
# Multiple alias
|
||||||
|
# --------------
|
||||||
|
|
||||||
|
- name: int alias number
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '123 is {{ dtype }}'
|
||||||
|
fail_msg: '123 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"int": "number", "float": "number"}
|
||||||
|
data: 123
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: number
|
||||||
|
|
||||||
|
- name: float alias number
|
||||||
|
assert:
|
||||||
|
that: data is community.general.ansible_type(dtype, alias)
|
||||||
|
success_msg: '123.45 is {{ dtype }}'
|
||||||
|
fail_msg: '123.45 is {{ result }}'
|
||||||
|
quiet: '{{ quiet_test | d(true) | bool }}'
|
||||||
|
vars:
|
||||||
|
alias: {"int": "number", "float": "number"}
|
||||||
|
data: 123.45
|
||||||
|
result: '{{ data | community.general.reveal_ansible_type(alias) }}'
|
||||||
|
dtype: number
|
Loading…
Reference in a new issue