|
32 | 32 |
|
33 | 33 | _ISO_DATE_RE = re.compile(r"^(\d{4})-(\d{2})-(\d{2})$") |
34 | 34 | _NUMERIC_DATE_RE = re.compile(r"^(\d{4})/(\d{2})/(\d{2})$") |
| 35 | +# Full month names and common abbreviations ("Mar", "Sept.") — GPU list tables |
| 36 | +# write dates like "Mar 11, 2010" and "Dec 2024". |
| 37 | +_MONTH_NAME = ( |
| 38 | + r"(Jan(?:uary)?|Feb(?:ruary)?|Mar(?:ch)?|Apr(?:il)?|May|June?|July?|" |
| 39 | + r"Aug(?:ust)?|Sep(?:t(?:ember)?)?|Oct(?:ober)?|Nov(?:ember)?|Dec(?:ember)?)\.?" |
| 40 | +) |
35 | 41 | _LONG_DATE_RE = re.compile( |
36 | | - r"\b(" |
37 | | - r"January|February|March|April|May|June|July|" |
38 | | - r"August|September|October|November|December" |
39 | | - r")\s+(\d{1,2}),?\s+(\d{4})\b", |
| 42 | + r"\b" + _MONTH_NAME + r"\s+(\d{1,2}),?\s+(\d{4})\b", |
40 | 43 | re.IGNORECASE, |
41 | 44 | ) |
42 | 45 | _SHORT_DATE_RE = re.compile( |
43 | | - r"\b(\d{1,2})\s+(" |
44 | | - r"January|February|March|April|May|June|July|" |
45 | | - r"August|September|October|November|December" |
46 | | - r")\s+(\d{4})\b", |
| 46 | + r"\b(\d{1,2})\s+" + _MONTH_NAME + r"\s+(\d{4})\b", |
47 | 47 | re.IGNORECASE, |
48 | 48 | ) |
49 | 49 | _QUARTER_RE = re.compile(r"\bQ([1-4])\s*'?(\d{2}|\d{4})\b", re.IGNORECASE) |
50 | | -_MONTH_YEAR_RE = re.compile( |
51 | | - r"\b(January|February|March|April|May|June|July|" |
52 | | - r"August|September|October|November|December)\s+(\d{4})\b", |
53 | | - re.IGNORECASE, |
54 | | -) |
| 50 | +_MONTH_YEAR_RE = re.compile(r"\b" + _MONTH_NAME + r"\s+(\d{4})\b", re.IGNORECASE) |
55 | 51 | _YEAR_ONLY_RE = re.compile(r"\b(19\d{2}|20\d{2})\b") |
56 | 52 |
|
57 | 53 | _MONTHS = { |
58 | | - name.lower(): index |
| 54 | + name.lower()[:3]: index |
59 | 55 | for index, name in enumerate( |
60 | 56 | [ |
61 | 57 | "January", "February", "March", "April", "May", "June", |
@@ -151,17 +147,17 @@ def parse_date(text: str) -> date | None: |
151 | 147 | return _safe_date(year, month, day) |
152 | 148 | if (match := _LONG_DATE_RE.search(stripped)): |
153 | 149 | month_name, day_str, year_str = match.group(1), match.group(2), match.group(3) |
154 | | - return _safe_date(int(year_str), _MONTHS[month_name.lower()], int(day_str)) |
| 150 | + return _safe_date(int(year_str), _MONTHS[month_name.lower()[:3]], int(day_str)) |
155 | 151 | if (match := _SHORT_DATE_RE.search(stripped)): |
156 | 152 | day_str, month_name, year_str = match.group(1), match.group(2), match.group(3) |
157 | | - return _safe_date(int(year_str), _MONTHS[month_name.lower()], int(day_str)) |
| 153 | + return _safe_date(int(year_str), _MONTHS[month_name.lower()[:3]], int(day_str)) |
158 | 154 | if (match := _QUARTER_RE.search(stripped)): |
159 | 155 | quarter = int(match.group(1)) |
160 | 156 | year_raw = match.group(2) |
161 | 157 | year = 2000 + int(year_raw) if len(year_raw) == 2 else int(year_raw) |
162 | 158 | return _safe_date(year, (quarter - 1) * 3 + 1, 1) |
163 | 159 | if (match := _MONTH_YEAR_RE.search(stripped)): |
164 | | - return _safe_date(int(match.group(2)), _MONTHS[match.group(1).lower()], 1) |
| 160 | + return _safe_date(int(match.group(2)), _MONTHS[match.group(1).lower()[:3]], 1) |
165 | 161 | if (match := _YEAR_ONLY_RE.search(stripped)): |
166 | 162 | return _safe_date(int(match.group(1)), 1, 1) |
167 | 163 | return None |
@@ -221,6 +217,8 @@ def guess_gpu_segment(name: str) -> str: |
221 | 217 | "instinct", "mi300", "mi325", "mi350", |
222 | 218 | "data center", "datacenter", "professional", "radeon pro", |
223 | 219 | "rtx 6000", "rtx 5000", "rtx 4500", "rtx 4000", |
| 220 | + # Workstation lines, matching where the curated records file them. |
| 221 | + "firepro", "nvs ", "rtx pro", |
224 | 222 | ) |
225 | 223 | if any(token in lowered for token in enterprise_tokens): |
226 | 224 | return "enterprise" |
|
0 commit comments