def cast(self, d): """ Cast a single value to a :class:`decimal.Decimal`. :returns: :class:`decimal.Decimal` or :code:`None`. :raises: :exc:`.CastError` """ if isinstance(d, Decimal) or d is None: return d elif isinstance(d, int): return Decimal(d) elif isinstance(d, float): raise CastError( 'Can not convert float to Decimal. Convert data to string first!' ) elif isinstance(d, six.string_types): d = d.strip() d = d.strip('%') for symbol in CURRENCY_SYMBOLS: d = d.strip(symbol) if d.lower() in self.null_values: return None try: return parse_decimal(d, self._locale) except: raise CastError('Can not parse value "%s" as Decimal.' % d)
def cast(self, d): """ Cast a single value to :class:`datetime.timedelta`. :param d: A value to cast. :returns: :class:`datetime.timedelta` or :code:`None` """ if isinstance(d, datetime.timedelta) or d is None: return d elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as timedelta.' % d) seconds = pytimeparse.parse(d) if seconds is None: raise CastError('Can not parse value "%s" to as timedelta.' % d) return datetime.timedelta(seconds=seconds)
def cast(self, d): """ Cast a single value to a :class:`decimal.Decimal`. :returns: :class:`decimal.Decimal` or :code:`None`. :raises: :exc:`.CastError` """ if isinstance(d, Decimal) or d is None: return d if isinstance(d, six.string_types): d = d.replace(',', '').strip() if d.lower() in self.null_values: return None if isinstance(d, float): raise CastError( 'Can not convert float to Decimal for NumberColumn. Convert data to string first!' ) try: return Decimal(d) except InvalidOperation: raise CastError( 'Can not convert value "%s" to Decimal for NumberColumn.' % d)
def cast(self, d): """ Cast a single value to a :class:`decimal.Decimal`. :returns: :class:`decimal.Decimal` or :code:`None`. """ if isinstance(d, Decimal) or d is None: return d elif type(d) is int: return Decimal(d) elif type(d) is float: return Decimal(repr(d)) elif isinstance(d, six.string_types): d = d.strip() d = d.strip('%') for symbol in CURRENCY_SYMBOLS: d = d.strip(symbol) if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as Decimal.' % d) try: return parse_decimal(d, self.locale) except: pass raise CastError('Can not parse value "%s" as Decimal.' % d)
def cast(self, d): """ Cast a single value to a :class:`datetime.date`. :param date_format: An optional :func:`datetime.strptime` format string for parsing datetimes in this column. :returns: :class:`datetime.date` or :code:`None`. """ if type(d) is date or d is None: return d elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as date.' % d) if self.date_format: try: dt = datetime.strptime(d, self.date_format) except: raise CastError('Value "%s" does not match date format.' % d) return dt.date() value, ctx = self.parser.parseDT(d, sourceTime=ZERO_DT) if ctx.hasDate and not ctx.hasTime: return value.date() raise CastError('Can not parse value "%s" as date.' % d)
def cast(self, d): """ Cast a single value to a :class:`decimal.Decimal`. :returns: :class:`decimal.Decimal` or :code:`None`. """ if isinstance(d, Decimal) or d is None: return d t = type(d) if t is int: return Decimal(d) elif six.PY2 and t is long: # noqa: F821 return Decimal(d) elif t is float: return Decimal(repr(d)) elif d is False: return Decimal(0) elif d is True: return Decimal(1) elif not isinstance(d, six.string_types): raise CastError('Can not parse value "%s" as Decimal.' % d) d = d.strip() if d.lower() in self.null_values: return None d = d.strip('%') if len(d) > 0 and d[0] == '-': d = d[1:] sign = NEGATIVE else: sign = POSITIVE for symbol in self.currency_symbols: d = d.strip(symbol) d = d.replace(self.group_symbol, '') d = d.replace(self.decimal_symbol, '.') try: return Decimal(d) * sign # The Decimal class will return an InvalidOperation exception on most Python implementations, # but PyPy3 may return a ValueError if the string is not translatable to ASCII except (InvalidOperation, ValueError): pass raise CastError('Can not parse value "%s" as Decimal.' % d)
def cast(self, d): """ Cast a single value to a :class:`datetime.datetime`. :param datetime_format: An optional :func:`datetime.strptime` format string for parsing datetimes in this column. :returns: :class:`datetime.datetime` or :code:`None`. """ if isinstance(d, datetime.datetime) or d is None: return d elif isinstance(d, datetime.date): return datetime.datetime.combine(d, datetime.time(0, 0, 0)) elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as datetime.' % d) if self.datetime_format: try: return datetime.datetime.strptime(d, self.datetime_format) except: raise CastError('Value "%s" does not match date format.' % d) try: (_, _, _, _, matched_text), = self._parser.nlp(d, sourceTime=self._source_time) except: matched_text = None else: value, ctx = self._parser.parseDT(d, sourceTime=self._source_time, tzinfo=self.timezone) if matched_text == d and ctx.hasDate and ctx.hasTime: return value elif matched_text == d and ctx.hasDate and not ctx.hasTime: return datetime.datetime.combine(value.date(), datetime.time.min) try: dt = isodate.parse_datetime(d) return dt except: pass raise CastError('Can not parse value "%s" as datetime.' % d)
def cast(self, d): """ Cast a single value to a :class:`decimal.Decimal`. :returns: :class:`decimal.Decimal` or :code:`None`. """ if isinstance(d, Decimal) or d is None: return d t = type(d) if t is int: return Decimal(d) elif six.PY2 and t is long: return Decimal(d) elif t is float: return Decimal(repr(d)) elif d is False: return Decimal(0) elif d is True: return Decimal(1) elif not isinstance(d, six.string_types): raise CastError('Can not parse value "%s" as Decimal.' % d) d = d.strip() if d.lower() in self.null_values: return None d = d.strip('%') if len(d) > 0 and d[0] == '-': d = d[1:] sign = NEGATIVE else: sign = POSITIVE for symbol in self.currency_symbols: d = d.strip(symbol) d = d.replace(self.group_symbol, '') d = d.replace(self.decimal_symbol, '.') try: return Decimal(d) * sign except InvalidOperation: pass raise CastError('Can not parse value "%s" as Decimal.' % d)
def cast(self, d): """ Cast a single value to a :class:`datetime.date`. :param date_format: An optional :func:`datetime.strptime` format string for parsing datetimes in this column. :returns: :class:`datetime.date` or :code:`None`. """ if type(d) is datetime.date or d is None: return d elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as date.' % d) if self.date_format: try: dt = datetime.datetime.strptime(d, self.date_format) except: raise CastError('Value "%s" does not match date format.' % d) return dt.date() zero = datetime.datetime.combine(datetime.date.min, datetime.time.min) value, status = self.parser.parseDT(d, sourceTime=zero) if status == 1: if value.time() != datetime.time.min: raise CastError('Value "%s" is datetime, not date.' % d) return value.date() try: dt = isodate.parse_date(d) try: dt = isodate.parse_datetime(d) except: return dt except: pass raise CastError('Can not parse value "%s" as date.' % d)
def cast(self, d): """ Cast a single value to :class:`bool`. :param d: A value to cast. :returns: :class:`bool` or :code:`None`. """ if isinstance(d, bool) or d is None: return d if isinstance(d, six.string_types): d = d.replace(',', '').strip() d_lower = d.lower() if d_lower in self.null_values: return None if d_lower in self.true_values: return True if d_lower in self.false_values: return False raise CastError('Can not convert value %s to bool for BooleanColumn.' % d)
def cast(self, d): """ Cast a single value to a :class:`datetime.datetime`. :param date_format: An optional :func:`datetime.strptime` format string for parsing datetimes in this column. :returns: :class:`datetime.datetime` or :code:`None`. """ if isinstance(d, datetime.datetime) or d is None: return d elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None if self.datetime_format: return datetime.datetime.strptime(d, self.datetime_format) value, status = self._parser.parseDT(d, sourceTime=self._source_time, tzinfo=self.timezone) if status != 3: raise CastError('Can not parse value "%s" to as datetime.' % d) return value
def cast(self, d): """ Cast a single value to :class:`bool`. :param d: A value to cast. :returns: :class:`bool` or :code:`None`. """ if d is None: return d elif type(d) is bool and type(d) is not int: return d elif type(d) is int or isinstance(d, Decimal): if d == 1: return True elif d == 0: return False elif isinstance(d, six.string_types): d = d.replace(',', '').strip() d_lower = d.lower() if d_lower in self.null_values: return None elif d_lower in self.true_values: return True elif d_lower in self.false_values: return False raise CastError('Can not convert value %s to bool.' % d)
def cast(self, d): """ Cast a single value to a :class:`datetime.date`. If both `date_format` and `locale` have been specified in the `agate.Date` instance, the `cast()` function is not thread-safe. :returns: :class:`datetime.date` or :code:`None`. """ if type(d) is date or d is None: return d elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as date.' % d) if self.date_format: orig_locale = None if self.locale: orig_locale = locale.getlocale(locale.LC_TIME) locale.setlocale(locale.LC_TIME, (self.locale, 'UTF-8')) try: dt = datetime.strptime(d, self.date_format) except (ValueError, TypeError): raise CastError('Value "%s" does not match date format.' % d) finally: if orig_locale: locale.setlocale(locale.LC_TIME, orig_locale) return dt.date() try: (value, ctx, _, _, matched_text), = self._parser.nlp(d, sourceTime=ZERO_DT) except (TypeError, ValueError, OverflowError): raise CastError('Value "%s" does not match date format.' % d) else: if matched_text == d and ctx.hasDate and not ctx.hasTime: return value.date() raise CastError('Can not parse value "%s" as date.' % d)
def cast(self, d): """ Cast a single value to :code:`None`. :param d: A value to cast. :returns: :code:`None` """ if d is None: return d if self.cast_nulls and isinstance(d, six.string_types): if d.strip().lower() in self.null_values: return None raise CastError('Can not parse value "%s" as Null.' % d)
def cast(self, d): if d is None: return d if re.match(r"^(?:[01]\d|2[0-3]|\d):[0-5]\d$", str(d)): return Text().cast(d) raise CastError('Can not parse value "%s" as time.' % d)
def cast(self, d): """ Cast a single value to a :class:`datetime.datetime`. If both `date_format` and `locale` have been specified in the `agate.DateTime` instance, the `cast()` function is not thread-safe. :returns: :class:`datetime.datetime` or :code:`None`. """ if isinstance(d, datetime.datetime) or d is None: return d elif isinstance(d, datetime.date): return datetime.datetime.combine(d, datetime.time(0, 0, 0)) elif isinstance(d, six.string_types): d = d.strip() if d.lower() in self.null_values: return None else: raise CastError('Can not parse value "%s" as datetime.' % d) if self.datetime_format: orig_locale = None if self.locale: orig_locale = locale.getlocale(locale.LC_TIME) locale.setlocale(locale.LC_TIME, (self.locale, 'UTF-8')) try: dt = datetime.datetime.strptime(d, self.datetime_format) except (ValueError, TypeError): raise CastError('Value "%s" does not match date format.' % d) finally: if orig_locale: locale.setlocale(locale.LC_TIME, orig_locale) return dt try: (_, _, _, _, matched_text), = self._parser.nlp(d, sourceTime=self._source_time) except Exception: matched_text = None else: value, ctx = self._parser.parseDT(d, sourceTime=self._source_time, tzinfo=self.timezone) if matched_text == d and ctx.hasDate and ctx.hasTime: return value elif matched_text == d and ctx.hasDate and not ctx.hasTime: return datetime.datetime.combine(value.date(), datetime.time.min) try: dt = isodate.parse_datetime(d) return dt except Exception: pass raise CastError('Can not parse value "%s" as datetime.' % d)
def cast(self, d): if d is None: return d if is_valid_siret(d) or is_valid_siren(d): return Text().cast(d) raise CastError('Can not parse value "%s" as a SIREN or SIRET.' % d)
def __init__(self, rows, column_names=None, column_types=None, row_names=None, _is_fork=False): if isinstance(rows, six.string_types): raise ValueError( 'When created directly, the first argument to Table must be a sequence of rows. Did you want agate.Table.from_csv?' ) # Validate column names if column_names: final_column_names = [] for i, column_name in enumerate(column_names): if not column_name: new_column_name = utils.letter_name(i) warn_unnamed_column(i, new_column_name) elif isinstance(column_name, six.string_types): new_column_name = column_name else: raise ValueError('Column names must be strings or None.') final_column_name = new_column_name duplicates = 0 while final_column_name in final_column_names: final_column_name = new_column_name + '_' + str( duplicates + 2) duplicates += 1 if duplicates > 0: warn_duplicate_column(new_column_name, final_column_name) final_column_names.append(final_column_name) self._column_names = tuple(final_column_names) elif rows: self._column_names = tuple( utils.letter_name(i) for i in range(len(rows[0]))) warnings.warn( 'Column names not specified. "%s" will be used as names.' % str(self._column_names), RuntimeWarning, stacklevel=2) else: self._column_names = tuple() len_column_names = len(self._column_names) # Validate column_types if column_types is None: column_types = TypeTester() elif isinstance(column_types, dict): for v in column_types.values(): if not isinstance(v, DataType): raise ValueError( 'Column types must be instances of DataType.') column_types = TypeTester(force=column_types) elif not isinstance(column_types, TypeTester): for column_type in column_types: if not isinstance(column_type, DataType): raise ValueError( 'Column types must be instances of DataType.') if isinstance(column_types, TypeTester): self._column_types = column_types.run(rows, self._column_names) else: self._column_types = tuple(column_types) if len_column_names != len(self._column_types): raise ValueError( 'column_names and column_types must be the same length.') if not _is_fork: new_rows = [] cast_funcs = [c.cast for c in self._column_types] for i, row in enumerate(rows): len_row = len(row) if len_row > len_column_names: raise ValueError( 'Row %i has %i values, but Table only has %i columns.' % (i, len_row, len_column_names)) elif len(row) < len_column_names: row = chain(row, [None] * (len_column_names - len_row)) row_values = [] for j, d in enumerate(row): try: row_values.append(cast_funcs[j](d)) except CastError as e: raise CastError( str(e) + ' Error at row %s column %s.' % (i, self._column_names[j])) new_rows.append(Row(row_values, self._column_names)) else: new_rows = rows if row_names: computed_row_names = [] if isinstance(row_names, six.string_types): for row in new_rows: name = row[row_names] computed_row_names.append(name) elif hasattr(row_names, '__call__'): for row in new_rows: name = row_names(row) computed_row_names.append(name) elif utils.issequence(row_names): computed_row_names = row_names else: raise ValueError( 'row_names must be a column name, function or sequence') for row_name in computed_row_names: if type(row_name) is int: raise ValueError( 'Row names cannot be of type int. Use Decimal for numbered row names.' ) self._row_names = tuple(computed_row_names) else: self._row_names = None self._rows = MappedSequence(new_rows, self._row_names) # Build columns new_columns = [] for i in range(len_column_names): name = self._column_names[i] data_type = self._column_types[i] column = Column(i, name, data_type, self._rows, row_names=self._row_names) new_columns.append(column) self._columns = MappedSequence(new_columns, self._column_names)