def __init__(self,
                 fare_id=None,
                 route_id=None,
                 origin_id=None,
                 destination_id=None,
                 contains_id=None,
                 field_dict=None):
        Persistable.__init__(self, None)

        self._schedule = None
        (self.fare_id, self.route_id, self.origin_id, self.destination_id,
         self.contains_id) = \
         (fare_id, route_id, origin_id, destination_id, contains_id)
        if field_dict:
            self.__dict__.update(field_dict)

        # canonicalize non-content values as None
        if not self.route_id:
            self.route_id = None
        if not self.origin_id:
            self.origin_id = None
        if not self.destination_id:
            self.destination_id = None
        if not self.contains_id:
            self.contains_id = None
Пример #2
0
  def __init__(self, schedule=None, from_stop_id=None, to_stop_id=None, transfer_type=None,
               min_transfer_time=None, field_dict=None):
    Persistable.__init__(self, None)

    self._schedule = None
    if field_dict:
      self.__dict__.update(field_dict)
    else:
      self.from_stop_id = from_stop_id
      self.to_stop_id = to_stop_id
      self.transfer_type = transfer_type
      self.min_transfer_time = min_transfer_time

    if getattr(self, 'transfer_type', None) in ("", None):
      # Use the default, recommended transfer, if attribute is not set or blank
      self.transfer_type = 0
    else:
      try:
        self.transfer_type = util.NonNegIntStringToInt(self.transfer_type)
      except (TypeError, ValueError):
        pass

    if hasattr(self, 'min_transfer_time'):
      try:
        self.min_transfer_time = util.NonNegIntStringToInt(self.min_transfer_time)
      except (TypeError, ValueError):
        pass
    else:
      self.min_transfer_time = None
    if schedule is not None:
      # Note from Tom, Nov 25, 2009: Maybe calling __init__ with a schedule
      # should output a DeprecationWarning. A schedule factory probably won't
      # use it and other GenericGTFSObject subclasses don't support it.
      schedule.AddTransferObject(self)
Пример #3
0
    def test_recursive_default_dict_payload(self,
                                            p=None,
                                            p_name="test",
                                            workingdatapath=TESTDATAPATH):
        """

        Parameters
        ----------
        p
        workingdatapath

        Returns
        -------

        """
        # Check default payload as recursive def. dict:

        if p is None:
            p = Persistable(p_name, workingdatapath=workingdatapath)
        key1 = "key1"
        key2 = "key2"
        p.payload[key1][key2] = "test"

        # Payload_keys
        self.assertListEqual(list(p.payload.keys()), [key1])
        self.assertListEqual(list(p.payload[key1].keys()), [key2])
        self.assertListEqual(list(p.payload.keys()), list(p.payload_keys))
Пример #4
0
  def __init__(self, name=None, url=None, timezone=None, id=None,
               field_dict=None, lang=None, **kwargs):
    """Initialize a new Agency object.

    Args:
      field_dict: A dictionary mapping attribute name to unicode string
      name: a string, ignored when field_dict is present
      url: a string, ignored when field_dict is present
      timezone: a string, ignored when field_dict is present
      id: a string, ignored when field_dict is present
      kwargs: arbitrary keyword arguments may be used to add attributes to the
        new object, ignored when field_dict is present
    """
    Persistable.__init__(self, None)

    self._schedule = None

    if not field_dict:
      if name:
        kwargs['agency_name'] = name
      if url:
        kwargs['agency_url'] = url
      if timezone:
        kwargs['agency_timezone'] = timezone
      if id:
        kwargs['agency_id'] = id
      if lang:
        kwargs['agency_lang'] = lang
      field_dict = kwargs

    self.__dict__.update(field_dict)
Пример #5
0
  def __init__(self, headsign=None, service_period=None,
               route=None, trip_id=None, field_dict=None):
    Persistable.__init__(self, None)

    self._schedule = None
    self._headways = []  # [(start_time, end_time, headway_secs)]
    if not field_dict:
      field_dict = {}
      if headsign is not None:
        field_dict['trip_headsign'] = headsign
      if route:
        field_dict['route_id'] = route.route_id
      if trip_id is not None:
        field_dict['trip_id'] = trip_id
      if service_period is not None:
        field_dict['service_id'] = service_period.service_id
      # Earlier versions of transitfeed.py assigned self.service_period here
      # and allowed the caller to set self.service_id. Schedule.Validate
      # checked the service_id attribute if it was assigned and changed it to a
      # service_period attribute. Now only the service_id attribute is used and
      # it is validated by Trip.Validate.
      if service_period is not None:
        # For backwards compatibility
        self.service_id = service_period.service_id
    self.__dict__.update(field_dict)
Пример #6
0
    def __init__(self,
                 shape_id=None,
                 lat=None,
                 lon=None,
                 seq=None,
                 dist=None,
                 field_dict=None):
        """Initialize a new ShapePoint object.

    Args:
      field_dict: A dictionary mapping attribute name to unicode string
    """
        Persistable.__init__(self, None)

        self._schedule = None
        if field_dict:
            if isinstance(field_dict, self.__class__):
                for k, v in field_dict.iteritems():
                    self.__dict__[k] = v
            else:
                self.__dict__.update(field_dict)
        else:
            self.shape_id = shape_id
            self.shape_pt_lat = lat
            self.shape_pt_lon = lon
            self.shape_pt_sequence = seq
            self.shape_dist_traveled = dist
Пример #7
0
  def __init__(self, lat=None, lng=None, name=None, stop_id=None,
               field_dict=None, stop_code=None):
    """Initialize a new Stop object.

    Args:
      field_dict: A dictionary mapping attribute name to unicode string
      lat: a float, ignored when field_dict is present
      lng: a float, ignored when field_dict is present
      name: a string, ignored when field_dict is present
      stop_id: a string, ignored when field_dict is present
      stop_code: a string, ignored when field_dict is present
    """
    Persistable.__init__(self, None)

    self._schedule = None
    if field_dict:
      if isinstance(field_dict, self.__class__):
        # Special case so that we don't need to re-parse the attributes to
        # native types iteritems returns all attributes that don't start with _
        for k, v in field_dict.iteritems():
          self.__dict__[k] = v
      else:
        self.__dict__.update(field_dict)
    else:
      if lat is not None:
        self.stop_lat = lat
      if lng is not None:
        self.stop_lon = lng
      if name is not None:
        self.stop_name = name
      if stop_id is not None:
        self.stop_id = stop_id
      if stop_code is not None:
        self.stop_code = stop_code
Пример #8
0
    def __init__(self,
                 headsign=None,
                 service_period=None,
                 route=None,
                 trip_id=None,
                 field_dict=None):
        Persistable.__init__(self, None)

        self._schedule = None
        self._headways = []  # [(start_time, end_time, headway_secs)]
        if not field_dict:
            field_dict = {}
            if headsign is not None:
                field_dict['trip_headsign'] = headsign
            if route:
                field_dict['route_id'] = route.route_id
            if trip_id is not None:
                field_dict['trip_id'] = trip_id
            if service_period is not None:
                field_dict['service_id'] = service_period.service_id
            # Earlier versions of transitfeed.py assigned self.service_period here
            # and allowed the caller to set self.service_id. Schedule.Validate
            # checked the service_id attribute if it was assigned and changed it to a
            # service_period attribute. Now only the service_id attribute is used and
            # it is validated by Trip.Validate.
            if service_period is not None:
                # For backwards compatibility
                self.service_id = service_period.service_id
        self.__dict__.update(field_dict)
Пример #9
0
    def __init__(self, field_dict=None):
      Persistable.__init__(self, None)

      self._schedule = None
      if not field_dict:
        return
      self.trip_id = field_dict['trip_id']
      self.start_time = field_dict['start_time']
      self.end_time = field_dict['end_time']
      self.headway_secs = field_dict['headway_secs']
Пример #10
0
    def __init__(self, field_dict=None):
        Persistable.__init__(self, None)

        self._schedule = None
        if not field_dict:
            return
        self.trip_id = field_dict['trip_id']
        self.start_time = field_dict['start_time']
        self.end_time = field_dict['end_time']
        self.headway_secs = field_dict['headway_secs']
Пример #11
0
    def test_persistload_functionality(self,
                                       p_name="test",
                                       params=TEST_PARAMS,
                                       workingdatapath=TESTDATAPATH):

        p = Persistable(p_name, params=params, workingdatapath=workingdatapath)
        key1 = "key1"
        key2 = "key2"
        p.payload[key1][key2] = "test"

        # Persist:
        p.persist()

        # Get Filename:
        fn = default_standard_filename(p_name, **params)

        # Check file persisted:
        self.assertTrue((workingdatapath / fn).exists())

        # Load to new persistable:
        p2 = Persistable(p_name,
                         params=params,
                         workingdatapath=workingdatapath)
        p2.load()

        # Check both payloads are the same:
        self.assertDictEqual(p.payload, p2.payload)
Пример #12
0
    def __init__(self,
                 fare_id=None,
                 price=None,
                 currency_type=None,
                 payment_method=None,
                 transfers=None,
                 transfer_duration=None,
                 field_dict=None):
        Persistable.__init__(self, None)

        self._schedule = None
        (self.fare_id, self.price, self.currency_type, self.payment_method,
         self.transfers, self.transfer_duration) = \
         (fare_id, price, currency_type, payment_method,
          transfers, transfer_duration)

        if field_dict:
            if isinstance(field_dict, FareAttribute):
                # Special case so that we don't need to re-parse the attributes to
                # native types iteritems returns all attributes that don't start with _
                for k, v in field_dict.iteritems():
                    self.__dict__[k] = v
            else:
                self.__dict__.update(field_dict)
        self.rules = []

        try:
            self.price = float(self.price)
        except (TypeError, ValueError):
            pass
        try:
            self.payment_method = int(self.payment_method)
        except (TypeError, ValueError):
            pass
        if self.transfers == None or self.transfers == "":
            self.transfers = None
        else:
            try:
                self.transfers = int(self.transfers)
            except (TypeError, ValueError):
                pass
        if self.transfer_duration == None or self.transfer_duration == "":
            self.transfer_duration = None
        else:
            try:
                self.transfer_duration = int(self.transfer_duration)
            except (TypeError, ValueError):
                pass
Пример #13
0
  def __init__(self,
               fare_id=None, price=None, currency_type=None,
               payment_method=None, transfers=None, transfer_duration=None,
               field_dict=None):
    Persistable.__init__(self, None)

    self._schedule = None
    (self.fare_id, self.price, self.currency_type, self.payment_method,
     self.transfers, self.transfer_duration) = \
     (fare_id, price, currency_type, payment_method,
      transfers, transfer_duration)

    if field_dict:
      if isinstance(field_dict, FareAttribute):
        # Special case so that we don't need to re-parse the attributes to
        # native types iteritems returns all attributes that don't start with _
        for k, v in field_dict.iteritems():
          self.__dict__[k] = v
      else:
        self.__dict__.update(field_dict)
    self.rules = []

    try:
      self.price = float(self.price)
    except (TypeError, ValueError):
      pass
    try:
      self.payment_method = int(self.payment_method)
    except (TypeError, ValueError):
      pass
    if self.transfers == None or self.transfers == "":
      self.transfers = None
    else:
      try:
        self.transfers = int(self.transfers)
      except (TypeError, ValueError):
        pass
    if self.transfer_duration == None or self.transfer_duration == "":
      self.transfer_duration = None
    else:
      try:
        self.transfer_duration = int(self.transfer_duration)
      except (TypeError, ValueError):
        pass
Пример #14
0
    def test_reset_payload(self, p_name="test", workingdatapath=TESTDATAPATH):
        """

        Parameters
        ----------
        workingdatapath

        Returns
        -------

        """
        p = Persistable(p_name, workingdatapath=workingdatapath)
        key1 = "key1"
        key2 = "key2"
        p.payload[key1][key2] = "test"

        p.reset_payload()

        self.test_payload_init(p)
        self.test_recursive_default_dict_payload(p)
    def __init__(self,
                 schedule=None,
                 from_stop_id=None,
                 to_stop_id=None,
                 transfer_type=None,
                 min_transfer_time=None,
                 field_dict=None):
        Persistable.__init__(self, None)

        self._schedule = None
        if field_dict:
            self.__dict__.update(field_dict)
        else:
            self.from_stop_id = from_stop_id
            self.to_stop_id = to_stop_id
            self.transfer_type = transfer_type
            self.min_transfer_time = min_transfer_time

        if getattr(self, 'transfer_type', None) in ("", None):
            # Use the default, recommended transfer, if attribute is not set or blank
            self.transfer_type = 0
        else:
            try:
                self.transfer_type = util.NonNegIntStringToInt(
                    self.transfer_type)
            except (TypeError, ValueError):
                pass

        if hasattr(self, 'min_transfer_time'):
            try:
                self.min_transfer_time = util.NonNegIntStringToInt(
                    self.min_transfer_time)
            except (TypeError, ValueError):
                pass
        else:
            self.min_transfer_time = None
        if schedule is not None:
            # Note from Tom, Nov 25, 2009: Maybe calling __init__ with a schedule
            # should output a DeprecationWarning. A schedule factory probably won't
            # use it and other GenericGTFSObject subclasses don't support it.
            schedule.AddTransferObject(self)
Пример #16
0
  def __init__(self, fare_id=None, route_id=None,
               origin_id=None, destination_id=None, contains_id=None,
               field_dict=None):
    Persistable.__init__(self, None)

    self._schedule = None
    (self.fare_id, self.route_id, self.origin_id, self.destination_id,
     self.contains_id) = \
     (fare_id, route_id, origin_id, destination_id, contains_id)
    if field_dict:
      self.__dict__.update(field_dict)

    # canonicalize non-content values as None
    if not self.route_id:
      self.route_id = None
    if not self.origin_id:
      self.origin_id = None
    if not self.destination_id:
      self.destination_id = None
    if not self.contains_id:
      self.contains_id = None
Пример #17
0
  def __init__(self, shape_id=None, lat=None, lon=None,seq=None, dist=None,
               field_dict=None):
    """Initialize a new ShapePoint object.

    Args:
      field_dict: A dictionary mapping attribute name to unicode string
    """
    Persistable.__init__(self, None)

    self._schedule = None
    if field_dict:
      if isinstance(field_dict, self.__class__):
        for k, v in field_dict.iteritems():
          self.__dict__[k] = v
      else:
        self.__dict__.update(field_dict)
    else:
      self.shape_id = shape_id
      self.shape_pt_lat = lat
      self.shape_pt_lon = lon
      self.shape_pt_sequence = seq
      self.shape_dist_traveled = dist
Пример #18
0
  def __init__(self, id=None, field_list=None):
    Persistable.__init__(self, None)

    self.original_day_values = {} 
    if field_list:
      field_dict = dict( zip( self._FIELD_NAMES, field_list ) )

      self.service_id = field_dict[ 'service_id' ]
      self.day_of_week = [False] * len(self._DAYS_OF_WEEK)

      for index, day in enumerate( self._DAYS_OF_WEEK ):
        value = field_dict[ day ] or ''
        self.original_day_values[ day ] = value.strip()
        self.day_of_week[index] = (value == u'1')

      self.start_date = field_dict[ 'start_date' ]
      self.end_date = field_dict[ 'end_date' ]
    else:
      self.service_id = id
      self.day_of_week = [False] * 7
      self.start_date = None
      self.end_date = None
    self.date_exceptions = {}  # Map from 'YYYYMMDD' to 1 (add) or 2 (remove)
Пример #19
0
    def __init__(self,
                 name=None,
                 url=None,
                 timezone=None,
                 id=None,
                 field_dict=None,
                 lang=None,
                 **kwargs):
        """Initialize a new Agency object.

    Args:
      field_dict: A dictionary mapping attribute name to unicode string
      name: a string, ignored when field_dict is present
      url: a string, ignored when field_dict is present
      timezone: a string, ignored when field_dict is present
      id: a string, ignored when field_dict is present
      kwargs: arbitrary keyword arguments may be used to add attributes to the
        new object, ignored when field_dict is present
    """
        Persistable.__init__(self, None)

        self._schedule = None

        if not field_dict:
            if name:
                kwargs['agency_name'] = name
            if url:
                kwargs['agency_url'] = url
            if timezone:
                kwargs['agency_timezone'] = timezone
            if id:
                kwargs['agency_id'] = id
            if lang:
                kwargs['agency_lang'] = lang
            field_dict = kwargs

        self.__dict__.update(field_dict)
    def __init__(self, id=None, field_list=None):
        Persistable.__init__(self, None)

        self.original_day_values = {}
        if field_list:
            field_dict = dict(zip(self._FIELD_NAMES, field_list))

            self.service_id = field_dict['service_id']
            self.day_of_week = [False] * len(self._DAYS_OF_WEEK)

            for index, day in enumerate(self._DAYS_OF_WEEK):
                value = field_dict[day] or ''
                self.original_day_values[day] = value.strip()
                self.day_of_week[index] = (value == u'1')

            self.start_date = field_dict['start_date']
            self.end_date = field_dict['end_date']
        else:
            self.service_id = id
            self.day_of_week = [False] * 7
            self.start_date = None
            self.end_date = None
        self.date_exceptions = {
        }  # Map from 'YYYYMMDD' to 1 (add) or 2 (remove)
Пример #21
0
    def test_payload_init(self,
                          p=None,
                          p_name="test",
                          workingdatapath=TESTDATAPATH):
        """

        Parameters
        ----------
        p               :
        workingdatapath :

        Returns
        -------

        """
        # Check payload:
        if p is None:
            p = Persistable(p_name, workingdatapath=workingdatapath)
        self.assertTrue(isinstance(p.payload, defaultdict))
Пример #22
0
  def __init__(self, problems, stop,
               arrival_time=None, departure_time=None,
               stop_headsign=None, pickup_type=None, drop_off_type=None,
               shape_dist_traveled=None, arrival_secs=None,
               departure_secs=None, stop_time=None, stop_sequence=None):
    self._schedule = None
    Persistable.__init__(self, self._schedule)

    # Implementation note from Andre, July 22, 2010:
    # The checks performed here should be in their own Validate* methods to
    # keep consistency. Unfortunately the performance degradation is too great,
    # so the validation was left in __init__.
    # Performance is also the reason why we don't use the GtfsFactory, but
    # have StopTime._STOP_CLASS instead. If a Stop class that does not inherit
    # from transitfeed.Stop is used, the extension should also provide a
    # StopTime class that updates _STOP_CLASS accordingly.
    #
    # For more details see the discussion at
    # http://codereview.appspot.com/1713041
    if stop_time != None:
      arrival_time = departure_time = stop_time

    if arrival_secs != None:
      self.arrival_secs = arrival_secs
    elif arrival_time in (None, ""):
      self.arrival_secs = None  # Untimed
      arrival_time = None
    else:
      try:
        self.arrival_secs = util.TimeToSecondsSinceMidnight(arrival_time)
      except problems_module.Error:
        problems.InvalidValue('arrival_time', arrival_time)
        self.arrival_secs = None

    if departure_secs != None:
      self.departure_secs = departure_secs
    elif departure_time in (None, ""):
      self.departure_secs = None
      departure_time = None
    else:
      try:
        self.departure_secs = util.TimeToSecondsSinceMidnight(departure_time)
      except problems_module.Error:
        problems.InvalidValue('departure_time', departure_time)
        self.departure_secs = None

    if not isinstance(stop, self._STOP_CLASS):
      # Not quite correct, but better than letting the problem propagate
      problems.InvalidValue('stop', stop)
    self.stop = stop
    self.stop_headsign = stop_headsign

    if pickup_type in (None, ""):
      self.pickup_type = None
    else:
      try:
        pickup_type = int(pickup_type)
      except ValueError:
        problems.InvalidValue('pickup_type', pickup_type)
      else:
        if pickup_type < 0 or pickup_type > 3:
          problems.InvalidValue('pickup_type', pickup_type)
      self.pickup_type = pickup_type

    if drop_off_type in (None, ""):
      self.drop_off_type = None
    else:
      try:
        drop_off_type = int(drop_off_type)
      except ValueError:
        problems.InvalidValue('drop_off_type', drop_off_type)
      else:
        if drop_off_type < 0 or drop_off_type > 3:
          problems.InvalidValue('drop_off_type', drop_off_type)
      self.drop_off_type = drop_off_type

    if (self.pickup_type == 1 and self.drop_off_type == 1 and
        self.arrival_secs == None and self.departure_secs == None):
      problems.OtherProblem('This stop time has a pickup_type and '
                            'drop_off_type of 1, indicating that riders '
                            'can\'t get on or off here.  Since it doesn\'t '
                            'define a timepoint either, this entry serves no '
                            'purpose and should be excluded from the trip.',
                            type=problems_module.TYPE_WARNING)

    if ((self.arrival_secs != None) and (self.departure_secs != None) and
        (self.departure_secs < self.arrival_secs)):
      problems.InvalidValue('departure_time', departure_time,
                            'The departure time at this stop (%s) is before '
                            'the arrival time (%s).  This is often caused by '
                            'problems in the feed exporter\'s time conversion')

    # If the caller passed a valid arrival time but didn't attempt to pass a
    # departure time complain
    if (self.arrival_secs != None and
        self.departure_secs == None and departure_time == None):
      # self.departure_secs might be None because departure_time was invalid,
      # so we need to check both
      problems.MissingValue('departure_time',
                            'arrival_time and departure_time should either '
                            'both be provided or both be left blank.  '
                            'It\'s OK to set them both to the same value.')
    # If the caller passed a valid departure time but didn't attempt to pass a
    # arrival time complain
    if (self.departure_secs != None and
        self.arrival_secs == None and arrival_time == None):
      problems.MissingValue('arrival_time',
                            'arrival_time and departure_time should either '
                            'both be provided or both be left blank.  '
                            'It\'s OK to set them both to the same value.')

    if shape_dist_traveled in (None, ""):
      self.shape_dist_traveled = None
    else:
      try:
        self.shape_dist_traveled = float(shape_dist_traveled)
      except ValueError:
        problems.InvalidValue('shape_dist_traveled', shape_dist_traveled)

    if stop_sequence is not None:
      self.stop_sequence = stop_sequence
Пример #23
0
    def test_update_payload_name(self,
                                 old_p_name="test",
                                 new_p_name="test2",
                                 params=TEST_PARAMS,
                                 new_intermediate_data_path=TMPTESTDATAPATH):

        # Create clear directory:
        # If directory exists, remove it for test:
        if new_intermediate_data_path.exists():
            # Remove files and dir:
            [f.unlink() for f in new_intermediate_data_path.glob("*")]
            new_intermediate_data_path.rmdir()

        # Persist Payload:
        p = Persistable(old_p_name,
                        params=params,
                        workingdatapath=new_intermediate_data_path)
        p.payload = TEST_PAYLOAD
        p.persist()

        old_fn = default_standard_filename(old_p_name, **params)
        self.assertTrue((new_intermediate_data_path / old_fn).exists())

        # Update fn params and keep old file:
        p.update_payload_name(new_p_name, delete_old=False)
        new_fn = default_standard_filename(new_p_name, **params)
        self.assertTrue((new_intermediate_data_path / old_fn).exists())
        self.assertTrue((new_intermediate_data_path / new_fn).exists())

        # Update fn params when file already exists:
        p = Persistable(old_p_name,
                        params=params,
                        workingdatapath=new_intermediate_data_path)
        with self.assertRaises(FileExistsError):
            p.update_payload_name(new_p_name, delete_old=True)

        # Delete new file and update fn params and remove old file:
        new_fn = default_standard_filename(new_p_name, **params)
        (new_intermediate_data_path / new_fn).unlink()
        p = Persistable(old_p_name,
                        params=params,
                        workingdatapath=new_intermediate_data_path)
        p.update_payload_name(new_p_name, delete_old=True)
        self.assertFalse((new_intermediate_data_path / old_fn).exists())
        self.assertTrue((new_intermediate_data_path / new_fn).exists())

        # Test fn_params updated:
        self.assertEqual(p.payload_name, new_p_name)

        # Load new persistable and check payload:
        p2 = Persistable(new_p_name,
                         params=params,
                         workingdatapath=new_intermediate_data_path)
        p2.load()
        self.assertEqual(TEST_PAYLOAD, p2.payload)
Пример #24
0
    def __init__(self,
                 problems,
                 stop,
                 arrival_time=None,
                 departure_time=None,
                 stop_headsign=None,
                 pickup_type=None,
                 drop_off_type=None,
                 shape_dist_traveled=None,
                 arrival_secs=None,
                 departure_secs=None,
                 stop_time=None,
                 stop_sequence=None):
        self._schedule = None
        Persistable.__init__(self, self._schedule)

        # Implementation note from Andre, July 22, 2010:
        # The checks performed here should be in their own Validate* methods to
        # keep consistency. Unfortunately the performance degradation is too great,
        # so the validation was left in __init__.
        # Performance is also the reason why we don't use the GtfsFactory, but
        # have StopTime._STOP_CLASS instead. If a Stop class that does not inherit
        # from transitfeed.Stop is used, the extension should also provide a
        # StopTime class that updates _STOP_CLASS accordingly.
        #
        # For more details see the discussion at
        # http://codereview.appspot.com/1713041
        if stop_time != None:
            arrival_time = departure_time = stop_time

        if arrival_secs != None:
            self.arrival_secs = arrival_secs
        elif arrival_time in (None, ""):
            self.arrival_secs = None  # Untimed
            arrival_time = None
        else:
            try:
                self.arrival_secs = util.TimeToSecondsSinceMidnight(
                    arrival_time)
            except problems_module.Error:
                problems.InvalidValue('arrival_time', arrival_time)
                self.arrival_secs = None

        if departure_secs != None:
            self.departure_secs = departure_secs
        elif departure_time in (None, ""):
            self.departure_secs = None
            departure_time = None
        else:
            try:
                self.departure_secs = util.TimeToSecondsSinceMidnight(
                    departure_time)
            except problems_module.Error:
                problems.InvalidValue('departure_time', departure_time)
                self.departure_secs = None

        if not isinstance(stop, self._STOP_CLASS):
            # Not quite correct, but better than letting the problem propagate
            problems.InvalidValue('stop', stop)
        self.stop = stop
        self.stop_headsign = stop_headsign

        if pickup_type in (None, ""):
            self.pickup_type = None
        else:
            try:
                pickup_type = int(pickup_type)
            except ValueError:
                problems.InvalidValue('pickup_type', pickup_type)
            else:
                if pickup_type < 0 or pickup_type > 3:
                    problems.InvalidValue('pickup_type', pickup_type)
            self.pickup_type = pickup_type

        if drop_off_type in (None, ""):
            self.drop_off_type = None
        else:
            try:
                drop_off_type = int(drop_off_type)
            except ValueError:
                problems.InvalidValue('drop_off_type', drop_off_type)
            else:
                if drop_off_type < 0 or drop_off_type > 3:
                    problems.InvalidValue('drop_off_type', drop_off_type)
            self.drop_off_type = drop_off_type

        if (self.pickup_type == 1 and self.drop_off_type == 1
                and self.arrival_secs == None and self.departure_secs == None):
            problems.OtherProblem(
                'This stop time has a pickup_type and '
                'drop_off_type of 1, indicating that riders '
                'can\'t get on or off here.  Since it doesn\'t '
                'define a timepoint either, this entry serves no '
                'purpose and should be excluded from the trip.',
                type=problems_module.TYPE_WARNING)

        if ((self.arrival_secs != None) and (self.departure_secs != None)
                and (self.departure_secs < self.arrival_secs)):
            problems.InvalidValue(
                'departure_time', departure_time,
                'The departure time at this stop (%s) is before '
                'the arrival time (%s).  This is often caused by '
                'problems in the feed exporter\'s time conversion')

        # If the caller passed a valid arrival time but didn't attempt to pass a
        # departure time complain
        if (self.arrival_secs != None and self.departure_secs == None
                and departure_time == None):
            # self.departure_secs might be None because departure_time was invalid,
            # so we need to check both
            problems.MissingValue(
                'departure_time',
                'arrival_time and departure_time should either '
                'both be provided or both be left blank.  '
                'It\'s OK to set them both to the same value.')
        # If the caller passed a valid departure time but didn't attempt to pass a
        # arrival time complain
        if (self.departure_secs != None and self.arrival_secs == None
                and arrival_time == None):
            problems.MissingValue(
                'arrival_time',
                'arrival_time and departure_time should either '
                'both be provided or both be left blank.  '
                'It\'s OK to set them both to the same value.')

        if shape_dist_traveled in (None, ""):
            self.shape_dist_traveled = None
        else:
            try:
                self.shape_dist_traveled = float(shape_dist_traveled)
            except ValueError:
                problems.InvalidValue('shape_dist_traveled',
                                      shape_dist_traveled)

        if stop_sequence is not None:
            self.stop_sequence = stop_sequence