From 57e9215e999a1ee0b3322ea19e85bf4bee9e5a35 Mon Sep 17 00:00:00 2001 From: Marcus Read Date: Thu, 5 Feb 2026 15:50:51 +0000 Subject: [PATCH 1/6] Update dependencies Includes revisions to support pandas 3.0, including: - making "ns" resolution of timestamps explicit (pandas 3.0 now infers as "us" resolution of timestamps defined by str). - loadied and re-exported hdf5 data to ensure loads with explict "ns" resolution (pandas 3.0 was failing to load given lack of explicit resolution). - removes xfail from tests waiting on fixes that were implemented in pandas 3.0. - changes 'd' frequency to 'D' (in response to Pandas4Warning). --- .python-version | 2 +- pyproject.toml | 3 +- requirements.txt | 21 +- src/market_prices/helpers.py | 10 +- src/market_prices/prices/base.py | 10 +- src/market_prices/prices/csv.py | 4 +- src/market_prices/prices/yahoo.py | 2 +- src/market_prices/pt.py | 31 +- src/market_prices/utils/pandas_utils.py | 6 +- tests/resources/store.h5 | Bin 5340427 -> 6660539 bytes tests/resources/store_pbt.h5 | Bin 86787224 -> 103332968 bytes tests/test_base.py | 6 +- tests/test_base_prices.py | 30 +- tests/test_calendar_utils.py | 126 +++--- tests/test_csv.py | 10 +- tests/test_daterange.py | 8 +- tests/test_helpers.py | 6 - tests/test_intervals.py | 2 +- tests/test_pandas_utils.py | 2 +- tests/test_pt.py | 36 +- tests/test_tutorial_helpers.py | 14 +- tests/test_yahoo.py | 7 + uv.lock | 550 ++++++++++++++---------- 23 files changed, 524 insertions(+), 362 deletions(-) diff --git a/.python-version b/.python-version index c8cfe39..24ee5b1 100644 --- a/.python-version +++ b/.python-version @@ -1 +1 @@ -3.10 +3.13 diff --git a/pyproject.toml b/pyproject.toml index 43f69b1..2f7cce3 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -52,7 +52,7 @@ classifiers = [ ] dependencies = [ - "exchange_calendars", + "exchange-calendars", "numpy", "pandas", "tzdata", @@ -64,6 +64,7 @@ dependencies = [ test = [ "attrs", "hypothesis", + "pytz", # required as stored hdf data includes pytz objects "pytest", "pytest-mock", "tables", diff --git a/requirements.txt b/requirements.txt index d960aab..a86bc31 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,5 +1,5 @@ # This file was autogenerated by uv via the following command: -# uv export --format requirements-txt --no-emit-project --no-dev --no-hashes -o requirements.txt +# uv export --format requirements-txt --no-emit-project --no-hashes --no-dev -o requirements.txt beautifulsoup4==4.14.3 # via yahooquery certifi==2026.1.4 @@ -14,7 +14,7 @@ colorama==0.4.6 ; sys_platform == 'win32' # via tqdm curl-cffi==0.14.0 # via yahooquery -exchange-calendars==4.12 +exchange-calendars==4.13.1 # via market-prices idna==3.11 # via requests @@ -27,23 +27,28 @@ numpy==2.2.6 ; python_full_version < '3.11' # exchange-calendars # market-prices # pandas -numpy==2.4.1 ; python_full_version >= '3.11' +numpy==2.4.2 ; python_full_version >= '3.11' # via # exchange-calendars # market-prices # pandas -pandas==2.3.3 +pandas==2.3.3 ; python_full_version < '3.11' # via # exchange-calendars # market-prices # yahooquery -pycparser==2.23 ; implementation_name != 'PyPy' +pandas==3.0.0 ; python_full_version >= '3.11' + # via + # exchange-calendars + # market-prices + # yahooquery +pycparser==3.0 ; implementation_name != 'PyPy' # via cffi pyluach==2.3.0 # via exchange-calendars python-dateutil==2.9.0.post0 # via pandas -pytz==2025.2 +pytz==2025.2 ; python_full_version < '3.11' # via pandas requests==2.32.5 # via requests-futures @@ -51,11 +56,11 @@ requests-futures==1.0.2 # via yahooquery six==1.17.0 # via python-dateutil -soupsieve==2.8.1 +soupsieve==2.8.3 # via beautifulsoup4 toolz==1.1.0 # via exchange-calendars -tqdm==4.67.1 +tqdm==4.67.3 # via yahooquery typing-extensions==4.15.0 # via beautifulsoup4 diff --git a/src/market_prices/helpers.py b/src/market_prices/helpers.py index a4d6936..8ef5bd1 100644 --- a/src/market_prices/helpers.py +++ b/src/market_prices/helpers.py @@ -211,7 +211,7 @@ def freq_format_error_msg() -> str: return ( f'interval/frequency received as "{freq}", although must be defined' " as one or more consecutive digits followed by one or more" - ' consecutive letters. Valid examples: "30min", "3h", "1d", "3m".' + ' consecutive letters. Valid examples: "30min", "3h", "1D", "3m".' ) unit = genutils.remove_digits(freq) @@ -375,6 +375,14 @@ def resample( else: agg_f = agg_funcs(data) + # convert days to hours as Day is not considered a Tick frequency since pandas 3.0 + if isinstance(rule, str): + n, unit = extract_freq_parts(rule) + if unit.upper() == "D": + rule = f"{24 * n}h" + if isinstance(rule, pd.offsets.Day): + rule = f"{24 * rule.n}h" + resampler = resample_me.resample(rule, closed="left", label="left", origin=origin) resampled = resampler.agg(agg_f) resampled.columns = columns_ diff --git a/src/market_prices/prices/base.py b/src/market_prices/prices/base.py index f84969b..67e1f68 100644 --- a/src/market_prices/prices/base.py +++ b/src/market_prices/prices/base.py @@ -3337,7 +3337,7 @@ def get( # noqa: C901, PLR0912 p.get('10T', weeks=2) last two calendar weeks at ten minute intervals. p.get(days=5) last five trading days at inferred interval. - p.get('1d', months=6) daily data for last six months. + p.get('1D', months=6) daily data for last six months. p.get('1h', months=3, end='2021-03-17 15:00') three months at hourly intervals to defined datetime (timezone of 'end' assumed as most common timezone of all symbols). @@ -3514,7 +3514,7 @@ def get( # noqa: C901, PLR0912 unit: "min", "MIN", "T" or "t" for minutes "h" or "H" for hours - "d" or "D' for days + "D' for days 'm' or "M" for months Examples: @@ -3529,7 +3529,7 @@ def get( # noqa: C901, PLR0912 timedelta(hours=3) one day: - "1d", "1D" + "1D" pd.Timedelta(1, "D"), pd.Timedelta(days=1) timedelta(days=1), timedelta(1) @@ -3538,8 +3538,8 @@ def get( # noqa: C901, PLR0912 others: "90min", "90MIN" - ninety minutes - "5D", "5d" - five days - "40D", "40d" - forty days + "5D" - five days + "40D" - forty days "1M", "1m" - one month pd.Timedelta(hours=3, minutes=30) - three and a half hours diff --git a/src/market_prices/prices/csv.py b/src/market_prices/prices/csv.py index 1213f38..503e055 100644 --- a/src/market_prices/prices/csv.py +++ b/src/market_prices/prices/csv.py @@ -1095,7 +1095,7 @@ def __init__( root = path self.PM_SUBSESSION_ORIGIN = pm_subsession_origin # override class attr symbols_ = helpers.symbols_to_list(symbols) - delays = {symb: pd.Timedelta(0) for symb in symbols_} + delays = dict.fromkeys(symbols_, 0) csv_kwargs = _get_csv_read_kwargs(read_csv_kwargs) paths = self._csv_paths = get_csv_paths(root, symbols_) @@ -1167,7 +1167,7 @@ def _compile_tables( dfs.append(df_symb_) if not dfs: continue - df = pd.concat(dfs, axis=1) + df = pd.concat(dfs, axis=1, sort=True) df = df.sort_index() df.columns = df.columns.set_names("symbol", level=0) dfs_by_intrvl[interval] = df diff --git a/src/market_prices/prices/yahoo.py b/src/market_prices/prices/yahoo.py index 7720bcc..09e7695 100644 --- a/src/market_prices/prices/yahoo.py +++ b/src/market_prices/prices/yahoo.py @@ -814,7 +814,7 @@ def _tidy_yahoo( # noqa: C901, PLR0912 # for, at least, hong kong stocks include a single index after the close. params = dict(interval=interval, start=start, end=end) raise errors.PricesUnavailableFromSourceError(params, df) - df = pd.concat(sdfs, axis=1) + df = pd.concat(sdfs, axis=1, sort=True) if empty_sdfs: # add symbols for which prices unavailable over requested period diff --git a/src/market_prices/pt.py b/src/market_prices/pt.py index f437bfa..05ed05b 100644 --- a/src/market_prices/pt.py +++ b/src/market_prices/pt.py @@ -1244,7 +1244,7 @@ def _downsample_cbdays( "\nNB. Downsampling will downsample to a frequency defined in" " CustomBusinessDay when either `pdfreq` is passed as a" " CustomBusinessDay (or multiple of) or when the table has a" - ' CustomBusinessDay frequency and `pdfreq` is passed with unit "d".' + ' CustomBusinessDay frequency and `pdfreq` is passed with unit "D".' ) if not isinstance(calendar, xcals.ExchangeCalendar): @@ -1261,7 +1261,7 @@ def _downsample_cbdays( # Passing 'end' to the origin argument of DataFrame.resample has no # effect when passing rule as a CustomBusinessDay. - origin = "start" + origin = "start_day" # To ensure every indice, INCLUDING the last indice, comprises x # CustomBusinessDays it's necessary to curtail the start of the dataframe @@ -1286,9 +1286,20 @@ def _downsample_cbdays( resampled.index.right.freq = pdfreq return resampled - def _downsample_days(self, pdfreq: str | pd.offsets.BaseOffset) -> pd.DataFrame: - """Downsample to a frequency with unit "d".""" + def _downsample_days(self, pdfreq: str | pd.offsets.Day) -> pd.DataFrame: + """Downsample to a frequency with unit "D".""" df = self.prices + + if isinstance(pdfreq, str): + n, _ = helpers.extract_freq_parts(pdfreq) + elif isinstance(pdfreq, pd.offsets.Day): + n = pdfreq.n + else: + raise TypeError( + "'pdfreq' should be passed as a `str` or `pd.offsets.Day` although" + f" received {pdfreq} of type {type(pdfreq)}." + ) + pd_offset = pd.tseries.frequencies.to_offset(pdfreq) # `origin` should reflect left side of last indice @@ -1329,7 +1340,7 @@ def _downsample_months( if not pre_table_sessions.empty: start_ds = pd_offset.rollforward(start_table) df = df[start_ds:] - resampled = helpers.resample(df, pdfreq, origin="start", nominal_start=start_ds) + resampled = helpers.resample(df, pdfreq, origin="start_day", nominal_start=start_ds) resampled.index = pdutils.get_interval_index(resampled.index, pdfreq) if drop_incomplete_last_indice: @@ -1359,13 +1370,13 @@ def downsample( pdfreq Downsample frequency as CustomBusinessDay or any valid input to pd.tseries.frequencies.to_offset. Examples: - '2d', '3d', '5d', '10d', 'MS', 'QS' + '2D', '3D', '5D', '10D', 'MS', 'QS' pd.offsets.Day(5), pd.offsets.Day(15) 3 * calendar.day (where calendar is an instance of xcals.ExchangeCalendar and hence calendar.day is an instance of CustomBusinessDay). - If `pdfreq` has unit 'd', for example "5d", and table has a + If `pdfreq` has unit 'D', for example "5D", and table has a frequency in CustomBusinessDay then will assume required frequency is the table's CustomBusinessDay frequency. @@ -1440,7 +1451,7 @@ def downsample( f"Received `pdfreq` as {pdfreq} although must be either of" " type pd.offsets.CustomBusinessDay or acceptable input to" " pd.tseries.frequencies.to_offset that describes a" - ' frequency greater than one day. For example "2d", "5d"' + ' frequency greater than one day. For example "2D", "5D"' ' "QS" etc.' ) raise ValueError(msg) from None @@ -1449,7 +1460,7 @@ def downsample( freqstr: str = offset.freqstr value, unit = helpers.extract_freq_parts(freqstr) - if unit.lower() == "d": + if unit.upper() == "D": if isinstance(self.freq, pd.offsets.CustomBusinessDay): pdfreq = self.freq.base * value return self._downsample_cbdays(pdfreq, calendar) @@ -1459,7 +1470,7 @@ def downsample( ext = ["t", "T", "H", "S"] # for pandas pre 2.2 compatibility if unit in invalid_units + ext: raise ValueError( - "Cannot downsample to a `pdfreq` with a unit more precise than 'd'." + "Cannot downsample to a `pdfreq` with a unit more precise than 'D'." ) return self._downsample_months(freqstr, calendar, drop_incomplete_last_indice) diff --git a/src/market_prices/utils/pandas_utils.py b/src/market_prices/utils/pandas_utils.py index fe9ccd5..0ef1175 100644 --- a/src/market_prices/utils/pandas_utils.py +++ b/src/market_prices/utils/pandas_utils.py @@ -102,7 +102,7 @@ def timestamps_in_interval_of_intervals( >>> intervals = pd.interval_range(start, end, freq="10D", closed=closed) >>> intervals - IntervalIndex([[2021-03-02 00:00:00, 2021-03-12 00:00:00], [2021-03-12 00:00:00, 2021-03-22 00:00:00]], dtype='interval[datetime64[ns], both]') + IntervalIndex([[2021-03-02 00:00:00, 2021-03-12 00:00:00], [2021-03-12 00:00:00, 2021-03-22 00:00:00]], dtype='interval[datetime64[us], both]') >>> timestamps_in_interval_of_intervals(timestamps, intervals) True """ # noqa: E501 @@ -601,7 +601,7 @@ def indexes_union(indexes: list[pd.Index]) -> pd.Index: DatetimeIndex(['2021-05-01 12:20:00', '2021-05-01 13:20:00', '2021-05-02 17:10:00', '2021-05-02 17:32:00', '2021-05-03 00:00:00', '2021-05-04 00:00:00'], - dtype='datetime64[ns]', freq=None) + dtype='datetime64[us]', freq=None) """ index = indexes[0] for indx in indexes[1:]: @@ -630,7 +630,7 @@ def index_union(indexes: list[pd.Index | pd.Series | pd.DataFrame]) -> pd.Index: DatetimeIndex(['2021-05-01 12:20:00', '2021-05-01 13:20:00', '2021-05-02 17:10:00', '2021-05-02 17:32:00', '2021-05-03 00:00:00', '2021-05-04 00:00:00'], - dtype='datetime64[ns]', freq=None) + dtype='datetime64[us]', freq=None) """ indexes_ = [obj if isinstance(obj, pd.Index) else obj.index for obj in indexes] return indexes_union(indexes_) diff --git a/tests/resources/store.h5 b/tests/resources/store.h5 index f805220af198c7bbfc079a2a244b30d51fbd81ff..c30dba96cddd4afb5e8532f02fcbfdd48aa5c1f3 100644 GIT binary patch delta 23071 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 delta 14856 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 delta 56234 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 heq%~%( pd.DataFrame: # Necessary for csv saved prior to xcals v4.0 if df.index.tz is not None: df.index = df.index.tz_convert(None) + + df.index = df.index.as_unit("ns") + # Necessary for csv saved prior to xcals v4.0 for col in df: + df[col] = df[col].dt.as_unit("ns") if df[col].dt.tz is None: df[col] = df[col].dt.tz_localize(UTC) return df @@ -973,8 +977,8 @@ def test_non_trading_index1(self, composite_calendars): def intrvl(left: str, right: str) -> pd.Interval: return pd.Interval( - pd.Timestamp("2021-12-" + left), - pd.Timestamp("2021-12-" + right), + pd.Timestamp("2021-12-" + left).as_unit("ns"), + pd.Timestamp("2021-12-" + right).as_unit("ns"), "left", ) @@ -1021,7 +1025,7 @@ def test_non_trading_index2(self): cc = m.CompositeCalendar([x245]) rtrn = cc.non_trading_index(utc=False) - dates = pd.date_range(start, end) + dates = pd.date_range(start, end).as_unit("ns") left = dates[dates.weekday == 5] right = dates[dates.weekday == 0] expected = pd.IntervalIndex.from_arrays(left, right, "left") @@ -1040,8 +1044,8 @@ def test_non_trading_index2(self): def intrvl(left: str, right: str) -> pd.Interval: return pd.Interval( - pd.Timestamp("2021-12-" + left), - pd.Timestamp("2021-12-" + right), + pd.Timestamp("2021-12-" + left).as_unit("ns"), + pd.Timestamp("2021-12-" + right).as_unit("ns"), "left", ) @@ -1151,8 +1155,14 @@ def test_xlon(self, xlon, intervals): f = cc.trading_index # from inspection of schedule - opens = [T("2021-12-24 08:00"), T("2021-12-29 08:00")] - closes = [T("2021-12-24 12:30"), T("2021-12-29 16:30")] + opens = [ + T("2021-12-24 08:00").as_unit("ns"), + T("2021-12-29 08:00").as_unit("ns"), + ] + closes = [ + T("2021-12-24 12:30").as_unit("ns"), + T("2021-12-29 16:30").as_unit("ns"), + ] last_session_duration = closes[-1] - opens[-1] for interval in intervals: @@ -1206,8 +1216,16 @@ def test_xhkg(self, xhkg, intervals, match_xhkg): f = cc.trading_index # if ignoring breaks - opens = [T("2021-12-23 01:30"), T("2021-12-24 01:30"), T("2021-12-28 01:30")] - closes = [T("2021-12-23 08:00"), T("2021-12-24 04:00"), T("2021-12-28 08:00")] + opens = [ + T("2021-12-23 01:30").as_unit("ns"), + T("2021-12-24 01:30").as_unit("ns"), + T("2021-12-28 01:30").as_unit("ns"), + ] + closes = [ + T("2021-12-23 08:00").as_unit("ns"), + T("2021-12-24 04:00").as_unit("ns"), + T("2021-12-28 08:00").as_unit("ns"), + ] for interval in intervals: start, end = T("2021-12-23"), T("2021-12-28") @@ -1217,19 +1235,19 @@ def test_xhkg(self, xhkg, intervals, match_xhkg): # if including breaks opens = [ - T("2021-12-23 01:30"), - T("2021-12-23 05:00"), - T("2021-12-24 01:30"), - T("2021-12-28 01:30"), - T("2021-12-28 05:00"), + T("2021-12-23 01:30").as_unit("ns"), + T("2021-12-23 05:00").as_unit("ns"), + T("2021-12-24 01:30").as_unit("ns"), + T("2021-12-28 01:30").as_unit("ns"), + T("2021-12-28 05:00").as_unit("ns"), ] closes = [ - T("2021-12-23 04:00"), - T("2021-12-23 08:00"), - T("2021-12-24 04:00"), - T("2021-12-28 04:00"), - T("2021-12-28 08:00"), + T("2021-12-23 04:00").as_unit("ns"), + T("2021-12-23 08:00").as_unit("ns"), + T("2021-12-24 04:00").as_unit("ns"), + T("2021-12-28 04:00").as_unit("ns"), + T("2021-12-28 08:00").as_unit("ns"), ] start, end = T("2021-12-23"), T("2021-12-28") @@ -1258,8 +1276,16 @@ def test_overlapping(self, xnys, xlon): f = cc.trading_index start, end = T("2021-12-23"), T("2021-12-27") - opens = [T("2021-12-23 08:00"), T("2021-12-24 08:00"), T("2021-12-27 14:30")] - closes = [T("2021-12-23 21:00"), T("2021-12-24 12:30"), T("2021-12-27 21:00")] + opens = [ + T("2021-12-23 08:00").as_unit("ns"), + T("2021-12-24 08:00").as_unit("ns"), + T("2021-12-27 14:30").as_unit("ns"), + ] + closes = [ + T("2021-12-23 21:00").as_unit("ns"), + T("2021-12-24 12:30").as_unit("ns"), + T("2021-12-27 21:00").as_unit("ns"), + ] for interval in [TDInterval.T1, TDInterval.T5, TDInterval.T30]: rtrn = f(interval, start, end, curtail_calendar_overlaps=False) @@ -1299,21 +1325,21 @@ def test_detached(self, xhkg, bvmf, intervals, match_xhkg): # if ignoring breaks opens = [ - T("2021-12-23 01:30"), - T("2021-12-23 13:00"), - T("2021-12-24 01:30"), - T("2021-12-27 13:00"), - T("2021-12-28 01:30"), - T("2021-12-28 13:00"), + T("2021-12-23 01:30").as_unit("ns"), + T("2021-12-23 13:00").as_unit("ns"), + T("2021-12-24 01:30").as_unit("ns"), + T("2021-12-27 13:00").as_unit("ns"), + T("2021-12-28 01:30").as_unit("ns"), + T("2021-12-28 13:00").as_unit("ns"), ] closes = [ - T("2021-12-23 08:00"), - T("2021-12-23 21:00"), - T("2021-12-24 04:00"), - T("2021-12-27 21:00"), - T("2021-12-28 08:00"), - T("2021-12-28 21:00"), + T("2021-12-23 08:00").as_unit("ns"), + T("2021-12-23 21:00").as_unit("ns"), + T("2021-12-24 04:00").as_unit("ns"), + T("2021-12-27 21:00").as_unit("ns"), + T("2021-12-28 08:00").as_unit("ns"), + T("2021-12-28 21:00").as_unit("ns"), ] for interval in intervals: @@ -1324,25 +1350,25 @@ def test_detached(self, xhkg, bvmf, intervals, match_xhkg): # if including breaks opens = [ - T("2021-12-23 01:30"), - T("2021-12-23 05:00"), - T("2021-12-23 13:00"), - T("2021-12-24 01:30"), - T("2021-12-27 13:00"), - T("2021-12-28 01:30"), - T("2021-12-28 05:00"), - T("2021-12-28 13:00"), + T("2021-12-23 01:30").as_unit("ns"), + T("2021-12-23 05:00").as_unit("ns"), + T("2021-12-23 13:00").as_unit("ns"), + T("2021-12-24 01:30").as_unit("ns"), + T("2021-12-27 13:00").as_unit("ns"), + T("2021-12-28 01:30").as_unit("ns"), + T("2021-12-28 05:00").as_unit("ns"), + T("2021-12-28 13:00").as_unit("ns"), ] closes = [ - T("2021-12-23 04:00"), - T("2021-12-23 08:00"), - T("2021-12-23 21:00"), - T("2021-12-24 04:00"), - T("2021-12-27 21:00"), - T("2021-12-28 04:00"), - T("2021-12-28 08:00"), - T("2021-12-28 21:00"), + T("2021-12-23 04:00").as_unit("ns"), + T("2021-12-23 08:00").as_unit("ns"), + T("2021-12-23 21:00").as_unit("ns"), + T("2021-12-24 04:00").as_unit("ns"), + T("2021-12-27 21:00").as_unit("ns"), + T("2021-12-28 04:00").as_unit("ns"), + T("2021-12-28 08:00").as_unit("ns"), + T("2021-12-28 21:00").as_unit("ns"), ] start, end = T("2021-12-23"), T("2021-12-28") diff --git a/tests/test_csv.py b/tests/test_csv.py index 930eb99..8f7f2a6 100644 --- a/tests/test_csv.py +++ b/tests/test_csv.py @@ -101,8 +101,8 @@ def test__get_csv_interval(): ("t", TDInterval.T1), ("min", TDInterval.T1), ("h", TDInterval.H1), - ("d", TDInterval.D1), - ("1d", TDInterval.D1), + ("D", TDInterval.D1), + ("1D", TDInterval.D1), ("mIN", TDInterval.T1), ("T2", TDInterval.T2), ("2T", TDInterval.T2), @@ -133,7 +133,7 @@ def test__get_csv_interval(): ("1D1", ERROR_MALFORMED_INTRVL), ("1daily1", None), ("D5", ERROR_DAILY_INTRVL), - ("5d", ERROR_DAILY_INTRVL), + ("5D", ERROR_DAILY_INTRVL), ] for inp, out in inputs_outputs: assert m._get_csv_interval(inp) is out @@ -684,7 +684,7 @@ def test_raises_csv_no_data_error(csv_dir, symbols, calendars): match = ( re.escape( - f"For symbols '['MSFT', 'AZN.L', '9988.HK', 'MSFTEXTRA']' it was not possible to create a price table for any interval from csv files. The following errors and warnings occurred during parsing:\n\n0) Prices are not available at base interval {TDInterval.T20} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n1) Prices are not available at base interval {TDInterval.T1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n2) Prices are not available at base interval {TDInterval.D1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n3) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n4) Prices are not available at base interval {TDInterval.T2} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n5) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[ns, UTC]', freq=None)\n\n6) For symbol 'MSFTEXTRA with interval '{TDInterval.T5}' no indice aligned with index evaluated from calendar 'XHKG'.\n\n7) Prices are not available at base interval {TDInterval.T5} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\nSee the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter." + f"For symbols '['MSFT', 'AZN.L', '9988.HK', 'MSFTEXTRA']' it was not possible to create a price table for any interval from csv files. The following errors and warnings occurred during parsing:\n\n0) Prices are not available at base interval {TDInterval.T20} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n1) Prices are not available at base interval {TDInterval.T1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n2) Prices are not available at base interval {TDInterval.D1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n3) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n4) Prices are not available at base interval {TDInterval.T2} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n5) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[us, UTC]', freq=None)\n\n6) For symbol 'MSFTEXTRA with interval '{TDInterval.T5}' no indice aligned with index evaluated from calendar 'XHKG'.\n\n7) Prices are not available at base interval {TDInterval.T5} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\nSee the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter." ) if WINDOWS else None @@ -696,7 +696,7 @@ def test_raises_csv_no_data_error(csv_dir, symbols, calendars): def test_consolidated_warning(csv_dir, symbols, calendars): match = ( re.escape( - f"Price data has been found for all symbols at a least one interval, however, you may find that not all the expected price data is available. See the `limits` property for available base intervals and the limits between which price data is available at each of these intervals. See the `csv_paths` property for paths to all csv files that were found for the requested symbols. See the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter.\n\nThe following errors and/or warnings occurred during parsing:\n\n0) Unable to create dataframe from csv file at 'f_9988.HK_T20_fails_on_ohlc_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n1) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t 'volume' column will not convert to 'float64' dtype.\nThe source error's message was:\n\t: could not convert string to float: 'not a volume'\n\n2) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n3) Unable to create dataframe from csv file at 'f_AZN.L_T20_fails_on_read_csv.csv' due to the following error:\n\t `pd.read_csv` raises error.\nThe source error's message was:\n\t: could not convert string to float: 'not_digits'\n\n4) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t No price data parsed from csv file.\n\n5) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n6) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t At least one row has a high value that is lower than the corresponding low value.\n\n7) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n8) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['AZN.L', 'MSFT']'.\n\n9) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[ns, UTC]', freq=None)" + f"Price data has been found for all symbols at a least one interval, however, you may find that not all the expected price data is available. See the `limits` property for available base intervals and the limits between which price data is available at each of these intervals. See the `csv_paths` property for paths to all csv files that were found for the requested symbols. See the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter.\n\nThe following errors and/or warnings occurred during parsing:\n\n0) Unable to create dataframe from csv file at 'f_9988.HK_T20_fails_on_ohlc_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n1) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t 'volume' column will not convert to 'float64' dtype.\nThe source error's message was:\n\t: could not convert string to float: 'not a volume'\n\n2) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n3) Unable to create dataframe from csv file at 'f_AZN.L_T20_fails_on_read_csv.csv' due to the following error:\n\t `pd.read_csv` raises error.\nThe source error's message was:\n\t: could not convert string to float: 'not_digits'\n\n4) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t No price data parsed from csv file.\n\n5) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n6) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t At least one row has a high value that is lower than the corresponding low value.\n\n7) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n8) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['AZN.L', 'MSFT']'.\n\n9) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[us, UTC]', freq=None)" ) if WINDOWS else None diff --git a/tests/test_daterange.py b/tests/test_daterange.py index 0a1752e..60900e0 100644 --- a/tests/test_daterange.py +++ b/tests/test_daterange.py @@ -10,6 +10,7 @@ """ import contextlib +from datetime import timedelta import itertools import re from collections import abc @@ -2207,7 +2208,7 @@ def match( end: pd.Timestamp, pp: dict, anchor: Anchor, - duration: int | None = None, + duration: int | timedelta | None = None, ) -> str: """Match message for errors.PricesUnavailableIntervalPeriodError. @@ -2217,7 +2218,10 @@ def match( duration_insert = "" if anchor is Anchor.WORKBACK: assert duration is not None - duration_ = pd.Timedelta(duration, "min") + if isinstance(duration, timedelta): + duration_ = pd.Timedelta(duration) + else: + duration_ = pd.Timedelta(duration, "min") duration_insert = f"\nPeriod duration evaluated as {duration_}." return re.escape( f"Period does not span a full indice of length {final_interval}." diff --git a/tests/test_helpers.py b/tests/test_helpers.py index ddbeb26..16f9a02 100644 --- a/tests/test_helpers.py +++ b/tests/test_helpers.py @@ -294,12 +294,6 @@ def test_volume_to_na(intraday_pt, intraday_pt_ss): assert_frame_equal(rtrn, df) -# TODO: Remove xfail when pandas >3 or fix otherwise released -# NB pd bug manifests in test, not package (manifests where evaluate -# `expected_ooo.index = df[::12]`) -# pandas issue ref is https://github.com/pandas-dev/pandas/issues/58604 -# https://github.com/pandas-dev/pandas/pull/58043, related PR, ya merged to dev -@pytest.mark.xfail(reason="Known pd issue with py3.12, should resolve with pd>3.0") def test_resample(intraday_pt): """Test `resample`. diff --git a/tests/test_intervals.py b/tests/test_intervals.py index 4fcaf0c..a544b01 100644 --- a/tests/test_intervals.py +++ b/tests/test_intervals.py @@ -307,7 +307,7 @@ def test_unit(unit: str, limit: int, Cls: m.PTInterval): f(str(i) + unit_) test_unit("h", 22, m.TDInterval) - test_unit("d", 250, m.TDInterval) + test_unit("D", 250, m.TDInterval) test_unit("m", 36, m.DOInterval) assert f("60min") == f("60T") == f("1H") == f("1h") == m.TDInterval.H1 diff --git a/tests/test_pandas_utils.py b/tests/test_pandas_utils.py index 3a4bd2a..9b5d002 100644 --- a/tests/test_pandas_utils.py +++ b/tests/test_pandas_utils.py @@ -156,7 +156,7 @@ def mock_func( match = re.escape( "'arg' can only take a pd.IntervalIndex that has each side" " as type pd.DatetimeIndex, although received with left side" - " as type ''." + " as type ''." ) with pytest.raises(ValueError, match=match): mock_func(invalid_int_index) diff --git a/tests/test_pt.py b/tests/test_pt.py index a29aded..9424765 100644 --- a/tests/test_pt.py +++ b/tests/test_pt.py @@ -27,7 +27,7 @@ def daily_pt() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["MSFT", "AZN.L", "ES=F"] - > df = prices.get("1d", start="2021", end="2021-12-31") + > df = prices.get("1D", start="2021", end="2021-12-31") """ yield get_resource("daily_pt") @@ -82,7 +82,7 @@ def multiple_sessions_pt() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["MSFT", "AZN.L", "ES=F"] - > df = prices.get("3d", start="2021", end="2021-12-31") + > df = prices.get("3D", start="2021", end="2021-12-31") """ yield get_resource("multiple_sessions_pt") @@ -93,7 +93,7 @@ def multiple_sessions_alldays_pt() -> abc.Iterator[pd.DataFrame]: Recreate table with: > symbols = ["MSFT", "AZN.L", "BTC-USD"] - > df = prices.get("3d", start="2021", end="2021-12-31", lead_symbol="BTC-USD") + > df = prices.get("3D", start="2021", end="2021-12-31", lead_symbol="BTC-USD") """ yield get_resource("multiple_sessions_alldays_pt") @@ -300,16 +300,16 @@ def test_new_constructor_errors( match = ( "To use PT accessor index must be of type pd.DatetimeIndex or" " pd.IntervalIndex with left and right sides as pd.DatetimeIndex," - " although index is of type ."): + with pytest.raises(TypeError, match=match + "RangeIndex'>."): _ = daily_df.pt intraday_df = intraday_pt.copy() intraday_df.index = pd.interval_range(start=0, periods=len(intraday_pt), freq=1) - with pytest.raises(TypeError, match=match + "base.Index'>."): + with pytest.raises(TypeError, match=match + "Index'>."): _ = intraday_df.pt daily_df = daily_pt.copy() @@ -1946,7 +1946,7 @@ def test_errors(self, daily_pt, daily_pt_ss, calendars, xnys, xlon): f = df.pt.downsample # test raises expected errors - match = "Cannot downsample to a `pdfreq` with a unit more precise than 'd'." + match = "Cannot downsample to a `pdfreq` with a unit more precise than 'D'." invalid_freqs = ("5min", "1ms", "3h", "120s", "1000ns", "26h") for freq in invalid_freqs: with pytest.raises(ValueError, match=match): @@ -1957,7 +1957,7 @@ def match_f(freq) -> str: f"Received `pdfreq` as {freq} although must be either of type" " pd.offsets.CustomBusinessDay or acceptable input to" " pd.tseries.frequencies.to_offset that describes a frequency greater" - ' than one day. For example "2d", "5d" "QS" etc.' + ' than one day. For example "2D", "5D" "QS" etc.' ) invalid_freqs = ("D2", "astring", "3E", "3") @@ -1971,7 +1971,7 @@ def match_f(freq) -> str: "\nNB. Downsampling will downsample to a frequency defined in" " CustomBusinessDay when either `pdfreq` is passed as a CustomBusinessDay" " (or multiple of) or when the table has a CustomBusinessDay frequency and" - ' `pdfreq` is passed with unit "d".' + ' `pdfreq` is passed with unit "D".' ) # Verify raises error when calendar not passed although required @@ -1989,7 +1989,7 @@ def match_f(freq) -> str: assert isinstance(df_cbday_freq.pt.freq, pd.offsets.CustomBusinessDay) with pytest.raises(TypeError, match=match): - df_cbday_freq.pt.downsample("3d", None) + df_cbday_freq.pt.downsample("3D", None) # Verify raises error when calendar.day does not match frequency (passed or # imferred) base. @@ -2004,7 +2004,7 @@ def match_f(freq) -> str: daily_pt.pt.downsample(xnys.day * 3, xlon) with pytest.raises(ValueError, match=match): - df_cbday_freq.pt.downsample("3d", xlon) + df_cbday_freq.pt.downsample("3D", xlon) def test_cbdays_freq(self, daily_pt, calendars, symbols, one_day): """Verify daily price table with frequency as multiple of CustomBusinessDay.""" @@ -2078,10 +2078,10 @@ def test_d_freq(self, daily_pt, xnys, symbols, one_day): table_start = df.pt.first_ts for days in range(1, 31): - freq = str(days) + "d" + freq = str(days) + "D" offset = pd.tseries.frequencies.to_offset(freq) rtrn = f(freq, xnys) - assert rtrn.pt.last_ts == expected_end + assert rtrn.pt.last_ts == expected_end, f"{days=}, {freq=}" # Assert every indice of rtrn has length i. values = rtrn.index.length.value_counts().index @@ -2118,15 +2118,9 @@ def test_cbday_freq(self, daily_pt_ss, xnys): assert_frame_equal( df.pt.downsample(xnys.day * 3, xnys), - df.pt.downsample("3d", xnys), + df.pt.downsample("3D", xnys), ) - # TODO: Remove xfail when pandas >3 or fix otherwise released - # NB pd bug manifests in test, not package (manifests where takes a slice to - # evaluate 'subset'). - # pandas issue ref is https://github.com/pandas-dev/pandas/issues/58604 - # https://github.com/pandas-dev/pandas/pull/58043, related PR, ya merged to dev - @pytest.mark.xfail(reason="Known pd issue with py3.12, should resolve with pd>3.0") def test_monthly_freq(self, daily_pt, xnys, x247, one_day, symbols): """Verify "MS" and "QS" frequencies.""" df = daily_pt @@ -2313,7 +2307,7 @@ def match_f(pdfreq) -> str: f" received `pdfreq` as {pdfreq}." ) - invalid_pdfreqs = ["1d", "1s", "1ns", "1ms"] + invalid_pdfreqs = ["1D", "1s", "1ns", "1ms"] ext = ["1M", "1Y"] if pandas_pre_22 else ["1ME", "1YE"] invalid_pdfreqs += ext for pdfreq in invalid_pdfreqs: diff --git a/tests/test_tutorial_helpers.py b/tests/test_tutorial_helpers.py index 4691e95..27db437 100644 --- a/tests/test_tutorial_helpers.py +++ b/tests/test_tutorial_helpers.py @@ -264,7 +264,7 @@ def match( no_session = pd.Timedelta(0) length = full_session_xlon - expected = pd.DatetimeIndex([start]) + expected = pd.DatetimeIndex([start]).as_unit("ns") num = 1 assert_index_equal(f(cals, [length], start, end, num), expected) assert_index_equal(f_cc(cc, length, start, end, num), expected) @@ -299,7 +299,7 @@ def match( length = half_session_xlon lengths = [[length]] num = 1 - expected = pd.DatetimeIndex([T("2021-12-24")]) + expected = pd.DatetimeIndex([T("2021-12-24")]).as_unit("ns") assert_index_equal(f(cals, [length], start, end, num), expected) assert_index_equal(f_cc(cc, length, start, end, num), expected) assert_index_equal(f_var(cals, lengths, start, end), expected) @@ -339,7 +339,7 @@ def match( # test var for variatons full_expected = pd.DatetimeIndex( [T("2021-12-23"), T("2021-12-24"), T("2021-12-29")] - ) + ).as_unit("ns") cc_lengths = [full_session_xlon, half_session_xlon] lengths = [cc_lengths] assert_index_equal(f_var(cals, lengths, start, end), full_expected[:2]) @@ -358,7 +358,7 @@ def match( length_by_cal = [full_session_xlon, full_session_xnys] length_cc = full_session_cc num = 1 - expected = pd.DatetimeIndex([start]) + expected = pd.DatetimeIndex([start]).as_unit("ns") assert_index_equal(f(cals, length_by_cal, start, end, num), expected) assert_index_equal(f_cc(cc, length_cc, start, end, num), expected) @@ -396,7 +396,7 @@ def match( lengths = [half_session_xlon, no_session] length_cc = half_session_xlon num = 1 - expected = pd.DatetimeIndex([T("2021-12-24")]) + expected = pd.DatetimeIndex([T("2021-12-24")]).as_unit("ns") assert_index_equal(f(cals, lengths, start, end, num), expected) assert_index_equal(f_cc(cc, length_cc, start, end, num), expected) lengths_by_cal = [[half_session_xlon], [no_session]] @@ -422,7 +422,7 @@ def match( # test var for variatons full_expected = pd.DatetimeIndex( [T("2021-12-" + str(day)) for day in (23, 24, 27, 28, 29)] - ) + ).as_unit("ns") lengths = [ [full_session_xlon, half_session_xlon] + [no_session] * 2 + [full_session_xlon], [full_session_xnys, no_session] + [full_session_xnys] * 3, @@ -460,7 +460,7 @@ def match( length_by_cal = [full_session_xlon, full_session_xnys, full_session_xhkg] length_cc = full_session_cc num = 1 - expected = pd.DatetimeIndex([start]) + expected = pd.DatetimeIndex([start]).as_unit("ns") assert_index_equal(f(cals, length_by_cal, start, end, num), expected) assert_index_equal(f_cc(cc, length_cc, start, end, num), expected) diff --git a/tests/test_yahoo.py b/tests/test_yahoo.py index 0588ad2..ad5d76f 100644 --- a/tests/test_yahoo.py +++ b/tests/test_yahoo.py @@ -29,6 +29,11 @@ # ...sessions that yahoo temporarily fails to return prices for if (seemingly) # send a high frequency of requests for prices from the same IP address. _flakylist = ( + pd.Timestamp("2025-12-07"), + pd.Timestamp("2025-11-30"), + pd.Timestamp("2025-11-20"), + pd.Timestamp("2025-11-19"), + pd.Timestamp("2025-11-18"), pd.Timestamp("2024-11-01"), pd.Timestamp("2024-08-26"), pd.Timestamp("2024-08-25"), @@ -1431,6 +1436,7 @@ def assertions( ) assert isinstance(hist, pd.DataFrame) hist_s = hist.loc[symbol].copy() + hist_s.index = hist_s.index.as_unit("ns") if hist_s.iloc[0].isna().any() and hist_s.index[0] < start: # because v rare bug can introduce an initial row with missing # values and indice < start @@ -1460,6 +1466,7 @@ def assertions( ) assert isinstance(hist_alt, pd.DataFrame) hist_alt_s = hist_alt.loc[symbol].copy() + hist_alt_s.index = hist_alt_s.index.as_unit("ns") if hist_alt_s.index[-2] + interval != hist_alt_s.index[-1]: # yahoo can return live indice at end of table diff --git a/uv.lock b/uv.lock index 70ced51..9bbcc7a 100644 --- a/uv.lock +++ b/uv.lock @@ -2,8 +2,12 @@ version = 1 revision = 3 requires-python = ">=3.10, <4" resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", "python_full_version < '3.11'", ] @@ -31,50 +35,48 @@ wheels = [ [[package]] name = "blosc2" -version = "3.12.2" +version = "4.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "msgpack" }, { name = "ndindex" }, { name = "numexpr", marker = "platform_machine != 'wasm32'" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "platformdirs" }, - { name = "py-cpuinfo", marker = "platform_machine != 'wasm32'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "requests" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/07/14/f5287028e013d16ab6dadc06b27fd5cb37fa9992c6fed4918ba8bb9889be/blosc2-3.12.2.tar.gz", hash = "sha256:a42f915c4b73e788bdc205c5473dcd8dd7a0290693408be471391d0ca65fe39f", size = 3974613, upload-time = "2025-12-04T11:43:31.426Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/05/95243e34a79b379dbcd10006fbb170d7195fe6c5c9487a0cb0788d0bc980/blosc2-4.0.0.tar.gz", hash = "sha256:aa28272fab4ba23b82396759bd05b6f99ac51a37388abef290e901cb071caf1c", size = 3986093, upload-time = "2026-01-29T13:04:45.754Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/38/d3/cf168f10d53b70762e2c0a1bca5fd125b0ca96a63f2c0b8b3ce1c4dd2859/blosc2-3.12.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8a029e81341ecff6a6ffb978576989b4181ed9828484f37da33bdaec78417aa5", size = 3958786, upload-time = "2025-12-04T11:42:46.117Z" }, - { url = "https://files.pythonhosted.org/packages/57/3d/853f04bfed2c9dc90a33cc2df7e80c06b708f4ef0e028624a0d948a584e7/blosc2-3.12.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7d6c474246b08867d4ec08eb2172de8e57a33d9b800a4d1bdab9968d13018633", size = 3460665, upload-time = "2025-12-04T11:42:48.133Z" }, - { url = "https://files.pythonhosted.org/packages/d0/0d/f500f07469494f8931fa9538b3a0da68ba63eedd043a827f8a6b8d2f711e/blosc2-3.12.2-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:248860b909fb1439c4a79e844eec618327b1404bfc7ef2d8b4c25e2bf063bb01", size = 4378812, upload-time = "2025-12-04T11:42:49.987Z" }, - { url = "https://files.pythonhosted.org/packages/a8/73/680aaee6611f3225e473a2f915883568d6e76a0e790e951f7ef9cb9f8c9e/blosc2-3.12.2-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2e755377b241df0005006d96467d02b985c0fc3cca8c3a4ecf503e0207141f4a", size = 4513720, upload-time = "2025-12-04T11:42:51.679Z" }, - { url = "https://files.pythonhosted.org/packages/c2/fc/764772835f22befbb6c7d9ef83d42561e15c94ba87f28958f8a49a3907e8/blosc2-3.12.2-cp310-cp310-win_amd64.whl", hash = "sha256:e85e3a20039181e9b1ad7a47cce5b263a3d2d94d2436cb4c805b8ea163d79903", size = 2282056, upload-time = "2025-12-04T11:42:52.972Z" }, - { url = "https://files.pythonhosted.org/packages/39/8e/a688d09de8214c2f4750c0975d91a52f3137d8a68b2e09501e6398f2d8c9/blosc2-3.12.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:124c591fd992ba5b3974367f7e187c4a9f1fabfca036ea1c064d494cd56911d3", size = 3955992, upload-time = "2025-12-04T11:42:54.274Z" }, - { url = "https://files.pythonhosted.org/packages/9d/87/80cf86d5d953940bffc1caa5b751b2786e263e08e4d7c4b252143129dd9b/blosc2-3.12.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6a7e5b6a7ce289bb30e6023374b92602805afd7145c058b12fe0200d505db149", size = 3458387, upload-time = "2025-12-04T11:42:55.648Z" }, - { url = "https://files.pythonhosted.org/packages/2e/66/8a4bbc2f6b13d8738d2275b777e093a0f86fe3aaf39f1dee37794097b04b/blosc2-3.12.2-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:467255d5c6f9ec859c8b5f88df57653928d4e508b139e937b5a0430449a673e8", size = 4378713, upload-time = "2025-12-04T11:42:57.357Z" }, - { url = "https://files.pythonhosted.org/packages/86/cb/774aad14385f3b9d02bf84a64614db8cb63a4fecfa7b3cf0b30aa8690347/blosc2-3.12.2-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:74f3b8cc2d9033f5316dafb320fde3f7529a8ad4a5d5cd3349d7616b1898d43c", size = 4512707, upload-time = "2025-12-04T11:42:58.734Z" }, - { url = "https://files.pythonhosted.org/packages/b1/60/e2f3805f43dc7a78a7c031b74181d3fbadb4f72c7c8eb85b41d7ab289b87/blosc2-3.12.2-cp311-cp311-win_amd64.whl", hash = "sha256:6513f06625d6417a30989875bac49e5bff7dfce8e900b4c7fb6308c159fb284b", size = 2282086, upload-time = "2025-12-04T11:43:00.346Z" }, - { url = "https://files.pythonhosted.org/packages/10/48/7e146eb59d00deef7f4266205cf4384cdaebf897b3ad18a361db0762b54d/blosc2-3.12.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:53e2c0729cd09c342ad113bf46990b7ca9803732dd89a0523a2f4889a29e2bc9", size = 3999740, upload-time = "2025-12-04T11:43:01.596Z" }, - { url = "https://files.pythonhosted.org/packages/6f/5b/e635eea25ffa8365f8693082adeadf3ab12b823c0be0efe27b397d5af20b/blosc2-3.12.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a0f69e50d127b039764cdcbceb2d7d58a0597c7ba51a18c62cefbcc3fc0c26cd", size = 3459066, upload-time = "2025-12-04T11:43:03.098Z" }, - { url = "https://files.pythonhosted.org/packages/81/8b/b1cf8253ed3305c76d709be8dccf554e3f89ea4bae320db1ea913f385af3/blosc2-3.12.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:9049b7d87a87ca77d78b9ac9e3714e0a42e23dc65ae92bd54ad6ffa74ef16b8b", size = 4358079, upload-time = "2025-12-04T11:43:04.569Z" }, - { url = "https://files.pythonhosted.org/packages/3a/47/b00b50be18b218ddda98e37cab173022544272940b2a39820d1504b4c246/blosc2-3.12.2-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7bd49b853e746923748f7cec6011b5dd8a9ebac647ac1625c362ef191fa453d3", size = 4494354, upload-time = "2025-12-04T11:43:06.252Z" }, - { url = "https://files.pythonhosted.org/packages/0a/59/b88f39271b44d4d34e2ff011eb7b1e9b2905d0095e0fa94ec1f84a5fb0cb/blosc2-3.12.2-cp312-cp312-win_amd64.whl", hash = "sha256:598d40f1b91450bb2d8465f2819fc3bace017a42c5d9f2d25cd142eda0708efe", size = 2266229, upload-time = "2025-12-04T11:43:07.489Z" }, - { url = "https://files.pythonhosted.org/packages/48/80/60a87aad4c4195ecf72aa471bbe220918c7dcf8964d939ed561dbc2377c1/blosc2-3.12.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:27b7772ed5e5a853a8bb2350cef2c7883c92256396c0eef499f419d87c91802b", size = 3999662, upload-time = "2025-12-04T11:43:08.715Z" }, - { url = "https://files.pythonhosted.org/packages/77/ba/f0dde80fc1e23828f9a69e8b73db0adb9d81eec1ac81b4b2dedaabfd28ff/blosc2-3.12.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f1d889a222b98d26b0031141685ec174b0fc9118f1e22c43dd0b65508c12970a", size = 3458834, upload-time = "2025-12-04T11:43:10.075Z" }, - { url = "https://files.pythonhosted.org/packages/f1/d4/b8801ae11cbf5acfb1e55ce3e1206840449b94b61dbd912a3e4c3793da0a/blosc2-3.12.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e17c5f6ba010a33700586bb921ca72efd46223a22f3695dcecfabbb7ed452e58", size = 4357441, upload-time = "2025-12-04T11:43:11.439Z" }, - { url = "https://files.pythonhosted.org/packages/aa/07/520849e62f3c62a6cad7c76559adceaba032ddb26c3d9e1da381bc18b5ea/blosc2-3.12.2-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e597b9c2bdd475159ee35684df1d6a4291cb5f3d7fb178734c81f033d17a9130", size = 4495409, upload-time = "2025-12-04T11:43:12.696Z" }, - { url = "https://files.pythonhosted.org/packages/69/e5/fd327ac868415958656d750f0ec8d63d94045053ba2e811c741134f83282/blosc2-3.12.2-cp313-cp313-win_amd64.whl", hash = "sha256:fde3d9c9f6279b93cf6c62177e5c873add2cd625bb220bc96b4928e93c81bda0", size = 2267508, upload-time = "2025-12-04T11:43:14.26Z" }, - { url = "https://files.pythonhosted.org/packages/40/79/2311808a45bc995f6f47649e07df927422934f8fc3ebc0c94fee39258c09/blosc2-3.12.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:0b0ec1e6d671f28cc0586ce832c03680d2bba3512689f5092028fc479fab37c9", size = 4001285, upload-time = "2025-12-04T11:43:15.881Z" }, - { url = "https://files.pythonhosted.org/packages/db/c6/745443986691ca40a7a279f3c0902c1c256997ccb72ca7d4a031a0fd753b/blosc2-3.12.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:523b03cd1cafaa9bbaf69cd3f564db17ba60597b49082f874e280333d2098c8b", size = 3461017, upload-time = "2025-12-04T11:43:17.732Z" }, - { url = "https://files.pythonhosted.org/packages/7e/94/082e63d85ff1ee2ca3a5f6286e755b236c90e9442310244c0b196761a49f/blosc2-3.12.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c807d5c6119e1aeb03ac620eaddf4c5424c06a73ff76e465db0d716d8cdc0ac6", size = 4362585, upload-time = "2025-12-04T11:43:19.022Z" }, - { url = "https://files.pythonhosted.org/packages/7f/d3/818e964889ed57278d646df6b9686da8335f6cf88c9c85ac4f184013db71/blosc2-3.12.2-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b912b6b4a7dd5e47eec7bd61ea2844a0313a838969115a7af0a7623b4b23a06d", size = 4494766, upload-time = "2025-12-04T11:43:20.782Z" }, - { url = "https://files.pythonhosted.org/packages/91/41/ad1bea85c2ea9cb63869883142b815c2257775c14045786e8a33708b7801/blosc2-3.12.2-cp314-cp314-win_amd64.whl", hash = "sha256:5ab38c57acdc6401c068a6aaccd6cdf799234ab0ac7b2988aa94383c2b944558", size = 2313056, upload-time = "2025-12-04T11:43:22.127Z" }, - { url = "https://files.pythonhosted.org/packages/a1/58/1a6626dd58d97da1308bc446e245ba9501025021711da8ae0f4b7bca6b56/blosc2-3.12.2-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:92859953744d321fd69152020aaff6925ef1a40fbe3ec0a8268cfdac841c871d", size = 4017448, upload-time = "2025-12-04T11:43:23.731Z" }, - { url = "https://files.pythonhosted.org/packages/c0/bb/74a71ff64340271839119b5d6f3d98ebbd090bdc549fc56e8d03c2460e95/blosc2-3.12.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:3e590eb589c1096a35d6b55d69443564d3d00d69ca60b36ff405511f28b091f8", size = 3481529, upload-time = "2025-12-04T11:43:25.16Z" }, - { url = "https://files.pythonhosted.org/packages/3b/9d/18cd9c74e2123fdcb6448f2cb90f2ca40e29f61ba4cddb6b4e9bdca502b0/blosc2-3.12.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4d53885643a0c817bff7856216a34dc8edf0d43d51c371b383511fdeb9f9a7ff", size = 4348228, upload-time = "2025-12-04T11:43:26.584Z" }, - { url = "https://files.pythonhosted.org/packages/9c/19/7f07a51f99329b9f0cfc296c872254e503fc6dcbdebb9998e1372036d22c/blosc2-3.12.2-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5b41420a374ff2628f45c653674b7dfa6eabf994b849c7e4cafa792a0d3ce3b", size = 4481547, upload-time = "2025-12-04T11:43:28.406Z" }, - { url = "https://files.pythonhosted.org/packages/c2/41/80558a50eaa253e029833ccc31442392734ce82f86433e93c32e2f8194a0/blosc2-3.12.2-cp314-cp314t-win_amd64.whl", hash = "sha256:619bbc1bf2543fc3f40407915abb71f16f19b0f575856b0f208863c5fa10f852", size = 2356076, upload-time = "2025-12-04T11:43:29.723Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6a/7d8fbe1306adb02fb66a54232df3572236e33e20613798558df2b309c60d/blosc2-4.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:883ce07b4b363490d9f64fc0ed44fd7a16522b9566f1ecf2033a64d5565db6fa", size = 4164852, upload-time = "2026-01-29T13:03:53.197Z" }, + { url = "https://files.pythonhosted.org/packages/9b/c2/04dc00ca0d51f7ed3b8d20bb36f704e0214e7eada83bd6b86a7dc3c8f60d/blosc2-4.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f2b5b34ea20c63760ca6d09c8a788f131f956ce187d94e4e4f8c02fda173459", size = 3637427, upload-time = "2026-01-29T13:03:55.522Z" }, + { url = "https://files.pythonhosted.org/packages/34/e1/74428ea7980c305860758d4ebe42016d4eb39dbb425a857d2c16925d71c2/blosc2-4.0.0-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cbefdaba0572eba7833b325c835ab27a5a0561958780a94523b456bbb8c76cf8", size = 4582088, upload-time = "2026-01-29T13:03:56.98Z" }, + { url = "https://files.pythonhosted.org/packages/66/75/e053deb51caaa4658d79b087e46cbec01b19d3d59f8ed7e4bc4308f0362e/blosc2-4.0.0-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:c80def4feef91c34e3dcbd89af0c982639f0e849c8f695a79d43c5d053434527", size = 4718022, upload-time = "2026-01-29T13:03:58.604Z" }, + { url = "https://files.pythonhosted.org/packages/79/18/323a86c26990f7a3dd72621744e42510178a45e6ff28261aadf1757d8efa/blosc2-4.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:66d05e927d69eefc798330a5fe5a6a4ee3f0eb9601f64f6eab71dd417750b45e", size = 2692721, upload-time = "2026-01-29T13:04:00.471Z" }, + { url = "https://files.pythonhosted.org/packages/36/41/458765ea5e0e4d912d8ebd8cc4ffef0f09ee95f8975126cc24b920d44e28/blosc2-4.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4ff5123b565768f7e2549fbe9b6b5b31527c5c3e8bb6bc3372d3015194f7f670", size = 4162592, upload-time = "2026-01-29T13:04:02.351Z" }, + { url = "https://files.pythonhosted.org/packages/1e/f8/7e80b73e12533f6608375a4397e2d5bf90aa0e37aa6d62af5d2d9d915340/blosc2-4.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:34f849d630e6e9e0016c6fb309c223fa20e9076374d16369183a0a466933568d", size = 3634801, upload-time = "2026-01-29T13:04:04.199Z" }, + { url = "https://files.pythonhosted.org/packages/4b/dd/c37647e7c76d6a6d3ecd83d51e26d37e0c605ee13f338151a083ceb635fd/blosc2-4.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:4c69d3435b027aff7e200bc8ba91532fc888628e18e6edc051727ca0d4c8d49c", size = 4581563, upload-time = "2026-01-29T13:04:06.25Z" }, + { url = "https://files.pythonhosted.org/packages/88/3f/e1b801e3b56a356f799f604adaaaaffbe2a4fdb902e035c4cc11bd90bc6f/blosc2-4.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4f4abe20c5b87a11a6ad773b34967d5ca36fd1a64dd57337fda08c0fd2a30f15", size = 4716712, upload-time = "2026-01-29T13:04:07.796Z" }, + { url = "https://files.pythonhosted.org/packages/c1/01/6ff32c4e6e13069f226cddf14abc0f075b8699e345e2d411b6874135b421/blosc2-4.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:e128e4c4ee13cfedd2faeb7cb67021f3a015658daf758862e6c0e865e758cca8", size = 2691477, upload-time = "2026-01-29T13:04:09.157Z" }, + { url = "https://files.pythonhosted.org/packages/f4/3e/a0f5722a0607c578f7398b319b6b3c7853e86dd40b487188f462e09a9ebf/blosc2-4.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3835809757bd3cc49450998eb4931f33f6f2ca54732fe5250e148d0f66f30464", size = 4207565, upload-time = "2026-01-29T13:04:10.591Z" }, + { url = "https://files.pythonhosted.org/packages/94/dd/ca0c1ffa41f1aeb3b167e57689bf4414e8e2f77866645d95a9cb7f3724d8/blosc2-4.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:628a9de17895d16d1ab19cfb137f3c24544309e2e1d317c0ed47a29411c55d0a", size = 3635889, upload-time = "2026-01-29T13:04:12.902Z" }, + { url = "https://files.pythonhosted.org/packages/88/d1/74d588d26d6c969f5093f11de5e854c08d076dd4576c577e5a606b882725/blosc2-4.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:2cfc8142db0e7d1fe4ecdb9d1df56cdfbb6faecaf254b505021524c4ba3a91ad", size = 4560853, upload-time = "2026-01-29T13:04:14.795Z" }, + { url = "https://files.pythonhosted.org/packages/7f/ad/ed66f7dd3d5e595a8bf1e115a54f77a185b616eb49ea94fe052c7fd4259e/blosc2-4.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0251050ede06d44355a89a839bb1565ea5baa8e3563b19c13e8a23f597fac58e", size = 4696784, upload-time = "2026-01-29T13:04:16.969Z" }, + { url = "https://files.pythonhosted.org/packages/fb/f1/cea2a12e4fcf11f0d6aa3554229a2011099661fa6ff7c4bd9e0304b038bb/blosc2-4.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a5c0749625c21dc972e9e40cf333c49bb0859f6dd87dc81028951d7cab1716b5", size = 2693460, upload-time = "2026-01-29T13:04:18.475Z" }, + { url = "https://files.pythonhosted.org/packages/34/89/1c9d16c9c903e7910cc1bab53f168d964bded7d23733d3d111c1e27b7868/blosc2-4.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c6bcf17149633b504fb578ab5faec3d45616c90cbb78e2735a0b68fc395191d4", size = 4207392, upload-time = "2026-01-29T13:04:19.82Z" }, + { url = "https://files.pythonhosted.org/packages/e7/05/7b45d105d70402d49508e31ab836dcc3f9daa8e343ce00715b9b43b0da63/blosc2-4.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6c7e1dd84bbf83d6990d27548304a57dd1196c647a5a47a3718f6426eda46ffa", size = 3635266, upload-time = "2026-01-29T13:04:21.37Z" }, + { url = "https://files.pythonhosted.org/packages/7f/4f/b2f6aa2ddf4a1171c0a2114cb462ddb66ef8306b1e6f3157d2e43e98d44d/blosc2-4.0.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3521447f1acea4305d6bbb7936503776b8a1be4fa8f1d6a562c309a941f7ae90", size = 4560514, upload-time = "2026-01-29T13:04:22.759Z" }, + { url = "https://files.pythonhosted.org/packages/ae/25/5f251369f1ad09a4c33b21cc82fb696ab7d1239f1e7b06ffe5eac4b244ff/blosc2-4.0.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:aa0631dde35c869a83b49abd7da9f992f2d1211dae1ad96544e0d7728340aa17", size = 4697793, upload-time = "2026-01-29T13:04:24.219Z" }, + { url = "https://files.pythonhosted.org/packages/de/2e/c50a63cffe2b59ba7fc72135d3ab1ac552069aae6d13b3984f462fbc7128/blosc2-4.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:ce28ae35ce7a8a1668a240fd63b677f43132ce5800604ebb1a04c2b17a6f94f6", size = 2693467, upload-time = "2026-01-29T13:04:26.393Z" }, + { url = "https://files.pythonhosted.org/packages/3a/22/13909df4020ece723f141f50f76ff577b243c499a67b6742b0b369ace2df/blosc2-4.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:a1798734fc519eccc178c28c02d142f5c3d902ced3b14293133f5b89cc7fa12b", size = 4209046, upload-time = "2026-01-29T13:04:29.217Z" }, + { url = "https://files.pythonhosted.org/packages/ac/fc/17215e2188292f89966b0c0e5dc43ff9542c70a4919680971ad164772940/blosc2-4.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:49a1148b074ec4c8cd610c33829aebe661a7e507f7d0345be05238d07f4d9dbb", size = 3638169, upload-time = "2026-01-29T13:04:31.466Z" }, + { url = "https://files.pythonhosted.org/packages/a7/37/28d99a88cb5c0c4f3ab0bd57603f6a21ffa7fbf0a125a358356c89d11049/blosc2-4.0.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:07ad63ee7de85228cc37a591829869ba8f8cab21a0e60eeba7889b7024d44955", size = 4564448, upload-time = "2026-01-29T13:04:32.888Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/26d6f259bd9fb7162f431e45d73282478d6915328e564088c2ffeb693678/blosc2-4.0.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:54d1ac3186abde31d0a56ccf7bc573592cdbdf96018674344937634003e51893", size = 4698032, upload-time = "2026-01-29T13:04:34.324Z" }, + { url = "https://files.pythonhosted.org/packages/6e/d1/2a5d14d89f3fc1942de698a9057467f0f25f789cd5f960ba130ae59ca559/blosc2-4.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:e4043dd04a400f20755963e1908a0cd55216aef238336344a404101a7d7a6562", size = 2753873, upload-time = "2026-01-29T13:04:36.294Z" }, + { url = "https://files.pythonhosted.org/packages/4c/27/d534bbf0b3306b15e13d64dc513c473353cb6bfdf6617084cc5c4f6492da/blosc2-4.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:98b6229728f13585bb445327716dd77a67c6b9b7050dac7f152c0fde6d56f935", size = 4224248, upload-time = "2026-01-29T13:04:37.837Z" }, + { url = "https://files.pythonhosted.org/packages/47/fb/359813bd8bf1c9413fb880c415723f9ac380f04f26a6ec1d65433163b003/blosc2-4.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:5f380fc0fd74461c383a9ea8c55f59ccff86514a7142096c7bcf316b8117342f", size = 3658707, upload-time = "2026-01-29T13:04:39.219Z" }, + { url = "https://files.pythonhosted.org/packages/14/8c/17d7ef7b872503d138e3835637c57b839058e54c864747e9b8eafab17017/blosc2-4.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ea6734b79f64a68fb5165f0f07de4c20b930f46c123b9a2ef63843a855b1c006", size = 4549229, upload-time = "2026-01-29T13:04:41.178Z" }, + { url = "https://files.pythonhosted.org/packages/cf/48/d6d7a6aec1b4226537732bb4d35e3c973d6dbcf96dd9363e38e44dd559f3/blosc2-4.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d5d5852a4fad0fcea57614861bc8cc27bbcdf0461c0ed0d3b35dc9e3a5fb7d4d", size = 4683364, upload-time = "2026-01-29T13:04:42.817Z" }, + { url = "https://files.pythonhosted.org/packages/df/df/f0675137d235aad2ba2549147c75647db6b303539190dcd409913a90240a/blosc2-4.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:c75c313b5605c9da04b2f92374b93a052a750dd0bdfd96584c9edc29a332bd70", size = 2776799, upload-time = "2026-01-29T13:04:44.31Z" }, ] [[package]] @@ -321,20 +323,21 @@ wheels = [ [[package]] name = "exchange-calendars" -version = "4.12" +version = "4.13.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "korean-lunar-calendar" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pandas" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pyluach" }, { name = "toolz" }, { name = "tzdata" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/84/28/80b13e1c61ad10fb6b15c6005784a0df9b07953de05b3f1a4fda78447560/exchange_calendars-4.12.tar.gz", hash = "sha256:7d2049b624013eb67cb06feb4fd29825a8d53c0c03bf8e7f9d856c210f24eb8a", size = 4114218, upload-time = "2026-01-08T03:47:59.711Z" } +sdist = { url = "https://files.pythonhosted.org/packages/9e/fd/1bda66b3c2fefbf54b8cf765c9d8001b12654b5a897a21b0c6c9f55de5e3/exchange_calendars-4.13.1.tar.gz", hash = "sha256:42a4c7296da1f71b9625c668c9b3359cf5de4a2ffca28842b230e062bb4961ba", size = 4119843, upload-time = "2026-02-05T00:15:03.947Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/dd/67/aebf63806dd9893a1eead8e9dc564f5fb6599d7d80561f1b52ea47938e47/exchange_calendars-4.12-py3-none-any.whl", hash = "sha256:133946b468d00401f7e622fc4e198ec3a26cba7524ec357bb8597be4ddaf584e", size = 211172, upload-time = "2026-01-08T03:47:58.153Z" }, + { url = "https://files.pythonhosted.org/packages/45/b7/fffe7d5a6da6be10b43be96640f31d4191e746de66b046cc1a6ea5fc4f26/exchange_calendars-4.13.1-py3-none-any.whl", hash = "sha256:cf39d2128a4da3ac253283f91ab63d79930a68196a3aac811091a4e38b6cbe49", size = 211538, upload-time = "2026-02-05T00:15:05.694Z" }, ] [[package]] @@ -348,15 +351,15 @@ wheels = [ [[package]] name = "hypothesis" -version = "6.150.2" +version = "6.151.5" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, { name = "sortedcontainers" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/d2/19/a4eee0c98e2ec678854272f79646f34943f8fbbc42689cc355b530c5bc96/hypothesis-6.150.2.tar.gz", hash = "sha256:deb043c41c53eaf0955f4a08739c2a34c3d8040ee3d9a2da0aa5470122979f75", size = 475250, upload-time = "2026-01-13T17:09:22.146Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/d7/c40dcd401cc360d8d084e584ffb7ab17255fde22e2b9cf2b53bf25aed629/hypothesis-6.151.5.tar.gz", hash = "sha256:ae3a0622f9693e6b19c697777c2c266c02801f9769ab7c2c37b7ec83d4743783", size = 475923, upload-time = "2026-02-03T19:33:55.845Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b3/5e/21caad4acf45db7caf730cca1bc61422283e4c4e841efbc862d17ab81a21/hypothesis-6.150.2-py3-none-any.whl", hash = "sha256:648d6a2be435889e713ba3d335b0fb5e7a250f569b56e6867887c1e7a0d1f02f", size = 542712, upload-time = "2026-01-13T17:09:19.945Z" }, + { url = "https://files.pythonhosted.org/packages/c0/d9/53a8b53e75279a953fae608bd01025d9afcf393406c0da1dda1b7f5693c5/hypothesis-6.151.5-py3-none-any.whl", hash = "sha256:c0e15c91fa0e67bc0295551ef5041bebad42753b7977a610cd7a6ec1ad04ef13", size = 543338, upload-time = "2026-02-03T19:33:54.583Z" }, ] [[package]] @@ -397,75 +400,75 @@ wheels = [ [[package]] name = "librt" -version = "0.7.7" +version = "0.7.8" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b7/29/47f29026ca17f35cf299290292d5f8331f5077364974b7675a353179afa2/librt-0.7.7.tar.gz", hash = "sha256:81d957b069fed1890953c3b9c3895c7689960f233eea9a1d9607f71ce7f00b2c", size = 145910, upload-time = "2026-01-01T23:52:22.87Z" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/24/5f3646ff414285e0f7708fa4e946b9bf538345a41d1c375c439467721a5e/librt-0.7.8.tar.gz", hash = "sha256:1a4ede613941d9c3470b0368be851df6bb78ab218635512d0370b27a277a0862", size = 148323, upload-time = "2026-01-14T12:56:16.876Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c6/84/2cfb1f3b9b60bab52e16a220c931223fc8e963d0d7bb9132bef012aafc3f/librt-0.7.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e4836c5645f40fbdc275e5670819bde5ab5f2e882290d304e3c6ddab1576a6d0", size = 54709, upload-time = "2026-01-01T23:50:48.326Z" }, - { url = "https://files.pythonhosted.org/packages/19/a1/3127b277e9d3784a8040a54e8396d9ae5c64d6684dc6db4b4089b0eedcfb/librt-0.7.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6ae8aec43117a645a31e5f60e9e3a0797492e747823b9bda6972d521b436b4e8", size = 56658, upload-time = "2026-01-01T23:50:49.74Z" }, - { url = "https://files.pythonhosted.org/packages/3a/e9/b91b093a5c42eb218120445f3fef82e0b977fa2225f4d6fc133d25cdf86a/librt-0.7.7-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:aea05f701ccd2a76b34f0daf47ca5068176ff553510b614770c90d76ac88df06", size = 161026, upload-time = "2026-01-01T23:50:50.853Z" }, - { url = "https://files.pythonhosted.org/packages/c7/cb/1ded77d5976a79d7057af4a010d577ce4f473ff280984e68f4974a3281e5/librt-0.7.7-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7b16ccaeff0ed4355dfb76fe1ea7a5d6d03b5ad27f295f77ee0557bc20a72495", size = 169529, upload-time = "2026-01-01T23:50:52.24Z" }, - { url = "https://files.pythonhosted.org/packages/da/6e/6ca5bdaa701e15f05000ac1a4c5d1475c422d3484bd3d1ca9e8c2f5be167/librt-0.7.7-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c48c7e150c095d5e3cea7452347ba26094be905d6099d24f9319a8b475fcd3e0", size = 183271, upload-time = "2026-01-01T23:50:55.287Z" }, - { url = "https://files.pythonhosted.org/packages/e7/2d/55c0e38073997b4bbb5ddff25b6d1bbba8c2f76f50afe5bb9c844b702f34/librt-0.7.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4dcee2f921a8632636d1c37f1bbdb8841d15666d119aa61e5399c5268e7ce02e", size = 179039, upload-time = "2026-01-01T23:50:56.807Z" }, - { url = "https://files.pythonhosted.org/packages/33/4e/3662a41ae8bb81b226f3968426293517b271d34d4e9fd4b59fc511f1ae40/librt-0.7.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:14ef0f4ac3728ffd85bfc58e2f2f48fb4ef4fa871876f13a73a7381d10a9f77c", size = 173505, upload-time = "2026-01-01T23:50:58.291Z" }, - { url = "https://files.pythonhosted.org/packages/f8/5d/cf768deb8bdcbac5f8c21fcb32dd483d038d88c529fd351bbe50590b945d/librt-0.7.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e4ab69fa37f8090f2d971a5d2bc606c7401170dbdae083c393d6cbf439cb45b8", size = 193570, upload-time = "2026-01-01T23:50:59.546Z" }, - { url = "https://files.pythonhosted.org/packages/a1/ea/ee70effd13f1d651976d83a2812391f6203971740705e3c0900db75d4bce/librt-0.7.7-cp310-cp310-win32.whl", hash = "sha256:4bf3cc46d553693382d2abf5f5bd493d71bb0f50a7c0beab18aa13a5545c8900", size = 42600, upload-time = "2026-01-01T23:51:00.694Z" }, - { url = "https://files.pythonhosted.org/packages/f0/eb/dc098730f281cba76c279b71783f5de2edcba3b880c1ab84a093ef826062/librt-0.7.7-cp310-cp310-win_amd64.whl", hash = "sha256:f0c8fe5aeadd8a0e5b0598f8a6ee3533135ca50fd3f20f130f9d72baf5c6ac58", size = 48977, upload-time = "2026-01-01T23:51:01.726Z" }, - { url = "https://files.pythonhosted.org/packages/f0/56/30b5c342518005546df78841cb0820ae85a17e7d07d521c10ef367306d0d/librt-0.7.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a487b71fbf8a9edb72a8c7a456dda0184642d99cd007bc819c0b7ab93676a8ee", size = 54709, upload-time = "2026-01-01T23:51:02.774Z" }, - { url = "https://files.pythonhosted.org/packages/72/78/9f120e3920b22504d4f3835e28b55acc2cc47c9586d2e1b6ba04c3c1bf01/librt-0.7.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f4d4efb218264ecf0f8516196c9e2d1a0679d9fb3bb15df1155a35220062eba8", size = 56663, upload-time = "2026-01-01T23:51:03.838Z" }, - { url = "https://files.pythonhosted.org/packages/1c/ea/7d7a1ee7dfc1151836028eba25629afcf45b56bbc721293e41aa2e9b8934/librt-0.7.7-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b8bb331aad734b059c4b450cd0a225652f16889e286b2345af5e2c3c625c3d85", size = 161705, upload-time = "2026-01-01T23:51:04.917Z" }, - { url = "https://files.pythonhosted.org/packages/45/a5/952bc840ac8917fbcefd6bc5f51ad02b89721729814f3e2bfcc1337a76d6/librt-0.7.7-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:467dbd7443bda08338fc8ad701ed38cef48194017554f4c798b0a237904b3f99", size = 171029, upload-time = "2026-01-01T23:51:06.09Z" }, - { url = "https://files.pythonhosted.org/packages/fa/bf/c017ff7da82dc9192cf40d5e802a48a25d00e7639b6465cfdcee5893a22c/librt-0.7.7-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50d1d1ee813d2d1a3baf2873634ba506b263032418d16287c92ec1cc9c1a00cb", size = 184704, upload-time = "2026-01-01T23:51:07.549Z" }, - { url = "https://files.pythonhosted.org/packages/77/ec/72f3dd39d2cdfd6402ab10836dc9cbf854d145226062a185b419c4f1624a/librt-0.7.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c7e5070cf3ec92d98f57574da0224f8c73faf1ddd6d8afa0b8c9f6e86997bc74", size = 180719, upload-time = "2026-01-01T23:51:09.062Z" }, - { url = "https://files.pythonhosted.org/packages/78/86/06e7a1a81b246f3313bf515dd9613a1c81583e6fd7843a9f4d625c4e926d/librt-0.7.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bdb9f3d865b2dafe7f9ad7f30ef563c80d0ddd2fdc8cc9b8e4f242f475e34d75", size = 174537, upload-time = "2026-01-01T23:51:10.611Z" }, - { url = "https://files.pythonhosted.org/packages/83/08/f9fb2edc9c7a76e95b2924ce81d545673f5b034e8c5dd92159d1c7dae0c6/librt-0.7.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:8185c8497d45164e256376f9da5aed2bb26ff636c798c9dabe313b90e9f25b28", size = 195238, upload-time = "2026-01-01T23:51:11.762Z" }, - { url = "https://files.pythonhosted.org/packages/ba/56/ea2d2489d3ea1f47b301120e03a099e22de7b32c93df9a211e6ff4f9bf38/librt-0.7.7-cp311-cp311-win32.whl", hash = "sha256:44d63ce643f34a903f09ff7ca355aae019a3730c7afd6a3c037d569beeb5d151", size = 42939, upload-time = "2026-01-01T23:51:13.192Z" }, - { url = "https://files.pythonhosted.org/packages/58/7b/c288f417e42ba2a037f1c0753219e277b33090ed4f72f292fb6fe175db4c/librt-0.7.7-cp311-cp311-win_amd64.whl", hash = "sha256:7d13cc340b3b82134f8038a2bfe7137093693dcad8ba5773da18f95ad6b77a8a", size = 49240, upload-time = "2026-01-01T23:51:14.264Z" }, - { url = "https://files.pythonhosted.org/packages/7c/24/738eb33a6c1516fdb2dfd2a35db6e5300f7616679b573585be0409bc6890/librt-0.7.7-cp311-cp311-win_arm64.whl", hash = "sha256:983de36b5a83fe9222f4f7dcd071f9b1ac6f3f17c0af0238dadfb8229588f890", size = 42613, upload-time = "2026-01-01T23:51:15.268Z" }, - { url = "https://files.pythonhosted.org/packages/56/72/1cd9d752070011641e8aee046c851912d5f196ecd726fffa7aed2070f3e0/librt-0.7.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2a85a1fc4ed11ea0eb0a632459ce004a2d14afc085a50ae3463cd3dfe1ce43fc", size = 55687, upload-time = "2026-01-01T23:51:16.291Z" }, - { url = "https://files.pythonhosted.org/packages/50/aa/d5a1d4221c4fe7e76ae1459d24d6037783cb83c7645164c07d7daf1576ec/librt-0.7.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c87654e29a35938baead1c4559858f346f4a2a7588574a14d784f300ffba0efd", size = 57136, upload-time = "2026-01-01T23:51:17.363Z" }, - { url = "https://files.pythonhosted.org/packages/23/6f/0c86b5cb5e7ef63208c8cc22534df10ecc5278efc0d47fb8815577f3ca2f/librt-0.7.7-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:c9faaebb1c6212c20afd8043cd6ed9de0a47d77f91a6b5b48f4e46ed470703fe", size = 165320, upload-time = "2026-01-01T23:51:18.455Z" }, - { url = "https://files.pythonhosted.org/packages/16/37/df4652690c29f645ffe405b58285a4109e9fe855c5bb56e817e3e75840b3/librt-0.7.7-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1908c3e5a5ef86b23391448b47759298f87f997c3bd153a770828f58c2bb4630", size = 174216, upload-time = "2026-01-01T23:51:19.599Z" }, - { url = "https://files.pythonhosted.org/packages/9a/d6/d3afe071910a43133ec9c0f3e4ce99ee6df0d4e44e4bddf4b9e1c6ed41cc/librt-0.7.7-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:dbc4900e95a98fc0729523be9d93a8fedebb026f32ed9ffc08acd82e3e181503", size = 189005, upload-time = "2026-01-01T23:51:21.052Z" }, - { url = "https://files.pythonhosted.org/packages/d5/18/74060a870fe2d9fd9f47824eba6717ce7ce03124a0d1e85498e0e7efc1b2/librt-0.7.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a7ea4e1fbd253e5c68ea0fe63d08577f9d288a73f17d82f652ebc61fa48d878d", size = 183961, upload-time = "2026-01-01T23:51:22.493Z" }, - { url = "https://files.pythonhosted.org/packages/7c/5e/918a86c66304af66a3c1d46d54df1b2d0b8894babc42a14fb6f25511497f/librt-0.7.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ef7699b7a5a244b1119f85c5bbc13f152cd38240cbb2baa19b769433bae98e50", size = 177610, upload-time = "2026-01-01T23:51:23.874Z" }, - { url = "https://files.pythonhosted.org/packages/b2/d7/b5e58dc2d570f162e99201b8c0151acf40a03a39c32ab824dd4febf12736/librt-0.7.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:955c62571de0b181d9e9e0a0303c8bc90d47670a5eff54cf71bf5da61d1899cf", size = 199272, upload-time = "2026-01-01T23:51:25.341Z" }, - { url = "https://files.pythonhosted.org/packages/18/87/8202c9bd0968bdddc188ec3811985f47f58ed161b3749299f2c0dd0f63fb/librt-0.7.7-cp312-cp312-win32.whl", hash = "sha256:1bcd79be209313b270b0e1a51c67ae1af28adad0e0c7e84c3ad4b5cb57aaa75b", size = 43189, upload-time = "2026-01-01T23:51:26.799Z" }, - { url = "https://files.pythonhosted.org/packages/61/8d/80244b267b585e7aa79ffdac19f66c4861effc3a24598e77909ecdd0850e/librt-0.7.7-cp312-cp312-win_amd64.whl", hash = "sha256:4353ee891a1834567e0302d4bd5e60f531912179578c36f3d0430f8c5e16b456", size = 49462, upload-time = "2026-01-01T23:51:27.813Z" }, - { url = "https://files.pythonhosted.org/packages/2d/1f/75db802d6a4992d95e8a889682601af9b49d5a13bbfa246d414eede1b56c/librt-0.7.7-cp312-cp312-win_arm64.whl", hash = "sha256:a76f1d679beccccdf8c1958e732a1dfcd6e749f8821ee59d7bec009ac308c029", size = 42828, upload-time = "2026-01-01T23:51:28.804Z" }, - { url = "https://files.pythonhosted.org/packages/8d/5e/d979ccb0a81407ec47c14ea68fb217ff4315521730033e1dd9faa4f3e2c1/librt-0.7.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8f4a0b0a3c86ba9193a8e23bb18f100d647bf192390ae195d84dfa0a10fb6244", size = 55746, upload-time = "2026-01-01T23:51:29.828Z" }, - { url = "https://files.pythonhosted.org/packages/f5/2c/3b65861fb32f802c3783d6ac66fc5589564d07452a47a8cf9980d531cad3/librt-0.7.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5335890fea9f9e6c4fdf8683061b9ccdcbe47c6dc03ab8e9b68c10acf78be78d", size = 57174, upload-time = "2026-01-01T23:51:31.226Z" }, - { url = "https://files.pythonhosted.org/packages/50/df/030b50614b29e443607220097ebaf438531ea218c7a9a3e21ea862a919cd/librt-0.7.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b4346b1225be26def3ccc6c965751c74868f0578cbcba293c8ae9168483d811", size = 165834, upload-time = "2026-01-01T23:51:32.278Z" }, - { url = "https://files.pythonhosted.org/packages/5d/e1/bd8d1eacacb24be26a47f157719553bbd1b3fe812c30dddf121c0436fd0b/librt-0.7.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a10b8eebdaca6e9fdbaf88b5aefc0e324b763a5f40b1266532590d5afb268a4c", size = 174819, upload-time = "2026-01-01T23:51:33.461Z" }, - { url = "https://files.pythonhosted.org/packages/46/7d/91d6c3372acf54a019c1ad8da4c9ecf4fc27d039708880bf95f48dbe426a/librt-0.7.7-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:067be973d90d9e319e6eb4ee2a9b9307f0ecd648b8a9002fa237289a4a07a9e7", size = 189607, upload-time = "2026-01-01T23:51:34.604Z" }, - { url = "https://files.pythonhosted.org/packages/fa/ac/44604d6d3886f791fbd1c6ae12d5a782a8f4aca927484731979f5e92c200/librt-0.7.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:23d2299ed007812cccc1ecef018db7d922733382561230de1f3954db28433977", size = 184586, upload-time = "2026-01-01T23:51:35.845Z" }, - { url = "https://files.pythonhosted.org/packages/5c/26/d8a6e4c17117b7f9b83301319d9a9de862ae56b133efb4bad8b3aa0808c9/librt-0.7.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:6b6f8ea465524aa4c7420c7cc4ca7d46fe00981de8debc67b1cc2e9957bb5b9d", size = 178251, upload-time = "2026-01-01T23:51:37.018Z" }, - { url = "https://files.pythonhosted.org/packages/99/ab/98d857e254376f8e2f668e807daccc1f445e4b4fc2f6f9c1cc08866b0227/librt-0.7.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f8df32a99cc46eb0ee90afd9ada113ae2cafe7e8d673686cf03ec53e49635439", size = 199853, upload-time = "2026-01-01T23:51:38.195Z" }, - { url = "https://files.pythonhosted.org/packages/7c/55/4523210d6ae5134a5da959900be43ad8bab2e4206687b6620befddb5b5fd/librt-0.7.7-cp313-cp313-win32.whl", hash = "sha256:86f86b3b785487c7760247bcdac0b11aa8bf13245a13ed05206286135877564b", size = 43247, upload-time = "2026-01-01T23:51:39.629Z" }, - { url = "https://files.pythonhosted.org/packages/25/40/3ec0fed5e8e9297b1cf1a3836fb589d3de55f9930e3aba988d379e8ef67c/librt-0.7.7-cp313-cp313-win_amd64.whl", hash = "sha256:4862cb2c702b1f905c0503b72d9d4daf65a7fdf5a9e84560e563471e57a56949", size = 49419, upload-time = "2026-01-01T23:51:40.674Z" }, - { url = "https://files.pythonhosted.org/packages/1c/7a/aab5f0fb122822e2acbc776addf8b9abfb4944a9056c00c393e46e543177/librt-0.7.7-cp313-cp313-win_arm64.whl", hash = "sha256:0996c83b1cb43c00e8c87835a284f9057bc647abd42b5871e5f941d30010c832", size = 42828, upload-time = "2026-01-01T23:51:41.731Z" }, - { url = "https://files.pythonhosted.org/packages/69/9c/228a5c1224bd23809a635490a162e9cbdc68d99f0eeb4a696f07886b8206/librt-0.7.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:23daa1ab0512bafdd677eb1bfc9611d8ffbe2e328895671e64cb34166bc1b8c8", size = 55188, upload-time = "2026-01-01T23:51:43.14Z" }, - { url = "https://files.pythonhosted.org/packages/ba/c2/0e7c6067e2b32a156308205e5728f4ed6478c501947e9142f525afbc6bd2/librt-0.7.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:558a9e5a6f3cc1e20b3168fb1dc802d0d8fa40731f6e9932dcc52bbcfbd37111", size = 56895, upload-time = "2026-01-01T23:51:44.534Z" }, - { url = "https://files.pythonhosted.org/packages/0e/77/de50ff70c80855eb79d1d74035ef06f664dd073fb7fb9d9fb4429651b8eb/librt-0.7.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:2567cb48dc03e5b246927ab35cbb343376e24501260a9b5e30b8e255dca0d1d2", size = 163724, upload-time = "2026-01-01T23:51:45.571Z" }, - { url = "https://files.pythonhosted.org/packages/6e/19/f8e4bf537899bdef9e0bb9f0e4b18912c2d0f858ad02091b6019864c9a6d/librt-0.7.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6066c638cdf85ff92fc6f932d2d73c93a0e03492cdfa8778e6d58c489a3d7259", size = 172470, upload-time = "2026-01-01T23:51:46.823Z" }, - { url = "https://files.pythonhosted.org/packages/42/4c/dcc575b69d99076768e8dd6141d9aecd4234cba7f0e09217937f52edb6ed/librt-0.7.7-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a609849aca463074c17de9cda173c276eb8fee9e441053529e7b9e249dc8b8ee", size = 186806, upload-time = "2026-01-01T23:51:48.009Z" }, - { url = "https://files.pythonhosted.org/packages/fe/f8/4094a2b7816c88de81239a83ede6e87f1138477d7ee956c30f136009eb29/librt-0.7.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:add4e0a000858fe9bb39ed55f31085506a5c38363e6eb4a1e5943a10c2bfc3d1", size = 181809, upload-time = "2026-01-01T23:51:49.35Z" }, - { url = "https://files.pythonhosted.org/packages/1b/ac/821b7c0ab1b5a6cd9aee7ace8309c91545a2607185101827f79122219a7e/librt-0.7.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a3bfe73a32bd0bdb9a87d586b05a23c0a1729205d79df66dee65bb2e40d671ba", size = 175597, upload-time = "2026-01-01T23:51:50.636Z" }, - { url = "https://files.pythonhosted.org/packages/71/f9/27f6bfbcc764805864c04211c6ed636fe1d58f57a7b68d1f4ae5ed74e0e0/librt-0.7.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:0ecce0544d3db91a40f8b57ae26928c02130a997b540f908cefd4d279d6c5848", size = 196506, upload-time = "2026-01-01T23:51:52.535Z" }, - { url = "https://files.pythonhosted.org/packages/46/ba/c9b9c6fc931dd7ea856c573174ccaf48714905b1a7499904db2552e3bbaf/librt-0.7.7-cp314-cp314-win32.whl", hash = "sha256:8f7a74cf3a80f0c3b0ec75b0c650b2f0a894a2cec57ef75f6f72c1e82cdac61d", size = 39747, upload-time = "2026-01-01T23:51:53.683Z" }, - { url = "https://files.pythonhosted.org/packages/c5/69/cd1269337c4cde3ee70176ee611ab0058aa42fc8ce5c9dce55f48facfcd8/librt-0.7.7-cp314-cp314-win_amd64.whl", hash = "sha256:3d1fe2e8df3268dd6734dba33ededae72ad5c3a859b9577bc00b715759c5aaab", size = 45971, upload-time = "2026-01-01T23:51:54.697Z" }, - { url = "https://files.pythonhosted.org/packages/79/fd/e0844794423f5583108c5991313c15e2b400995f44f6ec6871f8aaf8243c/librt-0.7.7-cp314-cp314-win_arm64.whl", hash = "sha256:2987cf827011907d3dfd109f1be0d61e173d68b1270107bb0e89f2fca7f2ed6b", size = 39075, upload-time = "2026-01-01T23:51:55.726Z" }, - { url = "https://files.pythonhosted.org/packages/42/02/211fd8f7c381e7b2a11d0fdfcd410f409e89967be2e705983f7c6342209a/librt-0.7.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:8e92c8de62b40bfce91d5e12c6e8b15434da268979b1af1a6589463549d491e6", size = 57368, upload-time = "2026-01-01T23:51:56.706Z" }, - { url = "https://files.pythonhosted.org/packages/4c/b6/aca257affae73ece26041ae76032153266d110453173f67d7603058e708c/librt-0.7.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:f683dcd49e2494a7535e30f779aa1ad6e3732a019d80abe1309ea91ccd3230e3", size = 59238, upload-time = "2026-01-01T23:51:58.066Z" }, - { url = "https://files.pythonhosted.org/packages/96/47/7383a507d8e0c11c78ca34c9d36eab9000db5989d446a2f05dc40e76c64f/librt-0.7.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:9b15e5d17812d4d629ff576699954f74e2cc24a02a4fc401882dd94f81daba45", size = 183870, upload-time = "2026-01-01T23:51:59.204Z" }, - { url = "https://files.pythonhosted.org/packages/a4/b8/50f3d8eec8efdaf79443963624175c92cec0ba84827a66b7fcfa78598e51/librt-0.7.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c084841b879c4d9b9fa34e5d5263994f21aea7fd9c6add29194dbb41a6210536", size = 194608, upload-time = "2026-01-01T23:52:00.419Z" }, - { url = "https://files.pythonhosted.org/packages/23/d9/1b6520793aadb59d891e3b98ee057a75de7f737e4a8b4b37fdbecb10d60f/librt-0.7.7-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:10c8fb9966f84737115513fecbaf257f9553d067a7dd45a69c2c7e5339e6a8dc", size = 206776, upload-time = "2026-01-01T23:52:01.705Z" }, - { url = "https://files.pythonhosted.org/packages/ff/db/331edc3bba929d2756fa335bfcf736f36eff4efcb4f2600b545a35c2ae58/librt-0.7.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9b5fb1ecb2c35362eab2dbd354fd1efa5a8440d3e73a68be11921042a0edc0ff", size = 203206, upload-time = "2026-01-01T23:52:03.315Z" }, - { url = "https://files.pythonhosted.org/packages/b2/e1/6af79ec77204e85f6f2294fc171a30a91bb0e35d78493532ed680f5d98be/librt-0.7.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d1454899909d63cc9199a89fcc4f81bdd9004aef577d4ffc022e600c412d57f3", size = 196697, upload-time = "2026-01-01T23:52:04.857Z" }, - { url = "https://files.pythonhosted.org/packages/f3/46/de55ecce4b2796d6d243295c221082ca3a944dc2fb3a52dcc8660ce7727d/librt-0.7.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:7ef28f2e7a016b29792fe0a2dd04dec75725b32a1264e390c366103f834a9c3a", size = 217193, upload-time = "2026-01-01T23:52:06.159Z" }, - { url = "https://files.pythonhosted.org/packages/41/61/33063e271949787a2f8dd33c5260357e3d512a114fc82ca7890b65a76e2d/librt-0.7.7-cp314-cp314t-win32.whl", hash = "sha256:5e419e0db70991b6ba037b70c1d5bbe92b20ddf82f31ad01d77a347ed9781398", size = 40277, upload-time = "2026-01-01T23:52:07.625Z" }, - { url = "https://files.pythonhosted.org/packages/06/21/1abd972349f83a696ea73159ac964e63e2d14086fdd9bc7ca878c25fced4/librt-0.7.7-cp314-cp314t-win_amd64.whl", hash = "sha256:d6b7d93657332c817b8d674ef6bf1ab7796b4f7ce05e420fd45bd258a72ac804", size = 46765, upload-time = "2026-01-01T23:52:08.647Z" }, - { url = "https://files.pythonhosted.org/packages/51/0e/b756c7708143a63fca65a51ca07990fa647db2cc8fcd65177b9e96680255/librt-0.7.7-cp314-cp314t-win_arm64.whl", hash = "sha256:142c2cd91794b79fd0ce113bd658993b7ede0fe93057668c2f98a45ca00b7e91", size = 39724, upload-time = "2026-01-01T23:52:09.745Z" }, + { url = "https://files.pythonhosted.org/packages/44/13/57b06758a13550c5f09563893b004f98e9537ee6ec67b7df85c3571c8832/librt-0.7.8-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b45306a1fc5f53c9330fbee134d8b3227fe5da2ab09813b892790400aa49352d", size = 56521, upload-time = "2026-01-14T12:54:40.066Z" }, + { url = "https://files.pythonhosted.org/packages/c2/24/bbea34d1452a10612fb45ac8356f95351ba40c2517e429602160a49d1fd0/librt-0.7.8-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:864c4b7083eeee250ed55135d2127b260d7eb4b5e953a9e5df09c852e327961b", size = 58456, upload-time = "2026-01-14T12:54:41.471Z" }, + { url = "https://files.pythonhosted.org/packages/04/72/a168808f92253ec3a810beb1eceebc465701197dbc7e865a1c9ceb3c22c7/librt-0.7.8-cp310-cp310-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:6938cc2de153bc927ed8d71c7d2f2ae01b4e96359126c602721340eb7ce1a92d", size = 164392, upload-time = "2026-01-14T12:54:42.843Z" }, + { url = "https://files.pythonhosted.org/packages/14/5c/4c0d406f1b02735c2e7af8ff1ff03a6577b1369b91aa934a9fa2cc42c7ce/librt-0.7.8-cp310-cp310-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:66daa6ac5de4288a5bbfbe55b4caa7bf0cd26b3269c7a476ffe8ce45f837f87d", size = 172959, upload-time = "2026-01-14T12:54:44.602Z" }, + { url = "https://files.pythonhosted.org/packages/82/5f/3e85351c523f73ad8d938989e9a58c7f59fb9c17f761b9981b43f0025ce7/librt-0.7.8-cp310-cp310-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4864045f49dc9c974dadb942ac56a74cd0479a2aafa51ce272c490a82322ea3c", size = 186717, upload-time = "2026-01-14T12:54:45.986Z" }, + { url = "https://files.pythonhosted.org/packages/08/f8/18bfe092e402d00fe00d33aa1e01dda1bd583ca100b393b4373847eade6d/librt-0.7.8-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a36515b1328dc5b3ffce79fe204985ca8572525452eacabee2166f44bb387b2c", size = 184585, upload-time = "2026-01-14T12:54:47.139Z" }, + { url = "https://files.pythonhosted.org/packages/4e/fc/f43972ff56fd790a9fa55028a52ccea1875100edbb856b705bd393b601e3/librt-0.7.8-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:b7e7f140c5169798f90b80d6e607ed2ba5059784968a004107c88ad61fb3641d", size = 180497, upload-time = "2026-01-14T12:54:48.946Z" }, + { url = "https://files.pythonhosted.org/packages/e1/3a/25e36030315a410d3ad0b7d0f19f5f188e88d1613d7d3fd8150523ea1093/librt-0.7.8-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:ff71447cb778a4f772ddc4ce360e6ba9c95527ed84a52096bd1bbf9fee2ec7c0", size = 200052, upload-time = "2026-01-14T12:54:50.382Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b8/f3a5a1931ae2a6ad92bf6893b9ef44325b88641d58723529e2c2935e8abe/librt-0.7.8-cp310-cp310-win32.whl", hash = "sha256:047164e5f68b7a8ebdf9fae91a3c2161d3192418aadd61ddd3a86a56cbe3dc85", size = 43477, upload-time = "2026-01-14T12:54:51.815Z" }, + { url = "https://files.pythonhosted.org/packages/fe/91/c4202779366bc19f871b4ad25db10fcfa1e313c7893feb942f32668e8597/librt-0.7.8-cp310-cp310-win_amd64.whl", hash = "sha256:d6f254d096d84156a46a84861183c183d30734e52383602443292644d895047c", size = 49806, upload-time = "2026-01-14T12:54:53.149Z" }, + { url = "https://files.pythonhosted.org/packages/1b/a3/87ea9c1049f2c781177496ebee29430e4631f439b8553a4969c88747d5d8/librt-0.7.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ff3e9c11aa260c31493d4b3197d1e28dd07768594a4f92bec4506849d736248f", size = 56507, upload-time = "2026-01-14T12:54:54.156Z" }, + { url = "https://files.pythonhosted.org/packages/5e/4a/23bcef149f37f771ad30203d561fcfd45b02bc54947b91f7a9ac34815747/librt-0.7.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ddb52499d0b3ed4aa88746aaf6f36a08314677d5c346234c3987ddc506404eac", size = 58455, upload-time = "2026-01-14T12:54:55.978Z" }, + { url = "https://files.pythonhosted.org/packages/22/6e/46eb9b85c1b9761e0f42b6e6311e1cc544843ac897457062b9d5d0b21df4/librt-0.7.8-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e9c0afebbe6ce177ae8edba0c7c4d626f2a0fc12c33bb993d163817c41a7a05c", size = 164956, upload-time = "2026-01-14T12:54:57.311Z" }, + { url = "https://files.pythonhosted.org/packages/7a/3f/aa7c7f6829fb83989feb7ba9aa11c662b34b4bd4bd5b262f2876ba3db58d/librt-0.7.8-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:631599598e2c76ded400c0a8722dec09217c89ff64dc54b060f598ed68e7d2a8", size = 174364, upload-time = "2026-01-14T12:54:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/3f/2d/d57d154b40b11f2cb851c4df0d4c4456bacd9b1ccc4ecb593ddec56c1a8b/librt-0.7.8-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9c1ba843ae20db09b9d5c80475376168feb2640ce91cd9906414f23cc267a1ff", size = 188034, upload-time = "2026-01-14T12:55:00.141Z" }, + { url = "https://files.pythonhosted.org/packages/59/f9/36c4dad00925c16cd69d744b87f7001792691857d3b79187e7a673e812fb/librt-0.7.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b5b007bb22ea4b255d3ee39dfd06d12534de2fcc3438567d9f48cdaf67ae1ae3", size = 186295, upload-time = "2026-01-14T12:55:01.303Z" }, + { url = "https://files.pythonhosted.org/packages/23/9b/8a9889d3df5efb67695a67785028ccd58e661c3018237b73ad081691d0cb/librt-0.7.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dbd79caaf77a3f590cbe32dc2447f718772d6eea59656a7dcb9311161b10fa75", size = 181470, upload-time = "2026-01-14T12:55:02.492Z" }, + { url = "https://files.pythonhosted.org/packages/43/64/54d6ef11afca01fef8af78c230726a9394759f2addfbf7afc5e3cc032a45/librt-0.7.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:87808a8d1e0bd62a01cafc41f0fd6818b5a5d0ca0d8a55326a81643cdda8f873", size = 201713, upload-time = "2026-01-14T12:55:03.919Z" }, + { url = "https://files.pythonhosted.org/packages/2d/29/73e7ed2991330b28919387656f54109139b49e19cd72902f466bd44415fd/librt-0.7.8-cp311-cp311-win32.whl", hash = "sha256:31724b93baa91512bd0a376e7cf0b59d8b631ee17923b1218a65456fa9bda2e7", size = 43803, upload-time = "2026-01-14T12:55:04.996Z" }, + { url = "https://files.pythonhosted.org/packages/3f/de/66766ff48ed02b4d78deea30392ae200bcbd99ae61ba2418b49fd50a4831/librt-0.7.8-cp311-cp311-win_amd64.whl", hash = "sha256:978e8b5f13e52cf23a9e80f3286d7546baa70bc4ef35b51d97a709d0b28e537c", size = 50080, upload-time = "2026-01-14T12:55:06.489Z" }, + { url = "https://files.pythonhosted.org/packages/6f/e3/33450438ff3a8c581d4ed7f798a70b07c3206d298cf0b87d3806e72e3ed8/librt-0.7.8-cp311-cp311-win_arm64.whl", hash = "sha256:20e3946863d872f7cabf7f77c6c9d370b8b3d74333d3a32471c50d3a86c0a232", size = 43383, upload-time = "2026-01-14T12:55:07.49Z" }, + { url = "https://files.pythonhosted.org/packages/56/04/79d8fcb43cae376c7adbab7b2b9f65e48432c9eced62ac96703bcc16e09b/librt-0.7.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9b6943885b2d49c48d0cff23b16be830ba46b0152d98f62de49e735c6e655a63", size = 57472, upload-time = "2026-01-14T12:55:08.528Z" }, + { url = "https://files.pythonhosted.org/packages/b4/ba/60b96e93043d3d659da91752689023a73981336446ae82078cddf706249e/librt-0.7.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:46ef1f4b9b6cc364b11eea0ecc0897314447a66029ee1e55859acb3dd8757c93", size = 58986, upload-time = "2026-01-14T12:55:09.466Z" }, + { url = "https://files.pythonhosted.org/packages/7c/26/5215e4cdcc26e7be7eee21955a7e13cbf1f6d7d7311461a6014544596fac/librt-0.7.8-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:907ad09cfab21e3c86e8f1f87858f7049d1097f77196959c033612f532b4e592", size = 168422, upload-time = "2026-01-14T12:55:10.499Z" }, + { url = "https://files.pythonhosted.org/packages/0f/84/e8d1bc86fa0159bfc24f3d798d92cafd3897e84c7fea7fe61b3220915d76/librt-0.7.8-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2991b6c3775383752b3ca0204842743256f3ad3deeb1d0adc227d56b78a9a850", size = 177478, upload-time = "2026-01-14T12:55:11.577Z" }, + { url = "https://files.pythonhosted.org/packages/57/11/d0268c4b94717a18aa91df1100e767b010f87b7ae444dafaa5a2d80f33a6/librt-0.7.8-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03679b9856932b8c8f674e87aa3c55ea11c9274301f76ae8dc4d281bda55cf62", size = 192439, upload-time = "2026-01-14T12:55:12.7Z" }, + { url = "https://files.pythonhosted.org/packages/8d/56/1e8e833b95fe684f80f8894ae4d8b7d36acc9203e60478fcae599120a975/librt-0.7.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3968762fec1b2ad34ce57458b6de25dbb4142713e9ca6279a0d352fa4e9f452b", size = 191483, upload-time = "2026-01-14T12:55:13.838Z" }, + { url = "https://files.pythonhosted.org/packages/17/48/f11cf28a2cb6c31f282009e2208312aa84a5ee2732859f7856ee306176d5/librt-0.7.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:bb7a7807523a31f03061288cc4ffc065d684c39db7644c676b47d89553c0d714", size = 185376, upload-time = "2026-01-14T12:55:15.017Z" }, + { url = "https://files.pythonhosted.org/packages/b8/6a/d7c116c6da561b9155b184354a60a3d5cdbf08fc7f3678d09c95679d13d9/librt-0.7.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad64a14b1e56e702e19b24aae108f18ad1bf7777f3af5fcd39f87d0c5a814449", size = 206234, upload-time = "2026-01-14T12:55:16.571Z" }, + { url = "https://files.pythonhosted.org/packages/61/de/1975200bb0285fc921c5981d9978ce6ce11ae6d797df815add94a5a848a3/librt-0.7.8-cp312-cp312-win32.whl", hash = "sha256:0241a6ed65e6666236ea78203a73d800dbed896cf12ae25d026d75dc1fcd1dac", size = 44057, upload-time = "2026-01-14T12:55:18.077Z" }, + { url = "https://files.pythonhosted.org/packages/8e/cd/724f2d0b3461426730d4877754b65d39f06a41ac9d0a92d5c6840f72b9ae/librt-0.7.8-cp312-cp312-win_amd64.whl", hash = "sha256:6db5faf064b5bab9675c32a873436b31e01d66ca6984c6f7f92621656033a708", size = 50293, upload-time = "2026-01-14T12:55:19.179Z" }, + { url = "https://files.pythonhosted.org/packages/bd/cf/7e899acd9ee5727ad8160fdcc9994954e79fab371c66535c60e13b968ffc/librt-0.7.8-cp312-cp312-win_arm64.whl", hash = "sha256:57175aa93f804d2c08d2edb7213e09276bd49097611aefc37e3fa38d1fb99ad0", size = 43574, upload-time = "2026-01-14T12:55:20.185Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fe/b1f9de2829cf7fc7649c1dcd202cfd873837c5cc2fc9e526b0e7f716c3d2/librt-0.7.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4c3995abbbb60b3c129490fa985dfe6cac11d88fc3c36eeb4fb1449efbbb04fc", size = 57500, upload-time = "2026-01-14T12:55:21.219Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d4/4a60fbe2e53b825f5d9a77325071d61cd8af8506255067bf0c8527530745/librt-0.7.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:44e0c2cbc9bebd074cf2cdbe472ca185e824be4e74b1c63a8e934cea674bebf2", size = 59019, upload-time = "2026-01-14T12:55:22.256Z" }, + { url = "https://files.pythonhosted.org/packages/6a/37/61ff80341ba5159afa524445f2d984c30e2821f31f7c73cf166dcafa5564/librt-0.7.8-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:4d2f1e492cae964b3463a03dc77a7fe8742f7855d7258c7643f0ee32b6651dd3", size = 169015, upload-time = "2026-01-14T12:55:23.24Z" }, + { url = "https://files.pythonhosted.org/packages/1c/86/13d4f2d6a93f181ebf2fc953868826653ede494559da8268023fe567fca3/librt-0.7.8-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:451e7ffcef8f785831fdb791bd69211f47e95dc4c6ddff68e589058806f044c6", size = 178161, upload-time = "2026-01-14T12:55:24.826Z" }, + { url = "https://files.pythonhosted.org/packages/88/26/e24ef01305954fc4d771f1f09f3dd682f9eb610e1bec188ffb719374d26e/librt-0.7.8-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3469e1af9f1380e093ae06bedcbdd11e407ac0b303a56bbe9afb1d6824d4982d", size = 193015, upload-time = "2026-01-14T12:55:26.04Z" }, + { url = "https://files.pythonhosted.org/packages/88/a0/92b6bd060e720d7a31ed474d046a69bd55334ec05e9c446d228c4b806ae3/librt-0.7.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f11b300027ce19a34f6d24ebb0a25fd0e24a9d53353225a5c1e6cadbf2916b2e", size = 192038, upload-time = "2026-01-14T12:55:27.208Z" }, + { url = "https://files.pythonhosted.org/packages/06/bb/6f4c650253704279c3a214dad188101d1b5ea23be0606628bc6739456624/librt-0.7.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4adc73614f0d3c97874f02f2c7fd2a27854e7e24ad532ea6b965459c5b757eca", size = 186006, upload-time = "2026-01-14T12:55:28.594Z" }, + { url = "https://files.pythonhosted.org/packages/dc/00/1c409618248d43240cadf45f3efb866837fa77e9a12a71481912135eb481/librt-0.7.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:60c299e555f87e4c01b2eca085dfccda1dde87f5a604bb45c2906b8305819a93", size = 206888, upload-time = "2026-01-14T12:55:30.214Z" }, + { url = "https://files.pythonhosted.org/packages/d9/83/b2cfe8e76ff5c1c77f8a53da3d5de62d04b5ebf7cf913e37f8bca43b5d07/librt-0.7.8-cp313-cp313-win32.whl", hash = "sha256:b09c52ed43a461994716082ee7d87618096851319bf695d57ec123f2ab708951", size = 44126, upload-time = "2026-01-14T12:55:31.44Z" }, + { url = "https://files.pythonhosted.org/packages/a9/0b/c59d45de56a51bd2d3a401fc63449c0ac163e4ef7f523ea8b0c0dee86ec5/librt-0.7.8-cp313-cp313-win_amd64.whl", hash = "sha256:f8f4a901a3fa28969d6e4519deceab56c55a09d691ea7b12ca830e2fa3461e34", size = 50262, upload-time = "2026-01-14T12:55:33.01Z" }, + { url = "https://files.pythonhosted.org/packages/fc/b9/973455cec0a1ec592395250c474164c4a58ebf3e0651ee920fef1a2623f1/librt-0.7.8-cp313-cp313-win_arm64.whl", hash = "sha256:43d4e71b50763fcdcf64725ac680d8cfa1706c928b844794a7aa0fa9ac8e5f09", size = 43600, upload-time = "2026-01-14T12:55:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/1a/73/fa8814c6ce2d49c3827829cadaa1589b0bf4391660bd4510899393a23ebc/librt-0.7.8-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:be927c3c94c74b05128089a955fba86501c3b544d1d300282cc1b4bd370cb418", size = 57049, upload-time = "2026-01-14T12:55:35.056Z" }, + { url = "https://files.pythonhosted.org/packages/53/fe/f6c70956da23ea235fd2e3cc16f4f0b4ebdfd72252b02d1164dd58b4e6c3/librt-0.7.8-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:7b0803e9008c62a7ef79058233db7ff6f37a9933b8f2573c05b07ddafa226611", size = 58689, upload-time = "2026-01-14T12:55:36.078Z" }, + { url = "https://files.pythonhosted.org/packages/1f/4d/7a2481444ac5fba63050d9abe823e6bc16896f575bfc9c1e5068d516cdce/librt-0.7.8-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:79feb4d00b2a4e0e05c9c56df707934f41fcb5fe53fd9efb7549068d0495b758", size = 166808, upload-time = "2026-01-14T12:55:37.595Z" }, + { url = "https://files.pythonhosted.org/packages/ac/3c/10901d9e18639f8953f57c8986796cfbf4c1c514844a41c9197cf87cb707/librt-0.7.8-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b9122094e3f24aa759c38f46bd8863433820654927370250f460ae75488b66ea", size = 175614, upload-time = "2026-01-14T12:55:38.756Z" }, + { url = "https://files.pythonhosted.org/packages/db/01/5cbdde0951a5090a80e5ba44e6357d375048123c572a23eecfb9326993a7/librt-0.7.8-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7e03bea66af33c95ce3addf87a9bf1fcad8d33e757bc479957ddbc0e4f7207ac", size = 189955, upload-time = "2026-01-14T12:55:39.939Z" }, + { url = "https://files.pythonhosted.org/packages/6a/b4/e80528d2f4b7eaf1d437fcbd6fc6ba4cbeb3e2a0cb9ed5a79f47c7318706/librt-0.7.8-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f1ade7f31675db00b514b98f9ab9a7698c7282dad4be7492589109471852d398", size = 189370, upload-time = "2026-01-14T12:55:41.057Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ab/938368f8ce31a9787ecd4becb1e795954782e4312095daf8fd22420227c8/librt-0.7.8-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:a14229ac62adcf1b90a15992f1ab9c69ae8b99ffb23cb64a90878a6e8a2f5b81", size = 183224, upload-time = "2026-01-14T12:55:42.328Z" }, + { url = "https://files.pythonhosted.org/packages/3c/10/559c310e7a6e4014ac44867d359ef8238465fb499e7eb31b6bfe3e3f86f5/librt-0.7.8-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5bcaaf624fd24e6a0cb14beac37677f90793a96864c67c064a91458611446e83", size = 203541, upload-time = "2026-01-14T12:55:43.501Z" }, + { url = "https://files.pythonhosted.org/packages/f8/db/a0db7acdb6290c215f343835c6efda5b491bb05c3ddc675af558f50fdba3/librt-0.7.8-cp314-cp314-win32.whl", hash = "sha256:7aa7d5457b6c542ecaed79cec4ad98534373c9757383973e638ccced0f11f46d", size = 40657, upload-time = "2026-01-14T12:55:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/72/e0/4f9bdc2a98a798511e81edcd6b54fe82767a715e05d1921115ac70717f6f/librt-0.7.8-cp314-cp314-win_amd64.whl", hash = "sha256:3d1322800771bee4a91f3b4bd4e49abc7d35e65166821086e5afd1e6c0d9be44", size = 46835, upload-time = "2026-01-14T12:55:45.655Z" }, + { url = "https://files.pythonhosted.org/packages/f9/3d/59c6402e3dec2719655a41ad027a7371f8e2334aa794ed11533ad5f34969/librt-0.7.8-cp314-cp314-win_arm64.whl", hash = "sha256:5363427bc6a8c3b1719f8f3845ea53553d301382928a86e8fab7984426949bce", size = 39885, upload-time = "2026-01-14T12:55:47.138Z" }, + { url = "https://files.pythonhosted.org/packages/4e/9c/2481d80950b83085fb14ba3c595db56330d21bbc7d88a19f20165f3538db/librt-0.7.8-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:ca916919793a77e4a98d4a1701e345d337ce53be4a16620f063191f7322ac80f", size = 59161, upload-time = "2026-01-14T12:55:48.45Z" }, + { url = "https://files.pythonhosted.org/packages/96/79/108df2cfc4e672336765d54e3ff887294c1cc36ea4335c73588875775527/librt-0.7.8-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:54feb7b4f2f6706bb82325e836a01be805770443e2400f706e824e91f6441dde", size = 61008, upload-time = "2026-01-14T12:55:49.527Z" }, + { url = "https://files.pythonhosted.org/packages/46/f2/30179898f9994a5637459d6e169b6abdc982012c0a4b2d4c26f50c06f911/librt-0.7.8-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:39a4c76fee41007070f872b648cc2f711f9abf9a13d0c7162478043377b52c8e", size = 187199, upload-time = "2026-01-14T12:55:50.587Z" }, + { url = "https://files.pythonhosted.org/packages/b4/da/f7563db55cebdc884f518ba3791ad033becc25ff68eb70902b1747dc0d70/librt-0.7.8-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac9c8a458245c7de80bc1b9765b177055efff5803f08e548dd4bb9ab9a8d789b", size = 198317, upload-time = "2026-01-14T12:55:51.991Z" }, + { url = "https://files.pythonhosted.org/packages/b3/6c/4289acf076ad371471fa86718c30ae353e690d3de6167f7db36f429272f1/librt-0.7.8-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95b67aa7eff150f075fda09d11f6bfb26edffd300f6ab1666759547581e8f666", size = 210334, upload-time = "2026-01-14T12:55:53.682Z" }, + { url = "https://files.pythonhosted.org/packages/4a/7f/377521ac25b78ac0a5ff44127a0360ee6d5ddd3ce7327949876a30533daa/librt-0.7.8-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:535929b6eff670c593c34ff435d5440c3096f20fa72d63444608a5aef64dd581", size = 211031, upload-time = "2026-01-14T12:55:54.827Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b1/e1e96c3e20b23d00cf90f4aad48f0deb4cdfec2f0ed8380d0d85acf98bbf/librt-0.7.8-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:63937bd0f4d1cb56653dc7ae900d6c52c41f0015e25aaf9902481ee79943b33a", size = 204581, upload-time = "2026-01-14T12:55:56.811Z" }, + { url = "https://files.pythonhosted.org/packages/43/71/0f5d010e92ed9747e14bef35e91b6580533510f1e36a8a09eb79ee70b2f0/librt-0.7.8-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cf243da9e42d914036fd362ac3fa77d80a41cadcd11ad789b1b5eec4daaf67ca", size = 224731, upload-time = "2026-01-14T12:55:58.175Z" }, + { url = "https://files.pythonhosted.org/packages/22/f0/07fb6ab5c39a4ca9af3e37554f9d42f25c464829254d72e4ebbd81da351c/librt-0.7.8-cp314-cp314t-win32.whl", hash = "sha256:171ca3a0a06c643bd0a2f62a8944e1902c94aa8e5da4db1ea9a8daf872685365", size = 41173, upload-time = "2026-01-14T12:55:59.315Z" }, + { url = "https://files.pythonhosted.org/packages/24/d4/7e4be20993dc6a782639625bd2f97f3c66125c7aa80c82426956811cfccf/librt-0.7.8-cp314-cp314t-win_amd64.whl", hash = "sha256:445b7304145e24c60288a2f172b5ce2ca35c0f81605f5299f3fa567e189d2e32", size = 47668, upload-time = "2026-01-14T12:56:00.261Z" }, + { url = "https://files.pythonhosted.org/packages/fc/85/69f92b2a7b3c0f88ffe107c86b952b397004b5b8ea5a81da3d9c04c04422/librt-0.7.8-cp314-cp314t-win_arm64.whl", hash = "sha256:8766ece9de08527deabcd7cb1b4f1a967a385d26e33e536d6d8913db6ef74f06", size = 40550, upload-time = "2026-01-14T12:56:01.542Z" }, ] [[package]] @@ -598,8 +601,9 @@ source = { editable = "." } dependencies = [ { name = "exchange-calendars" }, { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "pandas" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "tzdata" }, { name = "valimp" }, { name = "yahooquery" }, @@ -611,10 +615,12 @@ dev = [ { name = "hypothesis" }, { name = "mypy" }, { name = "mypy-extensions" }, - { name = "pandas-stubs" }, + { name = "pandas-stubs", version = "2.3.3.260113", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas-stubs", version = "3.0.0.260204", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-mock" }, + { name = "pytz" }, { name = "tables", version = "3.10.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "tables", version = "3.10.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] @@ -623,6 +629,7 @@ test = [ { name = "hypothesis" }, { name = "pytest" }, { name = "pytest-mock" }, + { name = "pytz" }, { name = "tables", version = "3.10.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, { name = "tables", version = "3.10.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] @@ -647,6 +654,7 @@ dev = [ { name = "pre-commit" }, { name = "pytest" }, { name = "pytest-mock" }, + { name = "pytz" }, { name = "tables" }, ] test = [ @@ -654,6 +662,7 @@ test = [ { name = "hypothesis" }, { name = "pytest" }, { name = "pytest-mock" }, + { name = "pytz" }, { name = "tables" }, ] @@ -852,7 +861,7 @@ version = "2.14.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/cb/2f/fdba158c9dbe5caca9c3eca3eaffffb251f2fb8674bf8e2d0aed5f38d319/numexpr-2.14.1.tar.gz", hash = "sha256:4be00b1086c7b7a5c32e31558122b7b80243fe098579b170967da83f3152b48b", size = 119400, upload-time = "2025-10-13T16:17:27.351Z" } wheels = [ @@ -981,106 +990,112 @@ wheels = [ [[package]] name = "numpy" -version = "2.4.1" +version = "2.4.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", -] -sdist = { url = "https://files.pythonhosted.org/packages/24/62/ae72ff66c0f1fd959925b4c11f8c2dea61f47f6acaea75a08512cdfe3fed/numpy-2.4.1.tar.gz", hash = "sha256:a1ceafc5042451a858231588a104093474c6a5c57dcc724841f5c888d237d690", size = 20721320, upload-time = "2026-01-10T06:44:59.619Z" } + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +sdist = { url = "https://files.pythonhosted.org/packages/57/fd/0005efbd0af48e55eb3c7208af93f2862d4b1a56cd78e84309a2d959208d/numpy-2.4.2.tar.gz", hash = "sha256:659a6107e31a83c4e33f763942275fd278b21d095094044eb35569e86a21ddae", size = 20723651, upload-time = "2026-01-31T23:13:10.135Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a5/34/2b1bc18424f3ad9af577f6ce23600319968a70575bd7db31ce66731bbef9/numpy-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0cce2a669e3c8ba02ee563c7835f92c153cf02edff1ae05e1823f1dde21b16a5", size = 16944563, upload-time = "2026-01-10T06:42:14.615Z" }, - { url = "https://files.pythonhosted.org/packages/2c/57/26e5f97d075aef3794045a6ca9eada6a4ed70eb9a40e7a4a93f9ac80d704/numpy-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:899d2c18024984814ac7e83f8f49d8e8180e2fbe1b2e252f2e7f1d06bea92425", size = 12645658, upload-time = "2026-01-10T06:42:17.298Z" }, - { url = "https://files.pythonhosted.org/packages/8e/ba/80fc0b1e3cb2fd5c6143f00f42eb67762aa043eaa05ca924ecc3222a7849/numpy-2.4.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:09aa8a87e45b55a1c2c205d42e2808849ece5c484b2aab11fecabec3841cafba", size = 5474132, upload-time = "2026-01-10T06:42:19.637Z" }, - { url = "https://files.pythonhosted.org/packages/40/ae/0a5b9a397f0e865ec171187c78d9b57e5588afc439a04ba9cab1ebb2c945/numpy-2.4.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:edee228f76ee2dab4579fad6f51f6a305de09d444280109e0f75df247ff21501", size = 6804159, upload-time = "2026-01-10T06:42:21.44Z" }, - { url = "https://files.pythonhosted.org/packages/86/9c/841c15e691c7085caa6fd162f063eff494099c8327aeccd509d1ab1e36ab/numpy-2.4.1-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a92f227dbcdc9e4c3e193add1a189a9909947d4f8504c576f4a732fd0b54240a", size = 14708058, upload-time = "2026-01-10T06:42:23.546Z" }, - { url = "https://files.pythonhosted.org/packages/5d/9d/7862db06743f489e6a502a3b93136d73aea27d97b2cf91504f70a27501d6/numpy-2.4.1-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:538bf4ec353709c765ff75ae616c34d3c3dca1a68312727e8f2676ea644f8509", size = 16651501, upload-time = "2026-01-10T06:42:25.909Z" }, - { url = "https://files.pythonhosted.org/packages/a6/9c/6fc34ebcbd4015c6e5f0c0ce38264010ce8a546cb6beacb457b84a75dfc8/numpy-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ac08c63cb7779b85e9d5318e6c3518b424bc1f364ac4cb2c6136f12e5ff2dccc", size = 16492627, upload-time = "2026-01-10T06:42:28.938Z" }, - { url = "https://files.pythonhosted.org/packages/aa/63/2494a8597502dacda439f61b3c0db4da59928150e62be0e99395c3ad23c5/numpy-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:4f9c360ecef085e5841c539a9a12b883dff005fbd7ce46722f5e9cef52634d82", size = 18585052, upload-time = "2026-01-10T06:42:31.312Z" }, - { url = "https://files.pythonhosted.org/packages/6a/93/098e1162ae7522fc9b618d6272b77404c4656c72432ecee3abc029aa3de0/numpy-2.4.1-cp311-cp311-win32.whl", hash = "sha256:0f118ce6b972080ba0758c6087c3617b5ba243d806268623dc34216d69099ba0", size = 6236575, upload-time = "2026-01-10T06:42:33.872Z" }, - { url = "https://files.pythonhosted.org/packages/8c/de/f5e79650d23d9e12f38a7bc6b03ea0835b9575494f8ec94c11c6e773b1b1/numpy-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:18e14c4d09d55eef39a6ab5b08406e84bc6869c1e34eef45564804f90b7e0574", size = 12604479, upload-time = "2026-01-10T06:42:35.778Z" }, - { url = "https://files.pythonhosted.org/packages/dd/65/e1097a7047cff12ce3369bd003811516b20ba1078dbdec135e1cd7c16c56/numpy-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:6461de5113088b399d655d45c3897fa188766415d0f568f175ab071c8873bd73", size = 10578325, upload-time = "2026-01-10T06:42:38.518Z" }, - { url = "https://files.pythonhosted.org/packages/78/7f/ec53e32bf10c813604edf07a3682616bd931d026fcde7b6d13195dfb684a/numpy-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d3703409aac693fa82c0aee023a1ae06a6e9d065dba10f5e8e80f642f1e9d0a2", size = 16656888, upload-time = "2026-01-10T06:42:40.913Z" }, - { url = "https://files.pythonhosted.org/packages/b8/e0/1f9585d7dae8f14864e948fd7fa86c6cb72dee2676ca2748e63b1c5acfe0/numpy-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7211b95ca365519d3596a1d8688a95874cc94219d417504d9ecb2df99fa7bfa8", size = 12373956, upload-time = "2026-01-10T06:42:43.091Z" }, - { url = "https://files.pythonhosted.org/packages/8e/43/9762e88909ff2326f5e7536fa8cb3c49fb03a7d92705f23e6e7f553d9cb3/numpy-2.4.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:5adf01965456a664fc727ed69cc71848f28d063217c63e1a0e200a118d5eec9a", size = 5202567, upload-time = "2026-01-10T06:42:45.107Z" }, - { url = "https://files.pythonhosted.org/packages/4b/ee/34b7930eb61e79feb4478800a4b95b46566969d837546aa7c034c742ef98/numpy-2.4.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:26f0bcd9c79a00e339565b303badc74d3ea2bd6d52191eeca5f95936cad107d0", size = 6549459, upload-time = "2026-01-10T06:42:48.152Z" }, - { url = "https://files.pythonhosted.org/packages/79/e3/5f115fae982565771be994867c89bcd8d7208dbfe9469185497d70de5ddf/numpy-2.4.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0093e85df2960d7e4049664b26afc58b03236e967fb942354deef3208857a04c", size = 14404859, upload-time = "2026-01-10T06:42:49.947Z" }, - { url = "https://files.pythonhosted.org/packages/d9/7d/9c8a781c88933725445a859cac5d01b5871588a15969ee6aeb618ba99eee/numpy-2.4.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7ad270f438cbdd402c364980317fb6b117d9ec5e226fff5b4148dd9aa9fc6e02", size = 16371419, upload-time = "2026-01-10T06:42:52.409Z" }, - { url = "https://files.pythonhosted.org/packages/a6/d2/8aa084818554543f17cf4162c42f162acbd3bb42688aefdba6628a859f77/numpy-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:297c72b1b98100c2e8f873d5d35fb551fce7040ade83d67dd51d38c8d42a2162", size = 16182131, upload-time = "2026-01-10T06:42:54.694Z" }, - { url = "https://files.pythonhosted.org/packages/60/db/0425216684297c58a8df35f3284ef56ec4a043e6d283f8a59c53562caf1b/numpy-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:cf6470d91d34bf669f61d515499859fa7a4c2f7c36434afb70e82df7217933f9", size = 18295342, upload-time = "2026-01-10T06:42:56.991Z" }, - { url = "https://files.pythonhosted.org/packages/31/4c/14cb9d86240bd8c386c881bafbe43f001284b7cce3bc01623ac9475da163/numpy-2.4.1-cp312-cp312-win32.whl", hash = "sha256:b6bcf39112e956594b3331316d90c90c90fb961e39696bda97b89462f5f3943f", size = 5959015, upload-time = "2026-01-10T06:42:59.631Z" }, - { url = "https://files.pythonhosted.org/packages/51/cf/52a703dbeb0c65807540d29699fef5fda073434ff61846a564d5c296420f/numpy-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:e1a27bb1b2dee45a2a53f5ca6ff2d1a7f135287883a1689e930d44d1ff296c87", size = 12310730, upload-time = "2026-01-10T06:43:01.627Z" }, - { url = "https://files.pythonhosted.org/packages/69/80/a828b2d0ade5e74a9fe0f4e0a17c30fdc26232ad2bc8c9f8b3197cf7cf18/numpy-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:0e6e8f9d9ecf95399982019c01223dc130542960a12edfa8edd1122dfa66a8a8", size = 10312166, upload-time = "2026-01-10T06:43:03.673Z" }, - { url = "https://files.pythonhosted.org/packages/04/68/732d4b7811c00775f3bd522a21e8dd5a23f77eb11acdeb663e4a4ebf0ef4/numpy-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d797454e37570cfd61143b73b8debd623c3c0952959adb817dd310a483d58a1b", size = 16652495, upload-time = "2026-01-10T06:43:06.283Z" }, - { url = "https://files.pythonhosted.org/packages/20/ca/857722353421a27f1465652b2c66813eeeccea9d76d5f7b74b99f298e60e/numpy-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:82c55962006156aeef1629b953fd359064aa47e4d82cfc8e67f0918f7da3344f", size = 12368657, upload-time = "2026-01-10T06:43:09.094Z" }, - { url = "https://files.pythonhosted.org/packages/81/0d/2377c917513449cc6240031a79d30eb9a163d32a91e79e0da47c43f2c0c8/numpy-2.4.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:71abbea030f2cfc3092a0ff9f8c8fdefdc5e0bf7d9d9c99663538bb0ecdac0b9", size = 5197256, upload-time = "2026-01-10T06:43:13.634Z" }, - { url = "https://files.pythonhosted.org/packages/17/39/569452228de3f5de9064ac75137082c6214be1f5c532016549a7923ab4b5/numpy-2.4.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:5b55aa56165b17aaf15520beb9cbd33c9039810e0d9643dd4379e44294c7303e", size = 6545212, upload-time = "2026-01-10T06:43:15.661Z" }, - { url = "https://files.pythonhosted.org/packages/8c/a4/77333f4d1e4dac4395385482557aeecf4826e6ff517e32ca48e1dafbe42a/numpy-2.4.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c0faba4a331195bfa96f93dd9dfaa10b2c7aa8cda3a02b7fd635e588fe821bf5", size = 14402871, upload-time = "2026-01-10T06:43:17.324Z" }, - { url = "https://files.pythonhosted.org/packages/ba/87/d341e519956273b39d8d47969dd1eaa1af740615394fe67d06f1efa68773/numpy-2.4.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e3087f53e2b4428766b54932644d148613c5a595150533ae7f00dab2f319a8", size = 16359305, upload-time = "2026-01-10T06:43:19.376Z" }, - { url = "https://files.pythonhosted.org/packages/32/91/789132c6666288eaa20ae8066bb99eba1939362e8f1a534949a215246e97/numpy-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:49e792ec351315e16da54b543db06ca8a86985ab682602d90c60ef4ff4db2a9c", size = 16181909, upload-time = "2026-01-10T06:43:21.808Z" }, - { url = "https://files.pythonhosted.org/packages/cf/b8/090b8bd27b82a844bb22ff8fdf7935cb1980b48d6e439ae116f53cdc2143/numpy-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79e9e06c4c2379db47f3f6fc7a8652e7498251789bf8ff5bd43bf478ef314ca2", size = 18284380, upload-time = "2026-01-10T06:43:23.957Z" }, - { url = "https://files.pythonhosted.org/packages/67/78/722b62bd31842ff029412271556a1a27a98f45359dea78b1548a3a9996aa/numpy-2.4.1-cp313-cp313-win32.whl", hash = "sha256:3d1a100e48cb266090a031397863ff8a30050ceefd798f686ff92c67a486753d", size = 5957089, upload-time = "2026-01-10T06:43:27.535Z" }, - { url = "https://files.pythonhosted.org/packages/da/a6/cf32198b0b6e18d4fbfa9a21a992a7fca535b9bb2b0cdd217d4a3445b5ca/numpy-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:92a0e65272fd60bfa0d9278e0484c2f52fe03b97aedc02b357f33fe752c52ffb", size = 12307230, upload-time = "2026-01-10T06:43:29.298Z" }, - { url = "https://files.pythonhosted.org/packages/44/6c/534d692bfb7d0afe30611320c5fb713659dcb5104d7cc182aff2aea092f5/numpy-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:20d4649c773f66cc2fc36f663e091f57c3b7655f936a4c681b4250855d1da8f5", size = 10313125, upload-time = "2026-01-10T06:43:31.782Z" }, - { url = "https://files.pythonhosted.org/packages/da/a1/354583ac5c4caa566de6ddfbc42744409b515039e085fab6e0ff942e0df5/numpy-2.4.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:f93bc6892fe7b0663e5ffa83b61aab510aacffd58c16e012bb9352d489d90cb7", size = 12496156, upload-time = "2026-01-10T06:43:34.237Z" }, - { url = "https://files.pythonhosted.org/packages/51/b0/42807c6e8cce58c00127b1dc24d365305189991f2a7917aa694a109c8d7d/numpy-2.4.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:178de8f87948163d98a4c9ab5bee4ce6519ca918926ec8df195af582de28544d", size = 5324663, upload-time = "2026-01-10T06:43:36.211Z" }, - { url = "https://files.pythonhosted.org/packages/fe/55/7a621694010d92375ed82f312b2f28017694ed784775269115323e37f5e2/numpy-2.4.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:98b35775e03ab7f868908b524fc0a84d38932d8daf7b7e1c3c3a1b6c7a2c9f15", size = 6645224, upload-time = "2026-01-10T06:43:37.884Z" }, - { url = "https://files.pythonhosted.org/packages/50/96/9fa8635ed9d7c847d87e30c834f7109fac5e88549d79ef3324ab5c20919f/numpy-2.4.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:941c2a93313d030f219f3a71fd3d91a728b82979a5e8034eb2e60d394a2b83f9", size = 14462352, upload-time = "2026-01-10T06:43:39.479Z" }, - { url = "https://files.pythonhosted.org/packages/03/d1/8cf62d8bb2062da4fb82dd5d49e47c923f9c0738032f054e0a75342faba7/numpy-2.4.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:529050522e983e00a6c1c6b67411083630de8b57f65e853d7b03d9281b8694d2", size = 16407279, upload-time = "2026-01-10T06:43:41.93Z" }, - { url = "https://files.pythonhosted.org/packages/86/1c/95c86e17c6b0b31ce6ef219da00f71113b220bcb14938c8d9a05cee0ff53/numpy-2.4.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2302dc0224c1cbc49bb94f7064f3f923a971bfae45c33870dcbff63a2a550505", size = 16248316, upload-time = "2026-01-10T06:43:44.121Z" }, - { url = "https://files.pythonhosted.org/packages/30/b4/e7f5ff8697274c9d0fa82398b6a372a27e5cef069b37df6355ccb1f1db1a/numpy-2.4.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:9171a42fcad32dcf3fa86f0a4faa5e9f8facefdb276f54b8b390d90447cff4e2", size = 18329884, upload-time = "2026-01-10T06:43:46.613Z" }, - { url = "https://files.pythonhosted.org/packages/37/a4/b073f3e9d77f9aec8debe8ca7f9f6a09e888ad1ba7488f0c3b36a94c03ac/numpy-2.4.1-cp313-cp313t-win32.whl", hash = "sha256:382ad67d99ef49024f11d1ce5dcb5ad8432446e4246a4b014418ba3a1175a1f4", size = 6081138, upload-time = "2026-01-10T06:43:48.854Z" }, - { url = "https://files.pythonhosted.org/packages/16/16/af42337b53844e67752a092481ab869c0523bc95c4e5c98e4dac4e9581ac/numpy-2.4.1-cp313-cp313t-win_amd64.whl", hash = "sha256:62fea415f83ad8fdb6c20840578e5fbaf5ddd65e0ec6c3c47eda0f69da172510", size = 12447478, upload-time = "2026-01-10T06:43:50.476Z" }, - { url = "https://files.pythonhosted.org/packages/6c/f8/fa85b2eac68ec631d0b631abc448552cb17d39afd17ec53dcbcc3537681a/numpy-2.4.1-cp313-cp313t-win_arm64.whl", hash = "sha256:a7870e8c5fc11aef57d6fea4b4085e537a3a60ad2cdd14322ed531fdca68d261", size = 10382981, upload-time = "2026-01-10T06:43:52.575Z" }, - { url = "https://files.pythonhosted.org/packages/1b/a7/ef08d25698e0e4b4efbad8d55251d20fe2a15f6d9aa7c9b30cd03c165e6f/numpy-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:3869ea1ee1a1edc16c29bbe3a2f2a4e515cc3a44d43903ad41e0cacdbaf733dc", size = 16652046, upload-time = "2026-01-10T06:43:54.797Z" }, - { url = "https://files.pythonhosted.org/packages/8f/39/e378b3e3ca13477e5ac70293ec027c438d1927f18637e396fe90b1addd72/numpy-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:e867df947d427cdd7a60e3e271729090b0f0df80f5f10ab7dd436f40811699c3", size = 12378858, upload-time = "2026-01-10T06:43:57.099Z" }, - { url = "https://files.pythonhosted.org/packages/c3/74/7ec6154f0006910ed1fdbb7591cf4432307033102b8a22041599935f8969/numpy-2.4.1-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:e3bd2cb07841166420d2fa7146c96ce00cb3410664cbc1a6be028e456c4ee220", size = 5207417, upload-time = "2026-01-10T06:43:59.037Z" }, - { url = "https://files.pythonhosted.org/packages/f7/b7/053ac11820d84e42f8feea5cb81cc4fcd1091499b45b1ed8c7415b1bf831/numpy-2.4.1-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:f0a90aba7d521e6954670550e561a4cb925713bd944445dbe9e729b71f6cabee", size = 6542643, upload-time = "2026-01-10T06:44:01.852Z" }, - { url = "https://files.pythonhosted.org/packages/c0/c4/2e7908915c0e32ca636b92e4e4a3bdec4cb1e7eb0f8aedf1ed3c68a0d8cd/numpy-2.4.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5d558123217a83b2d1ba316b986e9248a1ed1971ad495963d555ccd75dcb1556", size = 14418963, upload-time = "2026-01-10T06:44:04.047Z" }, - { url = "https://files.pythonhosted.org/packages/eb/c0/3ed5083d94e7ffd7c404e54619c088e11f2e1939a9544f5397f4adb1b8ba/numpy-2.4.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2f44de05659b67d20499cbc96d49f2650769afcb398b79b324bb6e297bfe3844", size = 16363811, upload-time = "2026-01-10T06:44:06.207Z" }, - { url = "https://files.pythonhosted.org/packages/0e/68/42b66f1852bf525050a67315a4fb94586ab7e9eaa541b1bef530fab0c5dd/numpy-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:69e7419c9012c4aaf695109564e3387f1259f001b4326dfa55907b098af082d3", size = 16197643, upload-time = "2026-01-10T06:44:08.33Z" }, - { url = "https://files.pythonhosted.org/packages/d2/40/e8714fc933d85f82c6bfc7b998a0649ad9769a32f3494ba86598aaf18a48/numpy-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2ffd257026eb1b34352e749d7cc1678b5eeec3e329ad8c9965a797e08ccba205", size = 18289601, upload-time = "2026-01-10T06:44:10.841Z" }, - { url = "https://files.pythonhosted.org/packages/80/9a/0d44b468cad50315127e884802351723daca7cf1c98d102929468c81d439/numpy-2.4.1-cp314-cp314-win32.whl", hash = "sha256:727c6c3275ddefa0dc078524a85e064c057b4f4e71ca5ca29a19163c607be745", size = 6005722, upload-time = "2026-01-10T06:44:13.332Z" }, - { url = "https://files.pythonhosted.org/packages/7e/bb/c6513edcce5a831810e2dddc0d3452ce84d208af92405a0c2e58fd8e7881/numpy-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:7d5d7999df434a038d75a748275cd6c0094b0ecdb0837342b332a82defc4dc4d", size = 12438590, upload-time = "2026-01-10T06:44:15.006Z" }, - { url = "https://files.pythonhosted.org/packages/e9/da/a598d5cb260780cf4d255102deba35c1d072dc028c4547832f45dd3323a8/numpy-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:ce9ce141a505053b3c7bce3216071f3bf5c182b8b28930f14cd24d43932cd2df", size = 10596180, upload-time = "2026-01-10T06:44:17.386Z" }, - { url = "https://files.pythonhosted.org/packages/de/bc/ea3f2c96fcb382311827231f911723aeff596364eb6e1b6d1d91128aa29b/numpy-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:4e53170557d37ae404bf8d542ca5b7c629d6efa1117dac6a83e394142ea0a43f", size = 12498774, upload-time = "2026-01-10T06:44:19.467Z" }, - { url = "https://files.pythonhosted.org/packages/aa/ab/ef9d939fe4a812648c7a712610b2ca6140b0853c5efea361301006c02ae5/numpy-2.4.1-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:a73044b752f5d34d4232f25f18160a1cc418ea4507f5f11e299d8ac36875f8a0", size = 5327274, upload-time = "2026-01-10T06:44:23.189Z" }, - { url = "https://files.pythonhosted.org/packages/bd/31/d381368e2a95c3b08b8cf7faac6004849e960f4a042d920337f71cef0cae/numpy-2.4.1-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:fb1461c99de4d040666ca0444057b06541e5642f800b71c56e6ea92d6a853a0c", size = 6648306, upload-time = "2026-01-10T06:44:25.012Z" }, - { url = "https://files.pythonhosted.org/packages/c8/e5/0989b44ade47430be6323d05c23207636d67d7362a1796ccbccac6773dd2/numpy-2.4.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:423797bdab2eeefbe608d7c1ec7b2b4fd3c58d51460f1ee26c7500a1d9c9ee93", size = 14464653, upload-time = "2026-01-10T06:44:26.706Z" }, - { url = "https://files.pythonhosted.org/packages/10/a7/cfbe475c35371cae1358e61f20c5f075badc18c4797ab4354140e1d283cf/numpy-2.4.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:52b5f61bdb323b566b528899cc7db2ba5d1015bda7ea811a8bcf3c89c331fa42", size = 16405144, upload-time = "2026-01-10T06:44:29.378Z" }, - { url = "https://files.pythonhosted.org/packages/f8/a3/0c63fe66b534888fa5177cc7cef061541064dbe2b4b60dcc60ffaf0d2157/numpy-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:42d7dd5fa36d16d52a84f821eb96031836fd405ee6955dd732f2023724d0aa01", size = 16247425, upload-time = "2026-01-10T06:44:31.721Z" }, - { url = "https://files.pythonhosted.org/packages/6b/2b/55d980cfa2c93bd40ff4c290bf824d792bd41d2fe3487b07707559071760/numpy-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7b6b5e28bbd47b7532698e5db2fe1db693d84b58c254e4389d99a27bb9b8f6b", size = 18330053, upload-time = "2026-01-10T06:44:34.617Z" }, - { url = "https://files.pythonhosted.org/packages/23/12/8b5fc6b9c487a09a7957188e0943c9ff08432c65e34567cabc1623b03a51/numpy-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:5de60946f14ebe15e713a6f22850c2372fa72f4ff9a432ab44aa90edcadaa65a", size = 6152482, upload-time = "2026-01-10T06:44:36.798Z" }, - { url = "https://files.pythonhosted.org/packages/00/a5/9f8ca5856b8940492fc24fbe13c1bc34d65ddf4079097cf9e53164d094e1/numpy-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:8f085da926c0d491ffff3096f91078cc97ea67e7e6b65e490bc8dcda65663be2", size = 12627117, upload-time = "2026-01-10T06:44:38.828Z" }, - { url = "https://files.pythonhosted.org/packages/ad/0d/eca3d962f9eef265f01a8e0d20085c6dd1f443cbffc11b6dede81fd82356/numpy-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:6436cffb4f2bf26c974344439439c95e152c9a527013f26b3577be6c2ca64295", size = 10667121, upload-time = "2026-01-10T06:44:41.644Z" }, - { url = "https://files.pythonhosted.org/packages/1e/48/d86f97919e79314a1cdee4c832178763e6e98e623e123d0bada19e92c15a/numpy-2.4.1-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8ad35f20be147a204e28b6a0575fbf3540c5e5f802634d4258d55b1ff5facce1", size = 16822202, upload-time = "2026-01-10T06:44:43.738Z" }, - { url = "https://files.pythonhosted.org/packages/51/e9/1e62a7f77e0f37dcfb0ad6a9744e65df00242b6ea37dfafb55debcbf5b55/numpy-2.4.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:8097529164c0f3e32bb89412a0905d9100bf434d9692d9fc275e18dcf53c9344", size = 12569985, upload-time = "2026-01-10T06:44:45.945Z" }, - { url = "https://files.pythonhosted.org/packages/c7/7e/914d54f0c801342306fdcdce3e994a56476f1b818c46c47fc21ae968088c/numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:ea66d2b41ca4a1630aae5507ee0a71647d3124d1741980138aa8f28f44dac36e", size = 5398484, upload-time = "2026-01-10T06:44:48.012Z" }, - { url = "https://files.pythonhosted.org/packages/1c/d8/9570b68584e293a33474e7b5a77ca404f1dcc655e40050a600dee81d27fb/numpy-2.4.1-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d3f8f0df9f4b8be57b3bf74a1d087fec68f927a2fab68231fdb442bf2c12e426", size = 6713216, upload-time = "2026-01-10T06:44:49.725Z" }, - { url = "https://files.pythonhosted.org/packages/33/9b/9dd6e2db8d49eb24f86acaaa5258e5f4c8ed38209a4ee9de2d1a0ca25045/numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2023ef86243690c2791fd6353e5b4848eedaa88ca8a2d129f462049f6d484696", size = 14538937, upload-time = "2026-01-10T06:44:51.498Z" }, - { url = "https://files.pythonhosted.org/packages/53/87/d5bd995b0f798a37105b876350d346eea5838bd8f77ea3d7a48392f3812b/numpy-2.4.1-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8361ea4220d763e54cff2fbe7d8c93526b744f7cd9ddab47afeff7e14e8503be", size = 16479830, upload-time = "2026-01-10T06:44:53.931Z" }, - { url = "https://files.pythonhosted.org/packages/5b/c7/b801bf98514b6ae6475e941ac05c58e6411dd863ea92916bfd6d510b08c1/numpy-2.4.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:4f1b68ff47680c2925f8063402a693ede215f0257f02596b1318ecdfb1d79e33", size = 12492579, upload-time = "2026-01-10T06:44:57.094Z" }, + { url = "https://files.pythonhosted.org/packages/d3/44/71852273146957899753e69986246d6a176061ea183407e95418c2aa4d9a/numpy-2.4.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7e88598032542bd49af7c4747541422884219056c268823ef6e5e89851c8825", size = 16955478, upload-time = "2026-01-31T23:10:25.623Z" }, + { url = "https://files.pythonhosted.org/packages/74/41/5d17d4058bd0cd96bcbd4d9ff0fb2e21f52702aab9a72e4a594efa18692f/numpy-2.4.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:7edc794af8b36ca37ef5fcb5e0d128c7e0595c7b96a2318d1badb6fcd8ee86b1", size = 14965467, upload-time = "2026-01-31T23:10:28.186Z" }, + { url = "https://files.pythonhosted.org/packages/49/48/fb1ce8136c19452ed15f033f8aee91d5defe515094e330ce368a0647846f/numpy-2.4.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6e9f61981ace1360e42737e2bae58b27bf28a1b27e781721047d84bd754d32e7", size = 5475172, upload-time = "2026-01-31T23:10:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/40/a9/3feb49f17bbd1300dd2570432961f5c8a4ffeff1db6f02c7273bd020a4c9/numpy-2.4.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:cb7bbb88aa74908950d979eeaa24dbdf1a865e3c7e45ff0121d8f70387b55f73", size = 6805145, upload-time = "2026-01-31T23:10:32.352Z" }, + { url = "https://files.pythonhosted.org/packages/3f/39/fdf35cbd6d6e2fcad42fcf85ac04a85a0d0fbfbf34b30721c98d602fd70a/numpy-2.4.2-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4f069069931240b3fc703f1e23df63443dbd6390614c8c44a87d96cd0ec81eb1", size = 15966084, upload-time = "2026-01-31T23:10:34.502Z" }, + { url = "https://files.pythonhosted.org/packages/1b/46/6fa4ea94f1ddf969b2ee941290cca6f1bfac92b53c76ae5f44afe17ceb69/numpy-2.4.2-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c02ef4401a506fb60b411467ad501e1429a3487abca4664871d9ae0b46c8ba32", size = 16899477, upload-time = "2026-01-31T23:10:37.075Z" }, + { url = "https://files.pythonhosted.org/packages/09/a1/2a424e162b1a14a5bd860a464ab4e07513916a64ab1683fae262f735ccd2/numpy-2.4.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2653de5c24910e49c2b106499803124dde62a5a1fe0eedeaecf4309a5f639390", size = 17323429, upload-time = "2026-01-31T23:10:39.704Z" }, + { url = "https://files.pythonhosted.org/packages/ce/a2/73014149ff250628df72c58204822ac01d768697913881aacf839ff78680/numpy-2.4.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1ae241bbfc6ae276f94a170b14785e561cb5e7f626b6688cf076af4110887413", size = 18635109, upload-time = "2026-01-31T23:10:41.924Z" }, + { url = "https://files.pythonhosted.org/packages/6c/0c/73e8be2f1accd56df74abc1c5e18527822067dced5ec0861b5bb882c2ce0/numpy-2.4.2-cp311-cp311-win32.whl", hash = "sha256:df1b10187212b198dd45fa943d8985a3c8cf854aed4923796e0e019e113a1bda", size = 6237915, upload-time = "2026-01-31T23:10:45.26Z" }, + { url = "https://files.pythonhosted.org/packages/76/ae/e0265e0163cf127c24c3969d29f1c4c64551a1e375d95a13d32eab25d364/numpy-2.4.2-cp311-cp311-win_amd64.whl", hash = "sha256:b9c618d56a29c9cb1c4da979e9899be7578d2e0b3c24d52079c166324c9e8695", size = 12607972, upload-time = "2026-01-31T23:10:47.021Z" }, + { url = "https://files.pythonhosted.org/packages/29/a5/c43029af9b8014d6ea157f192652c50042e8911f4300f8f6ed3336bf437f/numpy-2.4.2-cp311-cp311-win_arm64.whl", hash = "sha256:47c5a6ed21d9452b10227e5e8a0e1c22979811cad7dcc19d8e3e2fb8fa03f1a3", size = 10485763, upload-time = "2026-01-31T23:10:50.087Z" }, + { url = "https://files.pythonhosted.org/packages/51/6e/6f394c9c77668153e14d4da83bcc247beb5952f6ead7699a1a2992613bea/numpy-2.4.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:21982668592194c609de53ba4933a7471880ccbaadcc52352694a59ecc860b3a", size = 16667963, upload-time = "2026-01-31T23:10:52.147Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f8/55483431f2b2fd015ae6ed4fe62288823ce908437ed49db5a03d15151678/numpy-2.4.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:40397bda92382fcec844066efb11f13e1c9a3e2a8e8f318fb72ed8b6db9f60f1", size = 14693571, upload-time = "2026-01-31T23:10:54.789Z" }, + { url = "https://files.pythonhosted.org/packages/2f/20/18026832b1845cdc82248208dd929ca14c9d8f2bac391f67440707fff27c/numpy-2.4.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:b3a24467af63c67829bfaa61eecf18d5432d4f11992688537be59ecd6ad32f5e", size = 5203469, upload-time = "2026-01-31T23:10:57.343Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/2eb97c8a77daaba34eaa3fa7241a14ac5f51c46a6bd5911361b644c4a1e2/numpy-2.4.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:805cc8de9fd6e7a22da5aed858e0ab16be5a4db6c873dde1d7451c541553aa27", size = 6550820, upload-time = "2026-01-31T23:10:59.429Z" }, + { url = "https://files.pythonhosted.org/packages/b1/91/b97fdfd12dc75b02c44e26c6638241cc004d4079a0321a69c62f51470c4c/numpy-2.4.2-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d82351358ffbcdcd7b686b90742a9b86632d6c1c051016484fa0b326a0a1548", size = 15663067, upload-time = "2026-01-31T23:11:01.291Z" }, + { url = "https://files.pythonhosted.org/packages/f5/c6/a18e59f3f0b8071cc85cbc8d80cd02d68aa9710170b2553a117203d46936/numpy-2.4.2-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e35d3e0144137d9fdae62912e869136164534d64a169f86438bc9561b6ad49f", size = 16619782, upload-time = "2026-01-31T23:11:03.669Z" }, + { url = "https://files.pythonhosted.org/packages/b7/83/9751502164601a79e18847309f5ceec0b1446d7b6aa12305759b72cf98b2/numpy-2.4.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:adb6ed2ad29b9e15321d167d152ee909ec73395901b70936f029c3bc6d7f4460", size = 17013128, upload-time = "2026-01-31T23:11:05.913Z" }, + { url = "https://files.pythonhosted.org/packages/61/c4/c4066322256ec740acc1c8923a10047818691d2f8aec254798f3dd90f5f2/numpy-2.4.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8906e71fd8afcb76580404e2a950caef2685df3d2a57fe82a86ac8d33cc007ba", size = 18345324, upload-time = "2026-01-31T23:11:08.248Z" }, + { url = "https://files.pythonhosted.org/packages/ab/af/6157aa6da728fa4525a755bfad486ae7e3f76d4c1864138003eb84328497/numpy-2.4.2-cp312-cp312-win32.whl", hash = "sha256:ec055f6dae239a6299cace477b479cca2fc125c5675482daf1dd886933a1076f", size = 5960282, upload-time = "2026-01-31T23:11:10.497Z" }, + { url = "https://files.pythonhosted.org/packages/92/0f/7ceaaeaacb40567071e94dbf2c9480c0ae453d5bb4f52bea3892c39dc83c/numpy-2.4.2-cp312-cp312-win_amd64.whl", hash = "sha256:209fae046e62d0ce6435fcfe3b1a10537e858249b3d9b05829e2a05218296a85", size = 12314210, upload-time = "2026-01-31T23:11:12.176Z" }, + { url = "https://files.pythonhosted.org/packages/2f/a3/56c5c604fae6dd40fa2ed3040d005fca97e91bd320d232ac9931d77ba13c/numpy-2.4.2-cp312-cp312-win_arm64.whl", hash = "sha256:fbde1b0c6e81d56f5dccd95dd4a711d9b95df1ae4009a60887e56b27e8d903fa", size = 10220171, upload-time = "2026-01-31T23:11:14.684Z" }, + { url = "https://files.pythonhosted.org/packages/a1/22/815b9fe25d1d7ae7d492152adbc7226d3eff731dffc38fe970589fcaaa38/numpy-2.4.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:25f2059807faea4b077a2b6837391b5d830864b3543627f381821c646f31a63c", size = 16663696, upload-time = "2026-01-31T23:11:17.516Z" }, + { url = "https://files.pythonhosted.org/packages/09/f0/817d03a03f93ba9c6c8993de509277d84e69f9453601915e4a69554102a1/numpy-2.4.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bd3a7a9f5847d2fb8c2c6d1c862fa109c31a9abeca1a3c2bd5a64572955b2979", size = 14688322, upload-time = "2026-01-31T23:11:19.883Z" }, + { url = "https://files.pythonhosted.org/packages/da/b4/f805ab79293c728b9a99438775ce51885fd4f31b76178767cfc718701a39/numpy-2.4.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:8e4549f8a3c6d13d55041925e912bfd834285ef1dd64d6bc7d542583355e2e98", size = 5198157, upload-time = "2026-01-31T23:11:22.375Z" }, + { url = "https://files.pythonhosted.org/packages/74/09/826e4289844eccdcd64aac27d13b0fd3f32039915dd5b9ba01baae1f436c/numpy-2.4.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:aea4f66ff44dfddf8c2cffd66ba6538c5ec67d389285292fe428cb2c738c8aef", size = 6546330, upload-time = "2026-01-31T23:11:23.958Z" }, + { url = "https://files.pythonhosted.org/packages/19/fb/cbfdbfa3057a10aea5422c558ac57538e6acc87ec1669e666d32ac198da7/numpy-2.4.2-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c3cd545784805de05aafe1dde61752ea49a359ccba9760c1e5d1c88a93bbf2b7", size = 15660968, upload-time = "2026-01-31T23:11:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/04/dc/46066ce18d01645541f0186877377b9371b8fa8017fa8262002b4ef22612/numpy-2.4.2-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d0d9b7c93578baafcbc5f0b83eaf17b79d345c6f36917ba0c67f45226911d499", size = 16607311, upload-time = "2026-01-31T23:11:28.117Z" }, + { url = "https://files.pythonhosted.org/packages/14/d9/4b5adfc39a43fa6bf918c6d544bc60c05236cc2f6339847fc5b35e6cb5b0/numpy-2.4.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f74f0f7779cc7ae07d1810aab8ac6b1464c3eafb9e283a40da7309d5e6e48fbb", size = 17012850, upload-time = "2026-01-31T23:11:30.888Z" }, + { url = "https://files.pythonhosted.org/packages/b7/20/adb6e6adde6d0130046e6fdfb7675cc62bc2f6b7b02239a09eb58435753d/numpy-2.4.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:c7ac672d699bf36275c035e16b65539931347d68b70667d28984c9fb34e07fa7", size = 18334210, upload-time = "2026-01-31T23:11:33.214Z" }, + { url = "https://files.pythonhosted.org/packages/78/0e/0a73b3dff26803a8c02baa76398015ea2a5434d9b8265a7898a6028c1591/numpy-2.4.2-cp313-cp313-win32.whl", hash = "sha256:8e9afaeb0beff068b4d9cd20d322ba0ee1cecfb0b08db145e4ab4dd44a6b5110", size = 5958199, upload-time = "2026-01-31T23:11:35.385Z" }, + { url = "https://files.pythonhosted.org/packages/43/bc/6352f343522fcb2c04dbaf94cb30cca6fd32c1a750c06ad6231b4293708c/numpy-2.4.2-cp313-cp313-win_amd64.whl", hash = "sha256:7df2de1e4fba69a51c06c28f5a3de36731eb9639feb8e1cf7e4a7b0daf4cf622", size = 12310848, upload-time = "2026-01-31T23:11:38.001Z" }, + { url = "https://files.pythonhosted.org/packages/6e/8d/6da186483e308da5da1cc6918ce913dcfe14ffde98e710bfeff2a6158d4e/numpy-2.4.2-cp313-cp313-win_arm64.whl", hash = "sha256:0fece1d1f0a89c16b03442eae5c56dc0be0c7883b5d388e0c03f53019a4bfd71", size = 10221082, upload-time = "2026-01-31T23:11:40.392Z" }, + { url = "https://files.pythonhosted.org/packages/25/a1/9510aa43555b44781968935c7548a8926274f815de42ad3997e9e83680dd/numpy-2.4.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5633c0da313330fd20c484c78cdd3f9b175b55e1a766c4a174230c6b70ad8262", size = 14815866, upload-time = "2026-01-31T23:11:42.495Z" }, + { url = "https://files.pythonhosted.org/packages/36/30/6bbb5e76631a5ae46e7923dd16ca9d3f1c93cfa8d4ed79a129814a9d8db3/numpy-2.4.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:d9f64d786b3b1dd742c946c42d15b07497ed14af1a1f3ce840cce27daa0ce913", size = 5325631, upload-time = "2026-01-31T23:11:44.7Z" }, + { url = "https://files.pythonhosted.org/packages/46/00/3a490938800c1923b567b3a15cd17896e68052e2145d8662aaf3e1ffc58f/numpy-2.4.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:b21041e8cb6a1eb5312dd1d2f80a94d91efffb7a06b70597d44f1bd2dfc315ab", size = 6646254, upload-time = "2026-01-31T23:11:46.341Z" }, + { url = "https://files.pythonhosted.org/packages/d3/e9/fac0890149898a9b609caa5af7455a948b544746e4b8fe7c212c8edd71f8/numpy-2.4.2-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:00ab83c56211a1d7c07c25e3217ea6695e50a3e2f255053686b081dc0b091a82", size = 15720138, upload-time = "2026-01-31T23:11:48.082Z" }, + { url = "https://files.pythonhosted.org/packages/ea/5c/08887c54e68e1e28df53709f1893ce92932cc6f01f7c3d4dc952f61ffd4e/numpy-2.4.2-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2fb882da679409066b4603579619341c6d6898fc83a8995199d5249f986e8e8f", size = 16655398, upload-time = "2026-01-31T23:11:50.293Z" }, + { url = "https://files.pythonhosted.org/packages/4d/89/253db0fa0e66e9129c745e4ef25631dc37d5f1314dad2b53e907b8538e6d/numpy-2.4.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66cb9422236317f9d44b67b4d18f44efe6e9c7f8794ac0462978513359461554", size = 17079064, upload-time = "2026-01-31T23:11:52.927Z" }, + { url = "https://files.pythonhosted.org/packages/2a/d5/cbade46ce97c59c6c3da525e8d95b7abe8a42974a1dc5c1d489c10433e88/numpy-2.4.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0f01dcf33e73d80bd8dc0f20a71303abbafa26a19e23f6b68d1aa9990af90257", size = 18379680, upload-time = "2026-01-31T23:11:55.22Z" }, + { url = "https://files.pythonhosted.org/packages/40/62/48f99ae172a4b63d981babe683685030e8a3df4f246c893ea5c6ef99f018/numpy-2.4.2-cp313-cp313t-win32.whl", hash = "sha256:52b913ec40ff7ae845687b0b34d8d93b60cb66dcee06996dd5c99f2fc9328657", size = 6082433, upload-time = "2026-01-31T23:11:58.096Z" }, + { url = "https://files.pythonhosted.org/packages/07/38/e054a61cfe48ad9f1ed0d188e78b7e26859d0b60ef21cd9de4897cdb5326/numpy-2.4.2-cp313-cp313t-win_amd64.whl", hash = "sha256:5eea80d908b2c1f91486eb95b3fb6fab187e569ec9752ab7d9333d2e66bf2d6b", size = 12451181, upload-time = "2026-01-31T23:11:59.782Z" }, + { url = "https://files.pythonhosted.org/packages/6e/a4/a05c3a6418575e185dd84d0b9680b6bb2e2dc3e4202f036b7b4e22d6e9dc/numpy-2.4.2-cp313-cp313t-win_arm64.whl", hash = "sha256:fd49860271d52127d61197bb50b64f58454e9f578cb4b2c001a6de8b1f50b0b1", size = 10290756, upload-time = "2026-01-31T23:12:02.438Z" }, + { url = "https://files.pythonhosted.org/packages/18/88/b7df6050bf18fdcfb7046286c6535cabbdd2064a3440fca3f069d319c16e/numpy-2.4.2-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:444be170853f1f9d528428eceb55f12918e4fda5d8805480f36a002f1415e09b", size = 16663092, upload-time = "2026-01-31T23:12:04.521Z" }, + { url = "https://files.pythonhosted.org/packages/25/7a/1fee4329abc705a469a4afe6e69b1ef7e915117747886327104a8493a955/numpy-2.4.2-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:d1240d50adff70c2a88217698ca844723068533f3f5c5fa6ee2e3220e3bdb000", size = 14698770, upload-time = "2026-01-31T23:12:06.96Z" }, + { url = "https://files.pythonhosted.org/packages/fb/0b/f9e49ba6c923678ad5bc38181c08ac5e53b7a5754dbca8e581aa1a56b1ff/numpy-2.4.2-cp314-cp314-macosx_14_0_arm64.whl", hash = "sha256:7cdde6de52fb6664b00b056341265441192d1291c130e99183ec0d4b110ff8b1", size = 5208562, upload-time = "2026-01-31T23:12:09.632Z" }, + { url = "https://files.pythonhosted.org/packages/7d/12/d7de8f6f53f9bb76997e5e4c069eda2051e3fe134e9181671c4391677bb2/numpy-2.4.2-cp314-cp314-macosx_14_0_x86_64.whl", hash = "sha256:cda077c2e5b780200b6b3e09d0b42205a3d1c68f30c6dceb90401c13bff8fe74", size = 6543710, upload-time = "2026-01-31T23:12:11.969Z" }, + { url = "https://files.pythonhosted.org/packages/09/63/c66418c2e0268a31a4cf8a8b512685748200f8e8e8ec6c507ce14e773529/numpy-2.4.2-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d30291931c915b2ab5717c2974bb95ee891a1cf22ebc16a8006bd59cd210d40a", size = 15677205, upload-time = "2026-01-31T23:12:14.33Z" }, + { url = "https://files.pythonhosted.org/packages/5d/6c/7f237821c9642fb2a04d2f1e88b4295677144ca93285fd76eff3bcba858d/numpy-2.4.2-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bba37bc29d4d85761deed3954a1bc62be7cf462b9510b51d367b769a8c8df325", size = 16611738, upload-time = "2026-01-31T23:12:16.525Z" }, + { url = "https://files.pythonhosted.org/packages/c2/a7/39c4cdda9f019b609b5c473899d87abff092fc908cfe4d1ecb2fcff453b0/numpy-2.4.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:b2f0073ed0868db1dcd86e052d37279eef185b9c8db5bf61f30f46adac63c909", size = 17028888, upload-time = "2026-01-31T23:12:19.306Z" }, + { url = "https://files.pythonhosted.org/packages/da/b3/e84bb64bdfea967cc10950d71090ec2d84b49bc691df0025dddb7c26e8e3/numpy-2.4.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:7f54844851cdb630ceb623dcec4db3240d1ac13d4990532446761baede94996a", size = 18339556, upload-time = "2026-01-31T23:12:21.816Z" }, + { url = "https://files.pythonhosted.org/packages/88/f5/954a291bc1192a27081706862ac62bb5920fbecfbaa302f64682aa90beed/numpy-2.4.2-cp314-cp314-win32.whl", hash = "sha256:12e26134a0331d8dbd9351620f037ec470b7c75929cb8a1537f6bfe411152a1a", size = 6006899, upload-time = "2026-01-31T23:12:24.14Z" }, + { url = "https://files.pythonhosted.org/packages/05/cb/eff72a91b2efdd1bc98b3b8759f6a1654aa87612fc86e3d87d6fe4f948c4/numpy-2.4.2-cp314-cp314-win_amd64.whl", hash = "sha256:068cdb2d0d644cdb45670810894f6a0600797a69c05f1ac478e8d31670b8ee75", size = 12443072, upload-time = "2026-01-31T23:12:26.33Z" }, + { url = "https://files.pythonhosted.org/packages/37/75/62726948db36a56428fce4ba80a115716dc4fad6a3a4352487f8bb950966/numpy-2.4.2-cp314-cp314-win_arm64.whl", hash = "sha256:6ed0be1ee58eef41231a5c943d7d1375f093142702d5723ca2eb07db9b934b05", size = 10494886, upload-time = "2026-01-31T23:12:28.488Z" }, + { url = "https://files.pythonhosted.org/packages/36/2f/ee93744f1e0661dc267e4b21940870cabfae187c092e1433b77b09b50ac4/numpy-2.4.2-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:98f16a80e917003a12c0580f97b5f875853ebc33e2eaa4bccfc8201ac6869308", size = 14818567, upload-time = "2026-01-31T23:12:30.709Z" }, + { url = "https://files.pythonhosted.org/packages/a7/24/6535212add7d76ff938d8bdc654f53f88d35cddedf807a599e180dcb8e66/numpy-2.4.2-cp314-cp314t-macosx_14_0_arm64.whl", hash = "sha256:20abd069b9cda45874498b245c8015b18ace6de8546bf50dfa8cea1696ed06ef", size = 5328372, upload-time = "2026-01-31T23:12:32.962Z" }, + { url = "https://files.pythonhosted.org/packages/5e/9d/c48f0a035725f925634bf6b8994253b43f2047f6778a54147d7e213bc5a7/numpy-2.4.2-cp314-cp314t-macosx_14_0_x86_64.whl", hash = "sha256:e98c97502435b53741540a5717a6749ac2ada901056c7db951d33e11c885cc7d", size = 6649306, upload-time = "2026-01-31T23:12:34.797Z" }, + { url = "https://files.pythonhosted.org/packages/81/05/7c73a9574cd4a53a25907bad38b59ac83919c0ddc8234ec157f344d57d9a/numpy-2.4.2-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:da6cad4e82cb893db4b69105c604d805e0c3ce11501a55b5e9f9083b47d2ffe8", size = 15722394, upload-time = "2026-01-31T23:12:36.565Z" }, + { url = "https://files.pythonhosted.org/packages/35/fa/4de10089f21fc7d18442c4a767ab156b25c2a6eaf187c0db6d9ecdaeb43f/numpy-2.4.2-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9e4424677ce4b47fe73c8b5556d876571f7c6945d264201180db2dc34f676ab5", size = 16653343, upload-time = "2026-01-31T23:12:39.188Z" }, + { url = "https://files.pythonhosted.org/packages/b8/f9/d33e4ffc857f3763a57aa85650f2e82486832d7492280ac21ba9efda80da/numpy-2.4.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2b8f157c8a6f20eb657e240f8985cc135598b2b46985c5bccbde7616dc9c6b1e", size = 17078045, upload-time = "2026-01-31T23:12:42.041Z" }, + { url = "https://files.pythonhosted.org/packages/c8/b8/54bdb43b6225badbea6389fa038c4ef868c44f5890f95dd530a218706da3/numpy-2.4.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5daf6f3914a733336dab21a05cdec343144600e964d2fcdabaac0c0269874b2a", size = 18380024, upload-time = "2026-01-31T23:12:44.331Z" }, + { url = "https://files.pythonhosted.org/packages/a5/55/6e1a61ded7af8df04016d81b5b02daa59f2ea9252ee0397cb9f631efe9e5/numpy-2.4.2-cp314-cp314t-win32.whl", hash = "sha256:8c50dd1fc8826f5b26a5ee4d77ca55d88a895f4e4819c7ecc2a9f5905047a443", size = 6153937, upload-time = "2026-01-31T23:12:47.229Z" }, + { url = "https://files.pythonhosted.org/packages/45/aa/fa6118d1ed6d776b0983f3ceac9b1a5558e80df9365b1c3aa6d42bf9eee4/numpy-2.4.2-cp314-cp314t-win_amd64.whl", hash = "sha256:fcf92bee92742edd401ba41135185866f7026c502617f422eb432cfeca4fe236", size = 12631844, upload-time = "2026-01-31T23:12:48.997Z" }, + { url = "https://files.pythonhosted.org/packages/32/0a/2ec5deea6dcd158f254a7b372fb09cfba5719419c8d66343bab35237b3fb/numpy-2.4.2-cp314-cp314t-win_arm64.whl", hash = "sha256:1f92f53998a17265194018d1cc321b2e96e900ca52d54c7c77837b71b9465181", size = 10565379, upload-time = "2026-01-31T23:12:51.345Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f8/50e14d36d915ef64d8f8bc4a087fc8264d82c785eda6711f80ab7e620335/numpy-2.4.2-pp311-pypy311_pp73-macosx_10_15_x86_64.whl", hash = "sha256:89f7268c009bc492f506abd6f5265defa7cb3f7487dc21d357c3d290add45082", size = 16833179, upload-time = "2026-01-31T23:12:53.5Z" }, + { url = "https://files.pythonhosted.org/packages/17/17/809b5cad63812058a8189e91a1e2d55a5a18fd04611dbad244e8aeae465c/numpy-2.4.2-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6dee3bb76aa4009d5a912180bf5b2de012532998d094acee25d9cb8dee3e44a", size = 14889755, upload-time = "2026-01-31T23:12:55.933Z" }, + { url = "https://files.pythonhosted.org/packages/3e/ea/181b9bcf7627fc8371720316c24db888dcb9829b1c0270abf3d288b2e29b/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_arm64.whl", hash = "sha256:cd2bd2bbed13e213d6b55dc1d035a4f91748a7d3edc9480c13898b0353708920", size = 5399500, upload-time = "2026-01-31T23:12:58.671Z" }, + { url = "https://files.pythonhosted.org/packages/33/9f/413adf3fc955541ff5536b78fcf0754680b3c6d95103230252a2c9408d23/numpy-2.4.2-pp311-pypy311_pp73-macosx_14_0_x86_64.whl", hash = "sha256:cf28c0c1d4c4bf00f509fa7eb02c58d7caf221b50b467bcb0d9bbf1584d5c821", size = 6714252, upload-time = "2026-01-31T23:13:00.518Z" }, + { url = "https://files.pythonhosted.org/packages/91/da/643aad274e29ccbdf42ecd94dafe524b81c87bcb56b83872d54827f10543/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e04ae107ac591763a47398bb45b568fc38f02dbc4aa44c063f67a131f99346cb", size = 15797142, upload-time = "2026-01-31T23:13:02.219Z" }, + { url = "https://files.pythonhosted.org/packages/66/27/965b8525e9cb5dc16481b30a1b3c21e50c7ebf6e9dbd48d0c4d0d5089c7e/numpy-2.4.2-pp311-pypy311_pp73-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:602f65afdef699cda27ec0b9224ae5dc43e328f4c24c689deaf77133dbee74d0", size = 16727979, upload-time = "2026-01-31T23:13:04.62Z" }, + { url = "https://files.pythonhosted.org/packages/de/e5/b7d20451657664b07986c2f6e3be564433f5dcaf3482d68eaecd79afaf03/numpy-2.4.2-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:be71bf1edb48ebbbf7f6337b5bfd2f895d1902f6335a5830b20141fc126ffba0", size = 12502577, upload-time = "2026-01-31T23:13:07.08Z" }, ] [[package]] name = "packaging" -version = "25.0" +version = "26.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +sdist = { url = "https://files.pythonhosted.org/packages/65/ee/299d360cdc32edc7d2cf530f3accf79c4fca01e96ffc950d8a52213bd8e4/packaging-26.0.tar.gz", hash = "sha256:00243ae351a257117b6a241061796684b084ed1c516a08c48a3f7e147a9d80b4", size = 143416, upload-time = "2026-01-21T20:50:39.064Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, + { url = "https://files.pythonhosted.org/packages/b7/b9/c538f279a4e237a006a2c98387d081e9eb060d203d8ed34467cc0f0b9b53/packaging-26.0-py3-none-any.whl", hash = "sha256:b36f1fef9334a5588b4166f8bcd26a14e521f2b55e6b9de3aaa80d3ff7a37529", size = 74366, upload-time = "2026-01-21T20:50:37.788Z" }, ] [[package]] name = "pandas" version = "2.3.3" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "python-dateutil" }, - { name = "pytz" }, - { name = "tzdata" }, + { name = "python-dateutil", marker = "python_full_version < '3.11'" }, + { name = "pytz", marker = "python_full_version < '3.11'" }, + { name = "tzdata", marker = "python_full_version < '3.11'" }, ] sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } wheels = [ @@ -1133,27 +1148,117 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, ] +[[package]] +name = "pandas" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "python-dateutil", marker = "python_full_version >= '3.11'" }, + { name = "tzdata", marker = "(python_full_version >= '3.11' and sys_platform == 'emscripten') or (python_full_version >= '3.11' and sys_platform == 'win32')" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/de/da/b1dc0481ab8d55d0f46e343cfe67d4551a0e14fcee52bd38ca1bd73258d8/pandas-3.0.0.tar.gz", hash = "sha256:0facf7e87d38f721f0af46fe70d97373a37701b1c09f7ed7aeeb292ade5c050f", size = 4633005, upload-time = "2026-01-21T15:52:04.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/1e/b184654a856e75e975a6ee95d6577b51c271cd92cb2b020c9378f53e0032/pandas-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d64ce01eb9cdca96a15266aa679ae50212ec52757c79204dbc7701a222401850", size = 10313247, upload-time = "2026-01-21T15:50:15.775Z" }, + { url = "https://files.pythonhosted.org/packages/dd/5e/e04a547ad0f0183bf151fd7c7a477468e3b85ff2ad231c566389e6cc9587/pandas-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:613e13426069793aa1ec53bdcc3b86e8d32071daea138bbcf4fa959c9cdaa2e2", size = 9913131, upload-time = "2026-01-21T15:50:18.611Z" }, + { url = "https://files.pythonhosted.org/packages/a2/93/bb77bfa9fc2aba9f7204db807d5d3fb69832ed2854c60ba91b4c65ba9219/pandas-3.0.0-cp311-cp311-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0192fee1f1a8e743b464a6607858ee4b071deb0b118eb143d71c2a1d170996d5", size = 10741925, upload-time = "2026-01-21T15:50:21.058Z" }, + { url = "https://files.pythonhosted.org/packages/62/fb/89319812eb1d714bfc04b7f177895caeba8ab4a37ef6712db75ed786e2e0/pandas-3.0.0-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f0b853319dec8d5e0c8b875374c078ef17f2269986a78168d9bd57e49bf650ae", size = 11245979, upload-time = "2026-01-21T15:50:23.413Z" }, + { url = "https://files.pythonhosted.org/packages/a9/63/684120486f541fc88da3862ed31165b3b3e12b6a1c7b93be4597bc84e26c/pandas-3.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:707a9a877a876c326ae2cb640fbdc4ef63b0a7b9e2ef55c6df9942dcee8e2af9", size = 11756337, upload-time = "2026-01-21T15:50:25.932Z" }, + { url = "https://files.pythonhosted.org/packages/39/92/7eb0ad232312b59aec61550c3c81ad0743898d10af5df7f80bc5e5065416/pandas-3.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:afd0aa3d0b5cda6e0b8ffc10dbcca3b09ef3cbcd3fe2b27364f85fdc04e1989d", size = 12325517, upload-time = "2026-01-21T15:50:27.952Z" }, + { url = "https://files.pythonhosted.org/packages/51/27/bf9436dd0a4fc3130acec0828951c7ef96a0631969613a9a35744baf27f6/pandas-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:113b4cca2614ff7e5b9fee9b6f066618fe73c5a83e99d721ffc41217b2bf57dd", size = 9881576, upload-time = "2026-01-21T15:50:30.149Z" }, + { url = "https://files.pythonhosted.org/packages/e7/2b/c618b871fce0159fd107516336e82891b404e3f340821853c2fc28c7830f/pandas-3.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c14837eba8e99a8da1527c0280bba29b0eb842f64aa94982c5e21227966e164b", size = 9140807, upload-time = "2026-01-21T15:50:32.308Z" }, + { url = "https://files.pythonhosted.org/packages/0b/38/db33686f4b5fa64d7af40d96361f6a4615b8c6c8f1b3d334eee46ae6160e/pandas-3.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9803b31f5039b3c3b10cc858c5e40054adb4b29b4d81cb2fd789f4121c8efbcd", size = 10334013, upload-time = "2026-01-21T15:50:34.771Z" }, + { url = "https://files.pythonhosted.org/packages/a5/7b/9254310594e9774906bacdd4e732415e1f86ab7dbb4b377ef9ede58cd8ec/pandas-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14c2a4099cd38a1d18ff108168ea417909b2dea3bd1ebff2ccf28ddb6a74d740", size = 9874154, upload-time = "2026-01-21T15:50:36.67Z" }, + { url = "https://files.pythonhosted.org/packages/63/d4/726c5a67a13bc66643e66d2e9ff115cead482a44fc56991d0c4014f15aaf/pandas-3.0.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d257699b9a9960e6125686098d5714ac59d05222bef7a5e6af7a7fd87c650801", size = 10384433, upload-time = "2026-01-21T15:50:39.132Z" }, + { url = "https://files.pythonhosted.org/packages/bf/2e/9211f09bedb04f9832122942de8b051804b31a39cfbad199a819bb88d9f3/pandas-3.0.0-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:69780c98f286076dcafca38d8b8eee1676adf220199c0a39f0ecbf976b68151a", size = 10864519, upload-time = "2026-01-21T15:50:41.043Z" }, + { url = "https://files.pythonhosted.org/packages/00/8d/50858522cdc46ac88b9afdc3015e298959a70a08cd21e008a44e9520180c/pandas-3.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4a66384f017240f3858a4c8a7cf21b0591c3ac885cddb7758a589f0f71e87ebb", size = 11394124, upload-time = "2026-01-21T15:50:43.377Z" }, + { url = "https://files.pythonhosted.org/packages/86/3f/83b2577db02503cd93d8e95b0f794ad9d4be0ba7cb6c8bcdcac964a34a42/pandas-3.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:be8c515c9bc33989d97b89db66ea0cececb0f6e3c2a87fcc8b69443a6923e95f", size = 11920444, upload-time = "2026-01-21T15:50:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/64/2d/4f8a2f192ed12c90a0aab47f5557ece0e56b0370c49de9454a09de7381b2/pandas-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:a453aad8c4f4e9f166436994a33884442ea62aa8b27d007311e87521b97246e1", size = 9730970, upload-time = "2026-01-21T15:50:47.962Z" }, + { url = "https://files.pythonhosted.org/packages/d4/64/ff571be435cf1e643ca98d0945d76732c0b4e9c37191a89c8550b105eed1/pandas-3.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:da768007b5a33057f6d9053563d6b74dd6d029c337d93c6d0d22a763a5c2ecc0", size = 9041950, upload-time = "2026-01-21T15:50:50.422Z" }, + { url = "https://files.pythonhosted.org/packages/6f/fa/7f0ac4ca8877c57537aaff2a842f8760e630d8e824b730eb2e859ffe96ca/pandas-3.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b78d646249b9a2bc191040988c7bb524c92fa8534fb0898a0741d7e6f2ffafa6", size = 10307129, upload-time = "2026-01-21T15:50:52.877Z" }, + { url = "https://files.pythonhosted.org/packages/6f/11/28a221815dcea4c0c9414dfc845e34a84a6a7dabc6da3194498ed5ba4361/pandas-3.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:bc9cba7b355cb4162442a88ce495e01cb605f17ac1e27d6596ac963504e0305f", size = 9850201, upload-time = "2026-01-21T15:50:54.807Z" }, + { url = "https://files.pythonhosted.org/packages/ba/da/53bbc8c5363b7e5bd10f9ae59ab250fc7a382ea6ba08e4d06d8694370354/pandas-3.0.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3c9a1a149aed3b6c9bf246033ff91e1b02d529546c5d6fb6b74a28fea0cf4c70", size = 10354031, upload-time = "2026-01-21T15:50:57.463Z" }, + { url = "https://files.pythonhosted.org/packages/f7/a3/51e02ebc2a14974170d51e2410dfdab58870ea9bcd37cda15bd553d24dc4/pandas-3.0.0-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:95683af6175d884ee89471842acfca29172a85031fccdabc35e50c0984470a0e", size = 10861165, upload-time = "2026-01-21T15:50:59.32Z" }, + { url = "https://files.pythonhosted.org/packages/a5/fe/05a51e3cac11d161472b8297bd41723ea98013384dd6d76d115ce3482f9b/pandas-3.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:1fbbb5a7288719e36b76b4f18d46ede46e7f916b6c8d9915b756b0a6c3f792b3", size = 11359359, upload-time = "2026-01-21T15:51:02.014Z" }, + { url = "https://files.pythonhosted.org/packages/ee/56/ba620583225f9b85a4d3e69c01df3e3870659cc525f67929b60e9f21dcd1/pandas-3.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8e8b9808590fa364416b49b2a35c1f4cf2785a6c156935879e57f826df22038e", size = 11912907, upload-time = "2026-01-21T15:51:05.175Z" }, + { url = "https://files.pythonhosted.org/packages/c9/8c/c6638d9f67e45e07656b3826405c5cc5f57f6fd07c8b2572ade328c86e22/pandas-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:98212a38a709feb90ae658cb6227ea3657c22ba8157d4b8f913cd4c950de5e7e", size = 9732138, upload-time = "2026-01-21T15:51:07.569Z" }, + { url = "https://files.pythonhosted.org/packages/7b/bf/bd1335c3bf1770b6d8fed2799993b11c4971af93bb1b729b9ebbc02ca2ec/pandas-3.0.0-cp313-cp313-win_arm64.whl", hash = "sha256:177d9df10b3f43b70307a149d7ec49a1229a653f907aa60a48f1877d0e6be3be", size = 9033568, upload-time = "2026-01-21T15:51:09.484Z" }, + { url = "https://files.pythonhosted.org/packages/8e/c6/f5e2171914d5e29b9171d495344097d54e3ffe41d2d85d8115baba4dc483/pandas-3.0.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2713810ad3806767b89ad3b7b69ba153e1c6ff6d9c20f9c2140379b2a98b6c98", size = 10741936, upload-time = "2026-01-21T15:51:11.693Z" }, + { url = "https://files.pythonhosted.org/packages/51/88/9a0164f99510a1acb9f548691f022c756c2314aad0d8330a24616c14c462/pandas-3.0.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:15d59f885ee5011daf8335dff47dcb8a912a27b4ad7826dc6cbe809fd145d327", size = 10393884, upload-time = "2026-01-21T15:51:14.197Z" }, + { url = "https://files.pythonhosted.org/packages/e0/53/b34d78084d88d8ae2b848591229da8826d1e65aacf00b3abe34023467648/pandas-3.0.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:24e6547fb64d2c92665dd2adbfa4e85fa4fd70a9c070e7cfb03b629a0bbab5eb", size = 10310740, upload-time = "2026-01-21T15:51:16.093Z" }, + { url = "https://files.pythonhosted.org/packages/5b/d3/bee792e7c3d6930b74468d990604325701412e55d7aaf47460a22311d1a5/pandas-3.0.0-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:48ee04b90e2505c693d3f8e8f524dab8cb8aaf7ddcab52c92afa535e717c4812", size = 10700014, upload-time = "2026-01-21T15:51:18.818Z" }, + { url = "https://files.pythonhosted.org/packages/55/db/2570bc40fb13aaed1cbc3fbd725c3a60ee162477982123c3adc8971e7ac1/pandas-3.0.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:66f72fb172959af42a459e27a8d8d2c7e311ff4c1f7db6deb3b643dbc382ae08", size = 11323737, upload-time = "2026-01-21T15:51:20.784Z" }, + { url = "https://files.pythonhosted.org/packages/bc/2e/297ac7f21c8181b62a4cccebad0a70caf679adf3ae5e83cb676194c8acc3/pandas-3.0.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4a4a400ca18230976724a5066f20878af785f36c6756e498e94c2a5e5d57779c", size = 11771558, upload-time = "2026-01-21T15:51:22.977Z" }, + { url = "https://files.pythonhosted.org/packages/0a/46/e1c6876d71c14332be70239acce9ad435975a80541086e5ffba2f249bcf6/pandas-3.0.0-cp313-cp313t-win_amd64.whl", hash = "sha256:940eebffe55528074341a5a36515f3e4c5e25e958ebbc764c9502cfc35ba3faa", size = 10473771, upload-time = "2026-01-21T15:51:25.285Z" }, + { url = "https://files.pythonhosted.org/packages/c0/db/0270ad9d13c344b7a36fa77f5f8344a46501abf413803e885d22864d10bf/pandas-3.0.0-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:597c08fb9fef0edf1e4fa2f9828dd27f3d78f9b8c9b4a748d435ffc55732310b", size = 10312075, upload-time = "2026-01-21T15:51:28.5Z" }, + { url = "https://files.pythonhosted.org/packages/09/9f/c176f5e9717f7c91becfe0f55a52ae445d3f7326b4a2cf355978c51b7913/pandas-3.0.0-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:447b2d68ac5edcbf94655fe909113a6dba6ef09ad7f9f60c80477825b6c489fe", size = 9900213, upload-time = "2026-01-21T15:51:30.955Z" }, + { url = "https://files.pythonhosted.org/packages/d9/e7/63ad4cc10b257b143e0a5ebb04304ad806b4e1a61c5da25f55896d2ca0f4/pandas-3.0.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:debb95c77ff3ed3ba0d9aa20c3a2f19165cc7956362f9873fce1ba0a53819d70", size = 10428768, upload-time = "2026-01-21T15:51:33.018Z" }, + { url = "https://files.pythonhosted.org/packages/9e/0e/4e4c2d8210f20149fd2248ef3fff26623604922bd564d915f935a06dd63d/pandas-3.0.0-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fedabf175e7cd82b69b74c30adbaa616de301291a5231138d7242596fc296a8d", size = 10882954, upload-time = "2026-01-21T15:51:35.287Z" }, + { url = "https://files.pythonhosted.org/packages/c6/60/c9de8ac906ba1f4d2250f8a951abe5135b404227a55858a75ad26f84db47/pandas-3.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:412d1a89aab46889f3033a386912efcdfa0f1131c5705ff5b668dda88305e986", size = 11430293, upload-time = "2026-01-21T15:51:37.57Z" }, + { url = "https://files.pythonhosted.org/packages/a1/69/806e6637c70920e5787a6d6896fd707f8134c2c55cd761e7249a97b7dc5a/pandas-3.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:e979d22316f9350c516479dd3a92252be2937a9531ed3a26ec324198a99cdd49", size = 11952452, upload-time = "2026-01-21T15:51:39.618Z" }, + { url = "https://files.pythonhosted.org/packages/cb/de/918621e46af55164c400ab0ef389c9d969ab85a43d59ad1207d4ddbe30a5/pandas-3.0.0-cp314-cp314-win_amd64.whl", hash = "sha256:083b11415b9970b6e7888800c43c82e81a06cd6b06755d84804444f0007d6bb7", size = 9851081, upload-time = "2026-01-21T15:51:41.758Z" }, + { url = "https://files.pythonhosted.org/packages/91/a1/3562a18dd0bd8c73344bfa26ff90c53c72f827df119d6d6b1dacc84d13e3/pandas-3.0.0-cp314-cp314-win_arm64.whl", hash = "sha256:5db1e62cb99e739fa78a28047e861b256d17f88463c76b8dafc7c1338086dca8", size = 9174610, upload-time = "2026-01-21T15:51:44.312Z" }, + { url = "https://files.pythonhosted.org/packages/ce/26/430d91257eaf366f1737d7a1c158677caaf6267f338ec74e3a1ec444111c/pandas-3.0.0-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:697b8f7d346c68274b1b93a170a70974cdc7d7354429894d5927c1effdcccd73", size = 10761999, upload-time = "2026-01-21T15:51:46.899Z" }, + { url = "https://files.pythonhosted.org/packages/ec/1a/954eb47736c2b7f7fe6a9d56b0cb6987773c00faa3c6451a43db4beb3254/pandas-3.0.0-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:8cb3120f0d9467ed95e77f67a75e030b67545bcfa08964e349252d674171def2", size = 10410279, upload-time = "2026-01-21T15:51:48.89Z" }, + { url = "https://files.pythonhosted.org/packages/20/fc/b96f3a5a28b250cd1b366eb0108df2501c0f38314a00847242abab71bb3a/pandas-3.0.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33fd3e6baa72899746b820c31e4b9688c8e1b7864d7aec2de7ab5035c285277a", size = 10330198, upload-time = "2026-01-21T15:51:51.015Z" }, + { url = "https://files.pythonhosted.org/packages/90/b3/d0e2952f103b4fbef1ef22d0c2e314e74fc9064b51cee30890b5e3286ee6/pandas-3.0.0-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a8942e333dc67ceda1095227ad0febb05a3b36535e520154085db632c40ad084", size = 10728513, upload-time = "2026-01-21T15:51:53.387Z" }, + { url = "https://files.pythonhosted.org/packages/76/81/832894f286df828993dc5fd61c63b231b0fb73377e99f6c6c369174cf97e/pandas-3.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:783ac35c4d0fe0effdb0d67161859078618b1b6587a1af15928137525217a721", size = 11345550, upload-time = "2026-01-21T15:51:55.329Z" }, + { url = "https://files.pythonhosted.org/packages/34/a0/ed160a00fb4f37d806406bc0a79a8b62fe67f29d00950f8d16203ff3409b/pandas-3.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:125eb901e233f155b268bbef9abd9afb5819db74f0e677e89a61b246228c71ac", size = 11799386, upload-time = "2026-01-21T15:51:57.457Z" }, + { url = "https://files.pythonhosted.org/packages/36/c8/2ac00d7255252c5e3cf61b35ca92ca25704b0188f7454ca4aec08a33cece/pandas-3.0.0-cp314-cp314t-win_amd64.whl", hash = "sha256:b86d113b6c109df3ce0ad5abbc259fe86a1bd4adfd4a31a89da42f84f65509bb", size = 10873041, upload-time = "2026-01-21T15:52:00.034Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3f/a80ac00acbc6b35166b42850e98a4f466e2c0d9c64054161ba9620f95680/pandas-3.0.0-cp314-cp314t-win_arm64.whl", hash = "sha256:1c39eab3ad38f2d7a249095f0a3d8f8c22cc0f847e98ccf5bbe732b272e2d9fa", size = 9441003, upload-time = "2026-01-21T15:52:02.281Z" }, +] + [[package]] name = "pandas-stubs" -version = "2.3.3.251201" +version = "2.3.3.260113" source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.11'", +] dependencies = [ { name = "numpy", version = "2.2.6", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, - { name = "types-pytz" }, + { name = "types-pytz", marker = "python_full_version < '3.11'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/ee/a6/491b2af2cb3ee232765a73fb273a44cc1ac33b154f7745b2df2ee1dc4d01/pandas_stubs-2.3.3.251201.tar.gz", hash = "sha256:7a980f4f08cff2a6d7e4c6d6d26f4c5fcdb82a6f6531489b2f75c81567fe4536", size = 107787, upload-time = "2025-12-01T18:29:22.403Z" } +sdist = { url = "https://files.pythonhosted.org/packages/92/5d/be23854a73fda69f1dbdda7bc10fbd6f930bd1fa87aaec389f00c901c1e8/pandas_stubs-2.3.3.260113.tar.gz", hash = "sha256:076e3724bcaa73de78932b012ec64b3010463d377fa63116f4e6850643d93800", size = 116131, upload-time = "2026-01-13T22:30:16.704Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e2/68/78a3c253f146254b8e2c19f4a4768f272e12ef11001d9b45ec7b165db054/pandas_stubs-2.3.3.251201-py3-none-any.whl", hash = "sha256:eb5c9b6138bd8492fd74a47b09c9497341a278fcfbc8633ea4b35b230ebf4be5", size = 164638, upload-time = "2025-12-01T18:29:21.006Z" }, + { url = "https://files.pythonhosted.org/packages/d1/c6/df1fe324248424f77b89371116dab5243db7f052c32cc9fe7442ad9c5f75/pandas_stubs-2.3.3.260113-py3-none-any.whl", hash = "sha256:ec070b5c576e1badf12544ae50385872f0631fc35d99d00dc598c2954ec564d3", size = 168246, upload-time = "2026-01-13T22:30:15.244Z" }, +] + +[[package]] +name = "pandas-stubs" +version = "3.0.0.260204" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", +] +dependencies = [ + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/27/1d/297ff2c7ea50a768a2247621d6451abb2a07c0e9be7ca6d36ebe371658e5/pandas_stubs-3.0.0.260204.tar.gz", hash = "sha256:bf9294b76352effcffa9cb85edf0bed1339a7ec0c30b8e1ac3d66b4228f1fbc3", size = 109383, upload-time = "2026-02-04T15:17:17.247Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/2f/f91e4eee21585ff548e83358332d5632ee49f6b2dcd96cb5dca4e0468951/pandas_stubs-3.0.0.260204-py3-none-any.whl", hash = "sha256:5ab9e4d55a6e2752e9720828564af40d48c4f709e6a2c69b743014a6fcb6c241", size = 168540, upload-time = "2026-02-04T15:17:15.615Z" }, ] [[package]] name = "pathspec" -version = "1.0.3" +version = "1.0.4" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/4c/b2/bb8e495d5262bfec41ab5cb18f522f1012933347fb5d9e62452d446baca2/pathspec-1.0.3.tar.gz", hash = "sha256:bac5cf97ae2c2876e2d25ebb15078eb04d76e4b98921ee31c6f85ade8b59444d", size = 130841, upload-time = "2026-01-09T15:46:46.009Z" } +sdist = { url = "https://files.pythonhosted.org/packages/fa/36/e27608899f9b8d4dff0617b2d9ab17ca5608956ca44461ac14ac48b44015/pathspec-1.0.4.tar.gz", hash = "sha256:0210e2ae8a21a9137c0d470578cb0e595af87edaa6ebf12ff176f14a02e0e645", size = 131200, upload-time = "2026-01-27T03:59:46.938Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/32/2b/121e912bd60eebd623f873fd090de0e84f322972ab25a7f9044c056804ed/pathspec-1.0.3-py3-none-any.whl", hash = "sha256:e80767021c1cc524aa3fb14bedda9c34406591343cc42797b386ce7b9354fb6c", size = 55021, upload-time = "2026-01-09T15:46:44.652Z" }, + { url = "https://files.pythonhosted.org/packages/ef/3c/2c197d226f9ea224a9ab8d197933f9da0ae0aac5b6e0f884e2b8d9c8e9f7/pathspec-1.0.4-py3-none-any.whl", hash = "sha256:fb6ae2fd4e7c921a165808a552060e722767cfa526f99ca5156ed2ce45a5c723", size = 55206, upload-time = "2026-01-27T03:59:45.137Z" }, ] [[package]] @@ -1201,11 +1306,11 @@ wheels = [ [[package]] name = "pycparser" -version = "2.23" +version = "3.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fe/cf/d2d3b9f5699fb1e4615c8e32ff220203e43b248e1dfcc6736ad9057731ca/pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2", size = 173734, upload-time = "2025-09-09T13:23:47.91Z" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a0/e3/59cd50310fc9b59512193629e1984c1f95e5c8ae6e5d8c69532ccc65a7fe/pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934", size = 118140, upload-time = "2025-09-09T13:23:46.651Z" }, + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, ] [[package]] @@ -1388,11 +1493,11 @@ wheels = [ [[package]] name = "soupsieve" -version = "2.8.1" +version = "2.8.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/89/23/adf3796d740536d63a6fbda113d07e60c734b6ed5d3058d1e47fc0495e47/soupsieve-2.8.1.tar.gz", hash = "sha256:4cf733bc50fa805f5df4b8ef4740fc0e0fa6218cf3006269afd3f9d6d80fd350", size = 117856, upload-time = "2025-12-18T13:50:34.655Z" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/ae/2d9c981590ed9999a0d91755b47fc74f74de286b0f5cee14c9269041e6c4/soupsieve-2.8.3.tar.gz", hash = "sha256:3267f1eeea4251fb42728b6dfb746edc9acaffc4a45b27e19450b676586e8349", size = 118627, upload-time = "2026-01-20T04:27:02.457Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/48/f3/b67d6ea49ca9154453b6d70b34ea22f3996b9fa55da105a79d8732227adc/soupsieve-2.8.1-py3-none-any.whl", hash = "sha256:a11fe2a6f3d76ab3cf2de04eb339c1be5b506a8a47f2ceb6d139803177f85434", size = 36710, upload-time = "2025-12-18T13:50:33.267Z" }, + { url = "https://files.pythonhosted.org/packages/46/2c/1462b1d0a634697ae9e55b3cecdcb64788e8b7d63f54d923fcd0bb140aed/soupsieve-2.8.3-py3-none-any.whl", hash = "sha256:ed64f2ba4eebeab06cc4962affce381647455978ffc1e36bb79a545b91f45a95", size = 37016, upload-time = "2026-01-20T04:27:01.012Z" }, ] [[package]] @@ -1438,13 +1543,17 @@ name = "tables" version = "3.10.2" source = { registry = "https://pypi.org/simple" } resolution-markers = [ - "python_full_version >= '3.12'", - "python_full_version == '3.11.*'", + "python_full_version >= '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'win32'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform == 'emscripten'", + "python_full_version >= '3.11' and python_full_version < '3.14' and sys_platform != 'emscripten' and sys_platform != 'win32'", ] dependencies = [ { name = "blosc2", marker = "python_full_version >= '3.11'" }, { name = "numexpr", marker = "python_full_version >= '3.11'" }, - { name = "numpy", version = "2.4.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, + { name = "numpy", version = "2.4.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "packaging", marker = "python_full_version >= '3.11'" }, { name = "py-cpuinfo", marker = "python_full_version >= '3.11'" }, { name = "typing-extensions", marker = "python_full_version >= '3.11'" }, @@ -1533,14 +1642,14 @@ wheels = [ [[package]] name = "tqdm" -version = "4.67.1" +version = "4.67.3" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737, upload-time = "2024-11-24T20:12:22.481Z" } +sdist = { url = "https://files.pythonhosted.org/packages/09/a9/6ba95a270c6f1fbcd8dac228323f2777d886cb206987444e4bce66338dd4/tqdm-4.67.3.tar.gz", hash = "sha256:7d825f03f89244ef73f1d4ce193cb1774a8179fd96f31d7e1dcde62092b960bb", size = 169598, upload-time = "2026-02-03T17:35:53.048Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540, upload-time = "2024-11-24T20:12:19.698Z" }, + { url = "https://files.pythonhosted.org/packages/16/e1/3079a9ff9b8e11b846c6ac5c8b5bfb7ff225eee721825310c91b3b50304f/tqdm-4.67.3-py3-none-any.whl", hash = "sha256:ee1e4c0e59148062281c49d80b25b67771a127c85fc9676d3be5f243206826bf", size = 78374, upload-time = "2026-02-03T17:35:50.982Z" }, ] [[package]] @@ -1611,7 +1720,8 @@ dependencies = [ { name = "beautifulsoup4" }, { name = "curl-cffi" }, { name = "lxml" }, - { name = "pandas" }, + { name = "pandas", version = "2.3.3", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.11'" }, + { name = "pandas", version = "3.0.0", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.11'" }, { name = "requests-futures" }, { name = "tqdm" }, ] From 6cfca566bee6343dee4847fbc9e52163d01542f8 Mon Sep 17 00:00:00 2001 From: "pre-commit-ci[bot]" <66853113+pre-commit-ci[bot]@users.noreply.github.com> Date: Thu, 5 Feb 2026 15:54:12 +0000 Subject: [PATCH 2/6] [pre-commit.ci] auto fixes from pre-commit.com hooks for more information, see https://pre-commit.ci --- src/market_prices/pt.py | 4 +++- tests/test_base_prices.py | 3 ++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/market_prices/pt.py b/src/market_prices/pt.py index 05ed05b..920106f 100644 --- a/src/market_prices/pt.py +++ b/src/market_prices/pt.py @@ -1340,7 +1340,9 @@ def _downsample_months( if not pre_table_sessions.empty: start_ds = pd_offset.rollforward(start_table) df = df[start_ds:] - resampled = helpers.resample(df, pdfreq, origin="start_day", nominal_start=start_ds) + resampled = helpers.resample( + df, pdfreq, origin="start_day", nominal_start=start_ds + ) resampled.index = pdutils.get_interval_index(resampled.index, pdfreq) if drop_incomplete_last_indice: diff --git a/tests/test_base_prices.py b/tests/test_base_prices.py index 8ed1417..0dfc9c5 100644 --- a/tests/test_base_prices.py +++ b/tests/test_base_prices.py @@ -1229,7 +1229,8 @@ def test__get_table_daily(prices_us, one_day, monkeypatch): table.index.left, pd.date_range(expected_start_left, freq="MS", periods=12) ) assert_index_equal( - table.index.right, pd.date_range(expected_start_right, freq="MS", periods=12) + table.index.right, + pd.date_range(expected_start_right, freq="MS", periods=12), ) # verify force_ds_daily=True returns daily table From edad16e1e1ab45b9f0a50dc106164c1eddc235b8 Mon Sep 17 00:00:00 2001 From: Marcus Read Date: Thu, 5 Feb 2026 16:56:55 +0000 Subject: [PATCH 3/6] Linting Removes unused code. --- src/market_prices/pt.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/src/market_prices/pt.py b/src/market_prices/pt.py index 920106f..1c1d322 100644 --- a/src/market_prices/pt.py +++ b/src/market_prices/pt.py @@ -1289,17 +1289,6 @@ def _downsample_cbdays( def _downsample_days(self, pdfreq: str | pd.offsets.Day) -> pd.DataFrame: """Downsample to a frequency with unit "D".""" df = self.prices - - if isinstance(pdfreq, str): - n, _ = helpers.extract_freq_parts(pdfreq) - elif isinstance(pdfreq, pd.offsets.Day): - n = pdfreq.n - else: - raise TypeError( - "'pdfreq' should be passed as a `str` or `pd.offsets.Day` although" - f" received {pdfreq} of type {type(pdfreq)}." - ) - pd_offset = pd.tseries.frequencies.to_offset(pdfreq) # `origin` should reflect left side of last indice From 9134bc11399eac246d6eb6583d7e56da17b8de67 Mon Sep 17 00:00:00 2001 From: Marcus Read Date: Thu, 5 Feb 2026 17:50:42 +0000 Subject: [PATCH 4/6] Linting Further changes to ruff. --- .pre-commit-config.yaml | 2 +- src/market_prices/prices/csv.py | 7 ++++--- tests/test_daterange.py | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index f0b1714..c122664 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -7,7 +7,7 @@ repos: - id: trailing-whitespace repo: https://github.com/astral-sh/ruff-pre-commit # Ruff version. - rev: v0.13.0 + rev: v0.15.0 hooks: # Run the linter. - id: ruff-check diff --git a/src/market_prices/prices/csv.py b/src/market_prices/prices/csv.py index 503e055..b14ca7c 100644 --- a/src/market_prices/prices/csv.py +++ b/src/market_prices/prices/csv.py @@ -33,8 +33,9 @@ CSV_READ_DFLT_KWARGS: dict[str, Any] = { "header": 0, - "usecols": lambda x: x.lower() - in ["date", "open", "high", "low", "close", "volume"], + "usecols": lambda x: ( + x.lower() in ["date", "open", "high", "low", "close", "volume"] + ), "index_col": "date", "parse_dates": ["date"], } @@ -118,7 +119,7 @@ def _get_symbol_from_filename(name: str, symbols: list[str]) -> str | None: # at least two different symbols in filename return None symbol = part - return symbol if symbol else None + return symbol or None def _get_interval_from_filename(name: str) -> TDInterval | None: diff --git a/tests/test_daterange.py b/tests/test_daterange.py index 60900e0..c2baa6e 100644 --- a/tests/test_daterange.py +++ b/tests/test_daterange.py @@ -10,10 +10,10 @@ """ import contextlib -from datetime import timedelta import itertools import re from collections import abc +from datetime import timedelta import exchange_calendars as xcals import hypothesis as hyp From b82846f3132c38163270acde78b6dbfed664c3ba Mon Sep 17 00:00:00 2001 From: Marcus Read Date: Thu, 5 Feb 2026 18:32:23 +0000 Subject: [PATCH 5/6] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index b4c8a74..1c5bd7b 100644 --- a/README.md +++ b/README.md @@ -271,6 +271,8 @@ The first beta version of `market_prices` was released May 2022. Whilst the test suite is pretty comprehensive, there will inevitably be bugs. Please do raise an [issue](https://github.com/maread99/market_prices/issues) with any that you come across. Even better, offer a PR! Contributions welcome. +The package is actively maintained to work with the latest versions of its dependencies, which include `numpy` and `pandas`. **Only limited consideration is given to backwards compatibility with earlier versions of dependencies** - no guarantees are offered in this regard. Of note, whilst the latest release works with pandas v3 and v2, support for pandas v1 was dropped some time ago. + Please use [discussions](https://github.com/maread99/market_prices/discussions) to make any suggestions and offer general feedback. ## Disclaimers From 8d97cd8396d05f1d9f63884441d927ee7d129e01 Mon Sep 17 00:00:00 2001 From: Marcus Read Date: Thu, 5 Feb 2026 19:19:49 +0000 Subject: [PATCH 6/6] Revise tests for pandas 2.3.3 compatibility Revises tests for pandas 2.3.3 compatibility, in turn providing for maintaining min supported python version as 3.10. --- src/market_prices/utils/pandas_utils.py | 25 ++++++++++++++----------- tests/test_csv.py | 6 ++++-- tests/test_pandas_utils.py | 5 +++-- tests/test_pt.py | 7 +++++-- 4 files changed, 26 insertions(+), 17 deletions(-) diff --git a/src/market_prices/utils/pandas_utils.py b/src/market_prices/utils/pandas_utils.py index 0ef1175..9178d13 100644 --- a/src/market_prices/utils/pandas_utils.py +++ b/src/market_prices/utils/pandas_utils.py @@ -94,15 +94,14 @@ def timestamps_in_interval_of_intervals( ... pd.Timestamp('2021-03-16 13:00'), ... ] ... ) - >>> start, end = pd.Timestamp('2021-03-02'), pd.Timestamp('2021-03-31') + >>> start, end = pd.Timestamp('2021-03-02').as_unit("ns"), pd.Timestamp('2021-03-31').as_unit("ns") >>> closed = "both" >>> intervals = pd.interval_range(start, end, freq="3D", closed=closed) >>> timestamps_in_interval_of_intervals(timestamps, intervals) False - >>> intervals = pd.interval_range(start, end, freq="10D", closed=closed) >>> intervals - IntervalIndex([[2021-03-02 00:00:00, 2021-03-12 00:00:00], [2021-03-12 00:00:00, 2021-03-22 00:00:00]], dtype='interval[datetime64[us], both]') + IntervalIndex([[2021-03-02 00:00:00, 2021-03-12 00:00:00], [2021-03-12 00:00:00, 2021-03-22 00:00:00]], dtype='interval[datetime64[ns], both]') >>> timestamps_in_interval_of_intervals(timestamps, intervals) True """ # noqa: E501 @@ -594,14 +593,16 @@ def indexes_union(indexes: list[pd.Index]) -> pd.Index: Examples -------- - >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1h') - >>> index2 = pd.date_range('2021-05-02 17:10', periods=2, freq='22min') - >>> index3 = pd.date_range('2021-05-03', periods=2, freq='1D') + >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1h').as_unit("ns") + >>> index2 = pd.date_range( + ... '2021-05-02 17:10', periods=2, freq='22min' + ... ).as_unit("ns") + >>> index3 = pd.date_range('2021-05-03', periods=2, freq='1D').as_unit("ns") >>> indexes_union([index1, index2, index3]) DatetimeIndex(['2021-05-01 12:20:00', '2021-05-01 13:20:00', '2021-05-02 17:10:00', '2021-05-02 17:32:00', '2021-05-03 00:00:00', '2021-05-04 00:00:00'], - dtype='datetime64[us]', freq=None) + dtype='datetime64[ns]', freq=None) """ index = indexes[0] for indx in indexes[1:]: @@ -621,16 +622,18 @@ def index_union(indexes: list[pd.Index | pd.Series | pd.DataFrame]) -> pd.Index: Examples -------- - >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1h') - >>> index2 = pd.date_range('2021-05-02 17:10', periods=2, freq='22min') - >>> index3 = pd.date_range('2021-05-03', periods=2, freq='1D') + >>> index1 = pd.date_range('2021-05-01 12:20', periods=2, freq='1h').as_unit("ns") + >>> index2 = pd.date_range( + ... '2021-05-02 17:10', periods=2, freq='22min' + ... ).as_unit("ns") + >>> index3 = pd.date_range('2021-05-03', periods=2, freq='1D').as_unit("ns") >>> ser = pd.Series(range(2), index=index2) >>> df = pd.DataFrame({'col_int': range(2)}, index=index3) >>> index_union([index1, ser, df]) DatetimeIndex(['2021-05-01 12:20:00', '2021-05-01 13:20:00', '2021-05-02 17:10:00', '2021-05-02 17:32:00', '2021-05-03 00:00:00', '2021-05-04 00:00:00'], - dtype='datetime64[us]', freq=None) + dtype='datetime64[ns]', freq=None) """ indexes_ = [obj if isinstance(obj, pd.Index) else obj.index for obj in indexes] return indexes_union(indexes_) diff --git a/tests/test_csv.py b/tests/test_csv.py index 8f7f2a6..061fb05 100644 --- a/tests/test_csv.py +++ b/tests/test_csv.py @@ -682,9 +682,10 @@ def test_raises_csv_no_data_error(csv_dir, symbols, calendars): # assign non-overlapping calendar so that all indices are rejected when compiling table calendars["MSFTEXTRA"] = "XHKG" + res = "us" if pd.__version__ >= "3.0.0" else "ns" match = ( re.escape( - f"For symbols '['MSFT', 'AZN.L', '9988.HK', 'MSFTEXTRA']' it was not possible to create a price table for any interval from csv files. The following errors and warnings occurred during parsing:\n\n0) Prices are not available at base interval {TDInterval.T20} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n1) Prices are not available at base interval {TDInterval.T1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n2) Prices are not available at base interval {TDInterval.D1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n3) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n4) Prices are not available at base interval {TDInterval.T2} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n5) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[us, UTC]', freq=None)\n\n6) For symbol 'MSFTEXTRA with interval '{TDInterval.T5}' no indice aligned with index evaluated from calendar 'XHKG'.\n\n7) Prices are not available at base interval {TDInterval.T5} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\nSee the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter." + f"For symbols '['MSFT', 'AZN.L', '9988.HK', 'MSFTEXTRA']' it was not possible to create a price table for any interval from csv files. The following errors and warnings occurred during parsing:\n\n0) Prices are not available at base interval {TDInterval.T20} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n1) Prices are not available at base interval {TDInterval.T1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n2) Prices are not available at base interval {TDInterval.D1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n3) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n4) Prices are not available at base interval {TDInterval.T2} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\n5) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[{res}, UTC]', freq=None)\n\n6) For symbol 'MSFTEXTRA with interval '{TDInterval.T5}' no indice aligned with index evaluated from calendar 'XHKG'.\n\n7) Prices are not available at base interval {TDInterval.T5} as (aligned) data was not found at this interval for symbols '['MSFTEXTRA']'.\n\nSee the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter." ) if WINDOWS else None @@ -694,9 +695,10 @@ def test_raises_csv_no_data_error(csv_dir, symbols, calendars): def test_consolidated_warning(csv_dir, symbols, calendars): + res = "us" if pd.__version__ >= "3.0.0" else "ns" match = ( re.escape( - f"Price data has been found for all symbols at a least one interval, however, you may find that not all the expected price data is available. See the `limits` property for available base intervals and the limits between which price data is available at each of these intervals. See the `csv_paths` property for paths to all csv files that were found for the requested symbols. See the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter.\n\nThe following errors and/or warnings occurred during parsing:\n\n0) Unable to create dataframe from csv file at 'f_9988.HK_T20_fails_on_ohlc_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n1) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t 'volume' column will not convert to 'float64' dtype.\nThe source error's message was:\n\t: could not convert string to float: 'not a volume'\n\n2) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n3) Unable to create dataframe from csv file at 'f_AZN.L_T20_fails_on_read_csv.csv' due to the following error:\n\t `pd.read_csv` raises error.\nThe source error's message was:\n\t: could not convert string to float: 'not_digits'\n\n4) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t No price data parsed from csv file.\n\n5) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n6) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t At least one row has a high value that is lower than the corresponding low value.\n\n7) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n8) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['AZN.L', 'MSFT']'.\n\n9) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[us, UTC]', freq=None)" + f"Price data has been found for all symbols at a least one interval, however, you may find that not all the expected price data is available. See the `limits` property for available base intervals and the limits between which price data is available at each of these intervals. See the `csv_paths` property for paths to all csv files that were found for the requested symbols. See the 'path' parameter and 'Notes' sections of help(PricesCsv) for advices on how csv files should be named and formatted and for use of the `read_csv_kwargs` parameter.\n\nThe following errors and/or warnings occurred during parsing:\n\n0) Unable to create dataframe from csv file at 'f_9988.HK_T20_fails_on_ohlc_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n1) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t 'volume' column will not convert to 'float64' dtype.\nThe source error's message was:\n\t: could not convert string to float: 'not a volume'\n\n2) Unable to create dataframe from csv file at 'f_AZN.L_H1_fails_on_vol_dtype.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n3) Unable to create dataframe from csv file at 'f_AZN.L_T20_fails_on_read_csv.csv' due to the following error:\n\t `pd.read_csv` raises error.\nThe source error's message was:\n\t: could not convert string to float: 'not_digits'\n\n4) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t No price data parsed from csv file.\n\n5) Unable to create dataframe from csv file at 'f_MSFT_H1_fails_on_no_data.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n6) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t At least one row has a high value that is lower than the corresponding low value.\n\n7) Unable to create dataframe from csv file at 'f_MSFT_T20_fails_on_high_low.csv' due to the following error:\n\t Date indices do not reflect the expected interval.\n\n8) Prices are not available at base interval {TDInterval.H1} as (aligned) data was not found at this interval for symbols '['AZN.L', 'MSFT']'.\n\n9) For symbol 'MSFT' at base interval {TDInterval.T5} the csv file included the following indices that are not aligned with the evaluated index and: have therefore been ignored:\nDatetimeIndex(['2022-04-18 16:02:00+00:00'], dtype='datetime64[{res}, UTC]', freq=None)" ) if WINDOWS else None diff --git a/tests/test_pandas_utils.py b/tests/test_pandas_utils.py index 9b5d002..5f94e48 100644 --- a/tests/test_pandas_utils.py +++ b/tests/test_pandas_utils.py @@ -156,7 +156,8 @@ def mock_func( match = re.escape( "'arg' can only take a pd.IntervalIndex that has each side" " as type pd.DatetimeIndex, although received with left side" - " as type ''." + " as type ''.") diff --git a/tests/test_pt.py b/tests/test_pt.py index 9424765..96a4c2d 100644 --- a/tests/test_pt.py +++ b/tests/test_pt.py @@ -303,14 +303,17 @@ def test_new_constructor_errors( " although index is of type ."): + + with pytest.raises(TypeError, match=match) as excinfo: _ = daily_df.pt + assert str(excinfo.value).endswith("RangeIndex'>.") intraday_df = intraday_pt.copy() intraday_df.index = pd.interval_range(start=0, periods=len(intraday_pt), freq=1) - with pytest.raises(TypeError, match=match + "Index'>."): + with pytest.raises(TypeError, match=match) as excinfo: _ = intraday_df.pt + assert str(excinfo.value).endswith(".Index'>.") daily_df = daily_pt.copy() daily_df.index = daily_df.index + pd.Timedelta(1, "min")