bool Python::PyTupleToIGCFixEnhanced(PyObject *py_fix, IGCFixEnhanced &fix) {
  PyObject *py_datetime = NULL,
           *py_location = NULL,
           *py_gps_alt = NULL,
           *py_pressure_alt = NULL,
           *py_enl = NULL,
           *py_trt = NULL,
           *py_gsp = NULL,
           *py_tas = NULL,
           *py_ias = NULL,
           *py_siu = NULL,
           *py_elevation = NULL,
           *py_level = NULL;

  fix.Clear();

  if (!PyArg_ParseTuple(py_fix, "OiOO|OOOOOOOOO",
         &py_datetime, &fix.clock, &py_location,
         &py_gps_alt, &py_pressure_alt,
         &py_enl, &py_trt, &py_gsp, &py_tas, &py_ias,
         &py_siu, &py_elevation, &py_level)) {
    PyErr_SetString(PyExc_TypeError, "Failed to parse tuple.");
    return false;
  }

  fix.date = PyToBrokenDateTime(py_datetime);
  fix.time = PyToBrokenDateTime(py_datetime);

  PyObject *py_latitude = PyDict_GetItemString(py_location, "latitude"),
           *py_longitude = PyDict_GetItemString(py_location, "longitude");

  if (!PyNumber_Check(py_latitude) || !PyNumber_Check(py_longitude)) {
    PyErr_SetString(PyExc_TypeError, "Failed to parse location.");
    return false;
  }

  fix.location.latitude = Angle::Degrees(PyFloat_AsDouble(py_latitude));
  fix.location.longitude = Angle::Degrees(PyFloat_AsDouble(py_longitude));

  if (!PyNumber_Check(py_gps_alt) && !PyNumber_Check(py_pressure_alt)) {
    PyErr_SetString(PyExc_ValueError, "Need at least gps or pressure altitude");
    return false;
  }

  if (PyNumber_Check(py_gps_alt))
    fix.gps_altitude = PyInt_AsLong(py_gps_alt);
  else
    fix.gps_altitude = 0;

  if (PyNumber_Check(py_pressure_alt))
    fix.pressure_altitude = PyInt_AsLong(py_pressure_alt);
  else
    fix.pressure_altitude = 0;

  fix.gps_valid = true;

  if (PyNumber_Check(py_enl))
    fix.enl = PyInt_AsLong(py_enl);

  if (PyNumber_Check(py_trt))
    fix.trt = PyInt_AsLong(py_trt);

  if (PyNumber_Check(py_gsp))
    fix.gsp = PyInt_AsLong(py_gsp);

  if (PyNumber_Check(py_tas))
    fix.tas = PyInt_AsLong(py_tas);

  if (PyNumber_Check(py_ias))
    fix.ias = PyInt_AsLong(py_ias);

  if (PyNumber_Check(py_siu))
    fix.siu = PyInt_AsLong(py_siu);

  if (PyNumber_Check(py_elevation))
    fix.elevation = PyInt_AsLong(py_elevation);

  if (PyNumber_Check(py_level))
    fix.level = PyInt_AsLong(py_level);

  return true;
}
bool Python::PyTupleToIGCFixEnhanced(PyObject *py_fix, IGCFixEnhanced &fix) {
  PyObject *py_datetime = nullptr,
           *py_location = nullptr,
           *py_gps_alt = nullptr,
           *py_pressure_alt = nullptr,
           *py_enl = nullptr,
           *py_trt = nullptr,
           *py_gsp = nullptr,
           *py_tas = nullptr,
           *py_ias = nullptr,
           *py_siu = nullptr,
           *py_elevation = nullptr,
           *py_level = nullptr;

  fix.Clear();

  if (!PyArg_ParseTuple(py_fix, "OiOO|OOOOOOOOO",
         &py_datetime, &fix.clock, &py_location,
         &py_gps_alt, &py_pressure_alt,
         &py_enl, &py_trt, &py_gsp, &py_tas, &py_ias,
         &py_siu, &py_elevation, &py_level)) {
    PyErr_SetString(PyExc_TypeError, "Failed to parse tuple.");
    return false;
  }

  fix.date = PyToBrokenDateTime(py_datetime);
  fix.time = PyToBrokenDateTime(py_datetime);

  fix.location = ReadLonLat(py_location);

  if (!fix.location.IsValid())
    return false;

  if (!PyNumber_Check(py_gps_alt) && !PyNumber_Check(py_pressure_alt)) {
    PyErr_SetString(PyExc_ValueError, "Need at least gps or pressure altitude");
    return false;
  }

  if (PyNumber_Check(py_gps_alt)) {
    fix.gps_altitude = PyInt_AsLong(py_gps_alt);
    fix.gps_valid = true;
  } else {
    fix.gps_altitude = 0;
    fix.gps_valid = false;
  }

  if (PyNumber_Check(py_pressure_alt))
    fix.pressure_altitude = PyInt_AsLong(py_pressure_alt);
  else
    /* fall back to GPS altitude - this is the same behaviour as in IGCFix::Apply() */
    fix.pressure_altitude = fix.gps_altitude;


  if (PyNumber_Check(py_enl))
    fix.enl = PyInt_AsLong(py_enl);

  if (PyNumber_Check(py_trt))
    fix.trt = PyInt_AsLong(py_trt);

  if (PyNumber_Check(py_gsp))
    fix.gsp = PyInt_AsLong(py_gsp);

  if (PyNumber_Check(py_tas))
    fix.tas = PyInt_AsLong(py_tas);

  if (PyNumber_Check(py_ias))
    fix.ias = PyInt_AsLong(py_ias);

  if (PyNumber_Check(py_siu))
    fix.siu = PyInt_AsLong(py_siu);

  if (PyNumber_Check(py_elevation))
    fix.elevation = PyInt_AsLong(py_elevation);

  if (PyNumber_Check(py_level))
    fix.level = PyInt_AsLong(py_level);

  return true;
}