diff --git a/pandas/_libs/tslibs/timedeltas.pxd b/pandas/_libs/tslibs/timedeltas.pxd index b08592755f2ee..d7af7636df753 100644 --- a/pandas/_libs/tslibs/timedeltas.pxd +++ b/pandas/_libs/tslibs/timedeltas.pxd @@ -1,6 +1,6 @@ from numpy cimport int64_t # Exposed for tslib, not intended for outside use. -cdef int64_t cast_from_unit(object ts, object unit) except? -1 +cdef int64_t cast_from_unit(object ts, str unit) except? -1 cpdef int64_t delta_to_nanoseconds(delta) except? -1 cdef convert_to_timedelta64(object ts, object unit) diff --git a/pandas/_libs/tslibs/timedeltas.pyx b/pandas/_libs/tslibs/timedeltas.pyx index f2b77f3517a25..3af2279e2440f 100644 --- a/pandas/_libs/tslibs/timedeltas.pyx +++ b/pandas/_libs/tslibs/timedeltas.pyx @@ -257,10 +257,15 @@ def array_to_timedelta64(object[:] values, unit='ns', errors='raise'): return iresult.base # .base to access underlying np.ndarray -cpdef inline object precision_from_unit(object unit): +cpdef inline object precision_from_unit(str unit): """ Return a casting of the unit represented to nanoseconds + the precision to round the fractional part. + + Notes + ----- + The caller is responsible for ensuring that the default value of "ns" + takes the place of None. """ cdef: int64_t m @@ -301,7 +306,7 @@ cpdef inline object precision_from_unit(object unit): return m, p -cdef inline int64_t cast_from_unit(object ts, object unit) except? -1: +cdef inline int64_t cast_from_unit(object ts, str unit) except? -1: """ return a casting of the unit represented to nanoseconds round the fractional part of a float to our precision, p """ cdef: @@ -525,15 +530,24 @@ cdef inline timedelta_from_spec(object number, object frac, object unit): return cast_from_unit(float(n), unit) -cpdef inline object parse_timedelta_unit(object unit): +cpdef inline str parse_timedelta_unit(object unit): """ Parameters ---------- - unit : an unit string + unit : str or None + + Returns + ------- + str + Canonical unit string. + + Raises + ------ + ValueError : on non-parseable input """ if unit is None: - return 'ns' - elif unit == 'M': + return "ns" + elif unit == "M": return unit try: return timedelta_abbrevs[unit.lower()] @@ -622,14 +636,14 @@ def _binary_op_method_timedeltalike(op, name): # ---------------------------------------------------------------------- # Timedelta Construction -cdef inline int64_t parse_iso_format_string(object ts) except? -1: +cdef inline int64_t parse_iso_format_string(str ts) except? -1: """ Extracts and cleanses the appropriate values from a match object with groups for each component of an ISO 8601 duration Parameters ---------- - ts: + ts: str ISO 8601 Duration formatted string Returns diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 3363d22686f96..9a49b9de2b5ef 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -4500,6 +4500,8 @@ def _reindex_with_indexers( allow_dups=allow_dups, copy=copy, ) + # If we've made a copy once, no need to make another one + copy = False if copy and new_data is self._mgr: new_data = new_data.copy() @@ -6459,7 +6461,6 @@ def replace( ): if not ( is_scalar(to_replace) - or isinstance(to_replace, pd.Series) or is_re_compilable(to_replace) or is_list_like(to_replace) ): diff --git a/pandas/core/indexes/base.py b/pandas/core/indexes/base.py index d0319e9181bad..df58593bc930c 100644 --- a/pandas/core/indexes/base.py +++ b/pandas/core/indexes/base.py @@ -1,3 +1,4 @@ +from copy import copy as copy_func from datetime import datetime import operator from textwrap import dedent @@ -5313,7 +5314,7 @@ def _add_numeric_methods_unary(cls): Add in numeric unary methods. """ - def _make_evaluate_unary(op, opstr): + def _make_evaluate_unary(op, opstr: str_t): def _evaluate_numeric_unary(self): attrs = self._get_attributes_dict() @@ -5419,7 +5420,7 @@ def _add_logical_methods(cls): """ ) - def _make_logical_function(name, desc, f): + def _make_logical_function(name: str_t, desc: str_t, f): @Substitution(outname=name, desc=desc) @Appender(_index_shared_docs["index_" + name]) @Appender(_doc) @@ -5508,15 +5509,15 @@ def ensure_index_from_sequences(sequences, names=None): return MultiIndex.from_arrays(sequences, names=names) -def ensure_index(index_like, copy=False): +def ensure_index(index_like, copy: bool = False): """ Ensure that we have an index from some index-like object. Parameters ---------- - index : sequence + index_like : sequence An Index or other sequence - copy : bool + copy : bool, default False Returns ------- @@ -5567,9 +5568,7 @@ def ensure_index(index_like, copy=False): # clean_index_list does the equivalent of copying # so only need to do this if not list instance if copy: - from copy import copy - - index_like = copy(index_like) + index_like = copy_func(index_like) return Index(index_like) @@ -5596,7 +5595,7 @@ def _trim_front(strings): return trimmed -def _validate_join_method(method): +def _validate_join_method(method: str): if method not in ["left", "right", "inner", "outer"]: raise ValueError(f"do not recognize join method {method}") diff --git a/pandas/core/indexing.py b/pandas/core/indexing.py index 06cd62c61b366..22a44d65a947a 100644 --- a/pandas/core/indexing.py +++ b/pandas/core/indexing.py @@ -625,7 +625,7 @@ def _ensure_listlike_indexer(self, key, axis=None): Parameters ---------- - key : _LocIndexer key or list-like of column labels + key : list-like of column labels Target labels. axis : key axis if known """ @@ -636,7 +636,7 @@ def _ensure_listlike_indexer(self, key, axis=None): return if isinstance(key, tuple): - # key may be a tuple if key is a _LocIndexer key + # key may be a tuple if we are .loc # in that case, set key to the column part of key key = key[column_axis] axis = column_axis @@ -649,9 +649,7 @@ def _ensure_listlike_indexer(self, key, axis=None): and all(is_hashable(k) for k in key) ): for k in key: - try: - self.obj[k] - except KeyError: + if k not in self.obj: self.obj[k] = np.nan def __setitem__(self, key, value): diff --git a/pandas/core/series.py b/pandas/core/series.py index 5ed8241101925..b74e80642dcdb 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -415,7 +415,7 @@ def _set_axis(self, axis: int, labels, fastpath: bool = False) -> None: object.__setattr__(self, "_index", labels) if not fastpath: - # The ensure_index call aabove ensures we have an Index object + # The ensure_index call above ensures we have an Index object self._mgr.set_axis(axis, labels) # ndarray compatibility