summaryrefslogtreecommitdiff
path: root/pykwalify/types.py
diff options
context:
space:
mode:
authorJohan Fleury <jfleury@arcaik.net>2018-10-08 12:58:12 -0400
committerJohan Fleury <jfleury@arcaik.net>2018-10-08 12:58:12 -0400
commit735c78d3ecb695dd16cb37879880f522c4b29c72 (patch)
tree8bfb2ecbd0f03730efa1540cc65d8490b67e8ddd /pykwalify/types.py
Import upstream version 1.7.0
Diffstat (limited to 'pykwalify/types.py')
-rw-r--r--pykwalify/types.py160
1 files changed, 160 insertions, 0 deletions
diff --git a/pykwalify/types.py b/pykwalify/types.py
new file mode 100644
index 0000000..beb33ad
--- /dev/null
+++ b/pykwalify/types.py
@@ -0,0 +1,160 @@
+# -*- coding: utf-8 -*-
+
+""" pyKwalify - types.py """
+
+# python stdlib
+import datetime
+from pykwalify.compat import basestring, bytes
+
+DEFAULT_TYPE = "str"
+
+
+class TextMeta(type):
+ def __instancecheck__(self, instance):
+ return is_text(instance)
+
+
+class text(object):
+ __metaclass__ = TextMeta
+
+
+_types = {
+ "str": str,
+ "int": int,
+ "float": float,
+ "number": None,
+ "bool": bool,
+ "map": dict,
+ "seq": list,
+ "timestamp": datetime.datetime,
+ "date": datetime.date,
+ "symbol": str,
+ "scalar": None,
+ "text": text,
+ "any": object,
+ "enum": str,
+ "none": None
+}
+
+
+sequence_aliases = ["sequence", "seq"]
+mapping_aliases = ["map", "mapping"]
+
+
+def type_class(type):
+ return _types[type]
+
+
+def is_builtin_type(type):
+ return type in _types
+
+
+def is_collection_type(type):
+ return type.lower().strip() == "map" or type.lower().strip() == "seq"
+
+
+def is_scalar_type(type):
+ return not is_collection_type(type)
+
+
+def is_collection(obj):
+ return isinstance(obj, dict) or isinstance(obj, list)
+
+
+def is_scalar(obj):
+ return not is_collection(obj) and obj is not None
+
+
+def is_correct_type(obj, type):
+ return isinstance(obj, type)
+
+
+def is_string(obj):
+ return isinstance(obj, basestring) or isinstance(obj, bytes)
+
+
+def is_int(obj):
+ """
+ True & False is not considered valid integers even if python considers them 1 & 0 in some versions
+ """
+ return isinstance(obj, int) and not isinstance(obj, bool)
+
+
+def is_bool(obj):
+ return isinstance(obj, bool)
+
+
+def is_float(obj):
+ """
+ Valid types are:
+ - objects of float type
+ - Strings that can be converted to float. For example '1e-06'
+ """
+ is_f = isinstance(obj, float)
+ if not is_f:
+ try:
+ float(obj)
+ is_f = True
+ except (ValueError, TypeError):
+ is_f = False
+ return is_f and not is_bool(obj)
+
+
+def is_number(obj):
+ return is_int(obj) or is_float(obj)
+
+
+def is_text(obj):
+ return (is_string(obj) or is_number(obj)) and is_bool(obj) is False
+
+
+def is_any(obj):
+ return True
+
+
+def is_enum(obj):
+ return isinstance(obj, basestring)
+
+
+def is_none(obj):
+ return obj is None
+
+
+def is_sequence_alias(alias):
+ return alias in sequence_aliases
+
+
+def is_mapping_alias(alias):
+ return alias in mapping_aliases
+
+
+def is_timestamp(obj):
+ """
+ Yaml either have automatically converted it to a datetime object
+ or it is a string that will be validated later.
+ """
+ return isinstance(obj, datetime.datetime) or is_string(obj) or is_int(obj) or is_float(obj)
+
+
+def is_date(obj):
+ """
+ :param obj: Object that is to be validated
+ :return: True/False if obj is valid date object
+ """
+ return isinstance(obj, basestring) or isinstance(obj, datetime.date)
+
+
+tt = {
+ "str": is_string,
+ "int": is_int,
+ "bool": is_bool,
+ "float": is_float,
+ "number": is_number,
+ "text": is_text,
+ "any": is_any,
+ "enum": is_enum,
+ "none": is_none,
+ "timestamp": is_timestamp,
+ "scalar": is_scalar,
+ "date": is_date,
+}