fastkml icon indicating copy to clipboard operation
fastkml copied to clipboard

TypeError (TypeError: type must be one of 'string', 'int', 'uint', 'short', 'ushort', 'float', 'double', 'bool')

Open wizardofozzie opened this issue 8 years ago • 5 comments

No handlers could be found for logger "fastkml.config" Traceback (most recent call last): File "/private/var/mobile/Containers/Shared/AppGroup/AA78F2EC-3EE8-40F4-A318-8A9AB1BCB5FF/Pythonista3/Documents/ceid-fixer/fkml.py", line 8, in <module> k.from_string(doc) File "/private/var/mobile/Containers/Shared/AppGroup/AA78F2EC-3EE8-40F4-A318-8A9AB1BCB5FF/Pythonista3/Documents/site-packages/fastkml/kml.py", line 101, in from_string feature.from_element(document) File "/private/var/mobile/Containers/Shared/AppGroup/AA78F2EC-3EE8-40F4-A318-8A9AB1BCB5FF/Pythonista3/Documents/site-packages/fastkml/kml.py", line 1001, in from_element s.from_element(schema) File "/private/var/mobile/Containers/Shared/AppGroup/AA78F2EC-3EE8-40F4-A318-8A9AB1BCB5FF/Pythonista3/Documents/site-packages/fastkml/kml.py", line 1359, in from_element self.append(sftype, sfname, sfdisplay_name) File "/private/var/mobile/Containers/Shared/AppGroup/AA78F2EC-3EE8-40F4-A318-8A9AB1BCB5FF/Pythonista3/Documents/site-packages/fastkml/kml.py", line 1337, in append "type must be one of ""'string', 'int', 'uint', 'short', " TypeError: type must be one of 'string', 'int', 'uint', 'short', 'ushort', 'float', 'double', 'bool'

wizardofozzie avatar Aug 19 '16 08:08 wizardofozzie

doc.kml is here

Running under py2&3 (no lxml since I'm using iOS Pythonista 3)

EDIT: same error with lxml using Python 2.7 in windows environment

wizardofozzie avatar Aug 19 '16 08:08 wizardofozzie

Workaround is as follows:

    def append(self, type, name, displayName=None):
        """
        append a field.
        The declaration of the custom field, must specify both the type
        and the name of this field.
        If either the type or the name is omitted, the field is ignored.

        The type can be one of the following:
            string
            int
            uint
            short
            ushort
            float
            double
            bool

        <displayName>
        The name, if any, to be used when the field name is displayed to
        the Google Earth user. Use the [CDATA] element to escape standard
        HTML markup.
        """
        allowed_types = [
            'string', 'int', 'uint', 'short', 'ushort',
            'float', 'double', 'bool'
        ]
        # if type not in allowed_types:
        #     raise TypeError(
        #         "type must be one of ""'string', 'int', 'uint', 'short', "
        #         "'ushort', 'float', 'double', 'bool'"
        #     )
        # else:
        #     # TODO explicit type conversion to check for the right type
        #     pass
        self._simple_fields.append({'type': str(type), 'name': name,
                                    'displayName': displayName})

wizardofozzie avatar Aug 21 '16 05:08 wizardofozzie

@wizardofozzie The doc.kml that you linked to is actually invalid KML, which is why fastkml is unhappy.

Specifically, doc.kml has several SimpleField declarations where the type="wstring". But the official KML documentation is pretty clear that this isn't valid; see: https://developers.google.com/kml/documentation/extendeddata#adding-typed-data-to-a-feature

I also ran into a set of KML files -- in my case, directly from census.gov -- with invalid SimpleField types.

Frustratingly, fastkml is not modular in the way you might hope in order to cleanly adjust its behavior here. I ended up writing an awful monkeypatch in my code to force it to be lenient. In your case, that might look like:

from fastkml import kml

_fastkml_append = kml.Schema.append

def monkeypatched_append(self, type, name, displayName=None):
    """
    Process a SimpleField declaration in a KML file, being lenient
    about the strings we will accept for the 'type' attribute.
    """
    if type is 'wstring':
        type = 'string'
    return _fastkml_append(self, type, name, displayName=displayName)

kml.Schema.append = monkeypatched_append

If anyone has a better suggestion for modifying fastkml's behavior to be more lenient about the input it accepts, I'd love to hear it.

davepeck avatar Jun 07 '18 19:06 davepeck

@wizardofozzie The doc.kml that you linked to is actually invalid KML, which is why fastkml is unhappy.

Specifically, doc.kml has several SimpleField declarations where the type="wstring". But the official KML documentation is pretty clear that this isn't valid; see: https://developers.google.com/kml/documentation/extendeddata#adding-typed-data-to-a-feature

I also ran into a set of KML files -- in my case, directly from census.gov -- with invalid SimpleField types.

Many thanks for this tip @davepeck. I encountered this also on school district data from census.gov in the form of type="xsd:string" and type="xsd:double".

Instead of changing fastkml to handle the invalid KML I ended up fixing the problem in the KML itself since there were only 8 occurrences.

anthony-curtis avatar Nov 03 '18 15:11 anthony-curtis

This should raise a warning, rather than an error.

cleder avatar Oct 14 '21 09:10 cleder