コード例 #1
0
        def test_no_value_behaviour_valid(self):
            for primitive_data in self.primitive_data_list:

                file_name = primitive_data.name
                field_type = primitive_data.field_type

                # Xhtml cannot have extentions. It is always consdered to have a value.
                # So we are not testing it here.
                if file_name == 'Xhtml':
                    continue

                # It's ok to have no value if there's at least another extension present
                # (More than one extension).
                primitive_with_no_value = field_type()

                self._set_primitive_has_no_value_extension(
                    primitive_with_no_value)

                # Add arbitrary extension.
                extensions_field = primitive_with_no_value.DESCRIPTOR.fields_by_name[
                    'extension']
                extension = proto_utils.create_message_from_descriptor(
                    extensions_field.message_type)
                cast(Any, extension).url.value = 'abcd'
                cast(Any, extension).value.boolean.value = True

                proto_utils.append_value_at_field(primitive_with_no_value,
                                                  'extension', extension)
                _ = self.json_format.print_fhir_to_json_string(
                    primitive_with_no_value)
コード例 #2
0
  def testAppendValueAtField_singularCompositeValue_raises(self):
    """Test append_value_at_field with a singular composite type."""
    patient = patient_pb2.Patient()
    active = datatypes_pb2.Boolean(value=True)

    with self.assertRaises(ValueError) as ve:
      proto_utils.append_value_at_field(patient, "active", active)

    self.assertIsInstance(ve.exception, ValueError)
コード例 #3
0
ファイル: _json_parser.py プロジェクト: gthaker/fhir
    def merge_value(self, json_value: Any, target: message.Message):
        """Merges the provided json_value into the target Message.

    Args:
      json_value: A Python-native representation of JSON data.
      target: The target Message to merge the JSON data into.
    """
        target_descriptor = target.DESCRIPTOR
        if annotation_utils.is_primitive_type(target_descriptor):
            if isinstance(json_value, dict):
                # This is a primitive type extension. Merge the extension fields into
                # the empty target proto, and tag it as having no value.
                self._merge_message(json_value, target)

                extension_field = target_descriptor.fields_by_name.get(
                    'extension')
                if extension_field is None:
                    raise ValueError(
                        "Invalid primitive. No 'extension' field exists on "
                        f"{target_descriptor.full_name}.")
                primitive_has_no_value = extensions.create_primitive_has_no_value(
                    extension_field.message_type)
                proto_utils.append_value_at_field(target, extension_field,
                                                  primitive_has_no_value)
            else:
                wrapper = self.primitive_handler.primitive_wrapper_from_json_value(
                    json_value,
                    type(target),
                    default_timezone=self.default_timezone)
                wrapper.merge_into(target)
        elif annotation_utils.is_reference(target_descriptor):
            self._merge_message(json_value, target)
            references.split_if_relative_reference(target)
        else:
            if isinstance(json_value, dict):
                # The provided value must be another FHIR element
                self._merge_message(json_value, target)
            elif isinstance(json_value,
                            (tuple, list)) and len(json_value) == 1:
                # Check if the target field is non-repeated, and we're trying to
                # populate it with a single-element array. This is considered valid, and
                # occurs when a profiled resource reduces the size of a repeated FHIR
                # field to a maximum of 1.
                self._merge_message(json_value[0], target)
            else:
                raise ValueError(
                    'Expected a JSON object for field of type: {}.'.format(
                        target_descriptor.full_name))
コード例 #4
0
  def testAppendValueAtField_repeatedCompositeValue_appendsValue(self):
    """Test append_value_at_field with a repeated composite type."""
    patient = patient_pb2.Patient()

    patient_names = [
        datatypes_pb2.HumanName(text=datatypes_pb2.String(value="Foo")),
        datatypes_pb2.HumanName(text=datatypes_pb2.String(value="Bar")),
        datatypes_pb2.HumanName(text=datatypes_pb2.String(value="Bats")),
    ]
    self.assertEqual(proto_utils.field_content_length(patient, "name"), 0)

    for name in patient_names:
      proto_utils.append_value_at_field(patient, "name", name)

    self.assertEqual(proto_utils.field_content_length(patient, "name"), 3)
    self.assertEqual(patient.name[:], patient_names)
コード例 #5
0
    def test_no_value_behaviour_valid(self, field_type: Type[message.Message]):
        # It's ok to have no value if there's another extension present
        # (Two extensions in total).
        primitive_with_no_value = field_type()

        self._set_primitive_has_no_value_extension(primitive_with_no_value)

        # Add arbitrary extension.
        extensions_field = primitive_with_no_value.DESCRIPTOR.fields_by_name[
            'extension']
        extension = proto_utils.create_message_from_descriptor(
            extensions_field.message_type)
        cast(Any, extension).url.value = 'abcd'
        cast(Any, extension).value.boolean.value = True

        proto_utils.append_value_at_field(primitive_with_no_value, 'extension',
                                          extension)
        _ = json_format.print_fhir_to_json_string(primitive_with_no_value)
コード例 #6
0
  def get_element(self) -> Optional[message.Message]:
    """Returns the raw Element underlying the wrapped primitive.

    Note that conversion-only extensions are removed prior to returning.
    """
    if not (proto_utils.field_is_set(self.wrapped, 'id') or
            proto_utils.field_is_set(self.wrapped, 'extension')):
      return None  # Early-exit if we can't populate an Element

    element = proto_utils.create_message_from_descriptor(
        self.wrapped.DESCRIPTOR)
    if proto_utils.field_is_set(self.wrapped, 'id'):
      proto_utils.copy_common_field(self.wrapped, element, 'id')

    extensions_list = cast(List[Any],
                           extensions.get_fhir_extensions(self.wrapped))
    for extension in extensions_list:
      if extension.url.value not in extensions.CONVERSION_ONLY_EXTENSION_URLS:
        proto_utils.append_value_at_field(element, 'extension', extension)

    return element
コード例 #7
0
ファイル: extensions.py プロジェクト: medical-projects/fhir-1
def _add_extension_value_to_message(extension: message.Message,
                                    msg: message.Message,
                                    message_field: descriptor.FieldDescriptor):
    """Serialize the provided extension and add it to the message.

  Args:
    extension: The FHIR extension to serialize.
    msg: The message to add the serialized extension to.
    message_field: The field on the message to set.

  Raises:
    InvalidFhirError: In the event that the field to be set is not a singular
    message type, or if the provided extension is not singular (has nested
    extensions).
  """
    if message_field.type != descriptor.FieldDescriptor.TYPE_MESSAGE:
        raise fhir_errors.InvalidFhirError(
            f'{msg.DESCRIPTOR.full_name} is not a FHIR extension type.')

    extension_field = extension.DESCRIPTOR.fields_by_name['extension']
    if proto_utils.field_content_length(extension, extension_field) > 0:
        raise fhir_errors.InvalidFhirError(
            'No child extensions should be set on '
            f'{extension.DESCRIPTOR.full_name}.')

    value_field = _get_populated_extension_value_field(extension)

    # If a choice type, need to assign the extension value to the correct field.
    if annotation_utils.is_choice_type_field(message_field):
        choice_message = proto_utils.get_value_at_field(msg, message_field)
        choice_descriptor = choice_message.DESCRIPTOR

        for choice_field in choice_descriptor.fields:
            if (value_field.message_type.full_name ==
                    choice_field.message_type.full_name):
                _add_extension_value_to_message(extension, choice_message,
                                                choice_field)
                return

        raise ValueError(
            f'No field on Choice Type {choice_descriptor.full_name} '
            f'for extension {extension.DESCRIPTOR.full_name}.')

    # If the target message is a bound Code type, we need to convert the generic
    # Code field from the extension into the target typed Code.
    if annotation_utils.has_fhir_valueset_url(message_field.message_type):
        typed_code = proto_utils.set_in_parent_or_add(msg, message_field)
        codes.copy_code(cast(Any, extension).value.code, typed_code)
        return

    # If the target message is bound to a Coding type, we must convert the generic
    # Coding field from the extension into the target typed Coding.
    if fhir_types.is_type_or_profile_of_coding(message_field.message_type):
        typed_coding = proto_utils.set_in_parent_or_add(msg, message_field)
        codes.copy_coding(cast(Any, extension).value.coding, typed_coding)
        return

    # Value types must match
    if not proto_utils.are_same_message_type(value_field.message_type,
                                             message_field.message_type):
        raise ValueError(
            'Missing expected value of type '
            f'{message_field.message_type.full_name} in extension '
            f'{extension.DESCRIPTOR.full_name}.')

    value = proto_utils.get_value_at_field(
        cast(Any, extension).value, value_field)
    if proto_utils.field_is_repeated(message_field):
        proto_utils.append_value_at_field(msg, message_field, value)
    else:
        proto_utils.set_value_at_field(msg, message_field, value)