diff --git a/CHANGELOG.md b/CHANGELOG.md
index b41b8d76..89fd8c35 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -11,6 +11,7 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
### Fixed
- removed superfluous debug print when parsing FunctionImports from metadata - Jakub Filak
+- property 'Nullable' attributes are correctly parsed and respected - Vasilii Khomutov
## [1.4.0]
diff --git a/pyodata/v2/model.py b/pyodata/v2/model.py
index 5931ceb1..297c9ad4 100644
--- a/pyodata/v2/model.py
+++ b/pyodata/v2/model.py
@@ -1668,7 +1668,7 @@ def from_etree(entity_type_property_node):
return StructTypeProperty(
entity_type_property_node.get('Name'),
Types.parse_type_name(entity_type_property_node.get('Type')),
- entity_type_property_node.get('Nullable'),
+ attribute_get_bool(entity_type_property_node, 'Nullable', True),
entity_type_property_node.get('MaxLength'),
entity_type_property_node.get('Precision'),
entity_type_property_node.get('Scale'),
@@ -2364,7 +2364,7 @@ def from_etree(function_import_node, config: Config):
for param in function_import_node.xpath('edm:Parameter', namespaces=config.namespaces):
param_name = param.get('Name')
param_type_info = Types.parse_type_name(param.get('Type'))
- param_nullable = param.get('Nullable')
+ param_nullable = attribute_get_bool(param, 'Nullable', False)
param_max_length = param.get('MaxLength')
param_precision = param.get('Precision')
param_scale = param.get('Scale')
@@ -2401,8 +2401,7 @@ def sap_attribute_get_string(node, attr):
return sap_attribute_get(node, attr)
-def sap_attribute_get_bool(node, attr, default):
- value = sap_attribute_get(node, attr)
+def str_to_bool(value, attr, default):
if value is None:
return default
@@ -2415,6 +2414,14 @@ def sap_attribute_get_bool(node, attr, default):
raise TypeError('Not a bool attribute: {0} = {1}'.format(attr, value))
+def attribute_get_bool(node, attr, default):
+ return str_to_bool(node.get(attr), attr, default)
+
+
+def sap_attribute_get_bool(node, attr, default):
+ return str_to_bool(sap_attribute_get(node, attr), attr, default)
+
+
ANNOTATION_NAMESPACES = {
'edm': 'http://docs.oasis-open.org/odata/ns/edm',
'edmx': 'http://docs.oasis-open.org/odata/ns/edmx'
diff --git a/tests/metadata.xml b/tests/metadata.xml
index da460388..70b384ab 100644
--- a/tests/metadata.xml
+++ b/tests/metadata.xml
@@ -303,6 +303,7 @@
+
diff --git a/tests/test_model_v2.py b/tests/test_model_v2.py
index 6ce4dd64..52aded75 100644
--- a/tests/test_model_v2.py
+++ b/tests/test_model_v2.py
@@ -147,6 +147,19 @@ def test_edmx(schema):
assert typ_ex_info.value.args[0] == 'Type FooBar does not exist in Schema Namespace EXAMPLE_SRV'
+def test_schema_entity_type_nullable(schema):
+ emp_entity = schema.entity_type('Employee')
+
+ id_property = emp_entity.proprty('ID')
+ assert not id_property.nullable
+
+ firstname_property = emp_entity.proprty('NameFirst')
+ assert firstname_property.nullable
+
+ nickname_property = emp_entity.proprty('NickName')
+ assert nickname_property.nullable
+
+
def test_schema_entity_sets(schema):
"""Test Schema methods for EntitySets"""