From 1187cdc02ceef67b5a32b6b1f9f549a1aa139cc5 Mon Sep 17 00:00:00 2001 From: Jeremy Carbaugh <39159+jcarbaugh@users.noreply.github.com> Date: Wed, 20 May 2026 21:50:45 -0400 Subject: [PATCH 1/3] Add ASSOCIATED_STATES for Marshall Islands, FSM, and Palau Add entries for the three Compact of Free Association associated states to a new top-level ASSOCIATED_STATES list. These are sovereign nations, not US states or territories, so they are kept out of STATES_AND_TERRITORIES and are not returned by lookup(). A new is_associated boolean on State distinguishes them programmatically, matching the existing is_territory / is_obsolete pattern. Co-Authored-By: Claude Opus 4.7 (1M context) --- CHANGELOG.md | 1 + README.md | 10 ++++ us/__init__.py | 2 + us/states.py | 124 ++++++++++++++++++++++++++++++++++++++++++++ us/tests/test_us.py | 34 ++++++++++-- 5 files changed, 168 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index cb50574..396ca27 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## 4.0.0 +* add `ASSOCIATED_STATES` list with entries for Marshall Islands, Federated States of Micronesia, and Palau, plus a new `is_associated` attribute on `State` * add counties, thanks to [Ray Kiddy](https://github.com/rkiddy) * add `clean_name()` method and `fallback_func` parameter to `lookup()` to provide customizable matching, thanks to [Max Filenko](https://github.com/mfilenko) and [Charlie Tonneslan](https://github.com/c-tonneslan) * DC has returned to `STATES_AND_TERRITORIES`, thanks to [Kavi Gupta](https://github.com/kavigupta) diff --git a/README.md b/README.md index fba5d56..ac23e6c 100644 --- a/README.md +++ b/README.md @@ -111,6 +111,16 @@ There's also a list of obsolete territories: [, , ] ``` +And a list of associated states — sovereign nations in free association with +the United States under the Compact of Free Association. They are not US +states or territories, and are not included in `STATES_AND_TERRITORIES` or +returned by `lookup()`: + +```python +>>> us.states.ASSOCIATED_STATES +[, , ] +``` + The state lookup method allows matching by FIPS code, abbreviation, and name: ```python diff --git a/us/__init__.py b/us/__init__.py index fb152c7..d420486 100644 --- a/us/__init__.py +++ b/us/__init__.py @@ -5,6 +5,7 @@ TERRITORIES, STATES_AND_TERRITORIES, OBSOLETE, + ASSOCIATED_STATES, ) from .unitedstatesofamerica import name, abbr, birthday @@ -33,6 +34,7 @@ def __getattr__(name): "TERRITORIES", "STATES_AND_TERRITORIES", "OBSOLETE", + "ASSOCIATED_STATES", "name", "abbr", "birthday", diff --git a/us/states.py b/us/states.py index a86bef5..cd19149 100644 --- a/us/states.py +++ b/us/states.py @@ -42,6 +42,7 @@ class State: is_obsolete: bool is_contiguous: bool is_continental: bool + is_associated: bool name: str name_metaphone: str statehood_year: Optional[int] @@ -218,6 +219,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1819, "capital": "Montgomery", "capital_tz": "America/Chicago", @@ -306,6 +308,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": True, + "is_associated": False, "statehood_year": 1959, "capital": "Juneau", "capital_tz": "America/Anchorage", @@ -357,6 +360,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": None, "capital": "Pago Pago", "capital_tz": "Pacific/Samoa", @@ -383,6 +387,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1912, "capital": "Phoenix", "capital_tz": "America/Phoenix", @@ -419,6 +424,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1836, "capital": "Little Rock", "capital_tz": "America/Chicago", @@ -515,6 +521,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1850, "capital": "Sacramento", "capital_tz": "America/Los_Angeles", @@ -594,6 +601,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1876, "capital": "Denver", "capital_tz": "America/Denver", @@ -679,6 +687,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Hartford", "capital_tz": "America/New_York", @@ -708,6 +717,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": True, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": None, "capital": "Yankton", "capital_tz": "America/Chicago", @@ -728,6 +738,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1787, "capital": "Dover", "capital_tz": "America/New_York", @@ -752,6 +763,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": None, "capital": None, "capital_tz": "America/New_York", @@ -774,6 +786,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1845, "capital": "Tallahassee", "capital_tz": "America/New_York", @@ -853,6 +866,27 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N ) +FM = State( + **{ + "fips": "64", + "name": "Federated States of Micronesia", + "abbr": "FM", + "is_territory": False, + "is_obsolete": False, + "is_contiguous": False, + "is_continental": False, + "is_associated": True, + "statehood_year": None, + "capital": "Palikir", + "capital_tz": "Pacific/Pohnpei", + "ap_abbr": None, + "time_zones": ["Pacific/Chuuk", "Pacific/Pohnpei", "Pacific/Kosrae"], + "name_metaphone": "FTRTT STTS OF MKRNX", + "counties": [], + } +) + + GA = State( **{ "fips": "13", @@ -862,6 +896,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Atlanta", "capital_tz": "America/New_York", @@ -1042,6 +1077,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": None, "capital": "Hagåtña", "capital_tz": "Pacific/Guam", @@ -1064,6 +1100,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": 1959, "capital": "Honolulu", "capital_tz": "Pacific/Honolulu", @@ -1090,6 +1127,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1890, "capital": "Boise", "capital_tz": "America/Denver", @@ -1155,6 +1193,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1818, "capital": "Springfield", "capital_tz": "America/Chicago", @@ -1278,6 +1317,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1816, "capital": "Indianapolis", "capital_tz": "America/Indiana/Indianapolis", @@ -1404,6 +1444,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1846, "capital": "Des Moines", "capital_tz": "America/Chicago", @@ -1524,6 +1565,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1861, "capital": "Topeka", "capital_tz": "America/Chicago", @@ -1650,6 +1692,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1792, "capital": "Frankfort", "capital_tz": "America/New_York", @@ -1796,6 +1839,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1812, "capital": "Baton Rouge", "capital_tz": "America/Chicago", @@ -1881,6 +1925,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1820, "capital": "Augusta", "capital_tz": "America/New_York", @@ -1918,6 +1963,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Annapolis", "capital_tz": "America/New_York", @@ -1954,6 +2000,27 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N ) +MH = State( + **{ + "fips": "68", + "name": "Marshall Islands", + "abbr": "MH", + "is_territory": False, + "is_obsolete": False, + "is_contiguous": False, + "is_continental": False, + "is_associated": True, + "statehood_year": None, + "capital": "Majuro", + "capital_tz": "Pacific/Majuro", + "ap_abbr": None, + "time_zones": ["Pacific/Majuro", "Pacific/Kwajalein"], + "name_metaphone": "MRXL ISLNTS", + "counties": [], + } +) + + MA = State( **{ "fips": "25", @@ -1963,6 +2030,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Boston", "capital_tz": "America/New_York", @@ -1998,6 +2066,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1837, "capital": "Lansing", "capital_tz": "America/New_York", @@ -2102,6 +2171,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1858, "capital": "Saint Paul", "capital_tz": "America/Chicago", @@ -2210,6 +2280,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1817, "capital": "Jackson", "capital_tz": "America/Chicago", @@ -2313,6 +2384,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1821, "capital": "Jefferson City", "capital_tz": "America/Chicago", @@ -2449,6 +2521,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1889, "capital": "Helena", "capital_tz": "America/Denver", @@ -2526,6 +2599,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1867, "capital": "Lincoln", "capital_tz": "America/Chicago", @@ -2640,6 +2714,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1864, "capital": "Carson City", "capital_tz": "America/Los_Angeles", @@ -2678,6 +2753,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Concord", "capital_tz": "America/New_York", @@ -2709,6 +2785,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1787, "capital": "Trenton", "capital_tz": "America/New_York", @@ -2751,6 +2828,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1912, "capital": "Santa Fe", "capital_tz": "America/Denver", @@ -2805,6 +2883,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Albany", "capital_tz": "America/New_York", @@ -2888,6 +2967,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1789, "capital": "Raleigh", "capital_tz": "America/New_York", @@ -3009,6 +3089,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1889, "capital": "Bismarck", "capital_tz": "America/North_Dakota/Center", @@ -3089,6 +3170,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": None, "capital": "Saipan", "capital_tz": "Pacific/Guam", @@ -3114,6 +3196,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1803, "capital": "Columbus", "capital_tz": "America/New_York", @@ -3223,6 +3306,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1907, "capital": "Oklahoma City", "capital_tz": "America/Chicago", @@ -3321,6 +3405,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1859, "capital": "Salem", "capital_tz": "America/Los_Angeles", @@ -3378,6 +3463,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": True, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": None, "capital": None, "capital_tz": None, @@ -3389,6 +3475,27 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N ) +PW = State( + **{ + "fips": "70", + "name": "Palau", + "abbr": "PW", + "is_territory": False, + "is_obsolete": False, + "is_contiguous": False, + "is_continental": False, + "is_associated": True, + "statehood_year": None, + "capital": "Ngerulmud", + "capital_tz": "Pacific/Palau", + "ap_abbr": None, + "time_zones": ["Pacific/Palau"], + "name_metaphone": "PL", + "counties": [], + } +) + + PA = State( **{ "fips": "42", @@ -3398,6 +3505,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1787, "capital": "Harrisburg", "capital_tz": "America/New_York", @@ -3486,6 +3594,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": True, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": None, "capital": None, "capital_tz": None, @@ -3506,6 +3615,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": None, "capital": "San Juan", "capital_tz": "America/Puerto_Rico", @@ -3605,6 +3715,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1790, "capital": "Providence", "capital_tz": "America/New_York", @@ -3631,6 +3742,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Columbia", "capital_tz": "America/New_York", @@ -3698,6 +3810,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1889, "capital": "Pierre", "capital_tz": "America/Chicago", @@ -3785,6 +3898,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1796, "capital": "Nashville", "capital_tz": "America/Chicago", @@ -3901,6 +4015,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1845, "capital": "Austin", "capital_tz": "America/Chicago", @@ -4176,6 +4291,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1896, "capital": "Salt Lake City", "capital_tz": "America/Denver", @@ -4226,6 +4342,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1791, "capital": "Montpelier", "capital_tz": "America/New_York", @@ -4261,6 +4378,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": False, "is_continental": False, + "is_associated": False, "statehood_year": None, "capital": "Charlotte Amalie", "capital_tz": "America/Puerto_Rico", @@ -4285,6 +4403,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1788, "capital": "Richmond", "capital_tz": "America/New_York", @@ -4439,6 +4558,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1889, "capital": "Olympia", "capital_tz": "America/Los_Angeles", @@ -4499,6 +4619,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1863, "capital": "Charleston", "capital_tz": "America/New_York", @@ -4575,6 +4696,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1848, "capital": "Madison", "capital_tz": "America/Chicago", @@ -4668,6 +4790,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N "is_obsolete": False, "is_contiguous": True, "is_continental": True, + "is_associated": False, "statehood_year": 1890, "capital": "Cheyenne", "capital_tz": "America/Denver", @@ -4705,6 +4828,7 @@ def enumeration(value_field: str = "name", states: Optional[Iterable[State]] = N OBSOLETE: List[State] = [DK, OL, PI] TERRITORIES: List[State] = [AS, GU, MP, PR, VI] +ASSOCIATED_STATES: List[State] = [FM, MH, PW] STATES: List[State] = [ AL, AK, diff --git a/us/tests/test_us.py b/us/tests/test_us.py index b98482f..e14144d 100644 --- a/us/tests/test_us.py +++ b/us/tests/test_us.py @@ -12,7 +12,7 @@ def test_attribute(): - for state in us.STATES_AND_TERRITORIES: + for state in chain(us.STATES_AND_TERRITORIES, us.ASSOCIATED_STATES): assert state == getattr(us.states, state.abbr) @@ -23,7 +23,7 @@ def test_version_deprecation(): def test_valid_timezones(): - for state in us.STATES_AND_TERRITORIES: + for state in chain(us.STATES_AND_TERRITORIES, us.ASSOCIATED_STATES): if state.capital: assert pytz.timezone(state.capital_tz) for tz in state.time_zones: @@ -176,7 +176,7 @@ def test_lookup_cache_hit_short_circuit(): def test_jellyfish_metaphone(): - for state in chain(us.STATES_AND_TERRITORIES, us.OBSOLETE): + for state in chain(us.STATES_AND_TERRITORIES, us.OBSOLETE, us.ASSOCIATED_STATES): assert state.name_metaphone == jellyfish.metaphone(state.name) @@ -289,6 +289,34 @@ def test_continental(): assert len(us.STATES_CONTINENTAL) == 49 +# associated states (Compact of Free Association) + + +def test_associated_states_count(): + assert len(us.ASSOCIATED_STATES) == 3 + + +def test_associated_states_not_in_states_and_territories(): + for state in us.ASSOCIATED_STATES: + assert state not in us.STATES_AND_TERRITORIES + + +def test_associated_states_lookup_returns_none(): + # lookup() only scans STATES_AND_TERRITORIES, so associated states + # are deliberately unreachable through it + for state in us.ASSOCIATED_STATES: + assert us.states.lookup(state.abbr) is None + assert us.states.lookup(state.name) is None + assert us.states.lookup(state.fips) is None + + +def test_associated_states_have_is_associated_flag(): + for state in us.ASSOCIATED_STATES: + assert state.is_associated is True + for state in chain(us.STATES_AND_TERRITORIES, us.OBSOLETE): + assert state.is_associated is False + + # counties From 7198b6aeda896fb8747014ad2a5d91d1825a7963 Mon Sep 17 00:00:00 2001 From: Jeremy Carbaugh <39159+jcarbaugh@users.noreply.github.com> Date: Wed, 20 May 2026 22:05:06 -0400 Subject: [PATCH 2/3] adjust CHANGELOG --- .gitignore | 1 + CHANGELOG.md | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index 1ee4e63..1b2b3fa 100644 --- a/.gitignore +++ b/.gitignore @@ -8,6 +8,7 @@ dist/ .cache/ .mypy_cache/ .pytest_cache/ +.ruff_cache/ .tox/ __pycache__/ *.pyc diff --git a/CHANGELOG.md b/CHANGELOG.md index 396ca27..798022c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,8 +2,8 @@ ## 4.0.0 -* add `ASSOCIATED_STATES` list with entries for Marshall Islands, Federated States of Micronesia, and Palau, plus a new `is_associated` attribute on `State` * add counties, thanks to [Ray Kiddy](https://github.com/rkiddy) +* add `ASSOCIATED_STATES` list with entries for Marshall Islands, Federated States of Micronesia, and Palau, plus a new `is_associated` attribute on `State` * add `clean_name()` method and `fallback_func` parameter to `lookup()` to provide customizable matching, thanks to [Max Filenko](https://github.com/mfilenko) and [Charlie Tonneslan](https://github.com/c-tonneslan) * DC has returned to `STATES_AND_TERRITORIES`, thanks to [Kavi Gupta](https://github.com/kavigupta) * change ND time zone from America/Boise to America/Denver From 3e67952ae9252cff47f6e53d5b933f100878b358 Mon Sep 17 00:00:00 2001 From: Jeremy Carbaugh <39159+jcarbaugh@users.noreply.github.com> Date: Wed, 20 May 2026 22:11:44 -0400 Subject: [PATCH 3/3] adjust README --- README.md | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index ac23e6c..b1c738d 100644 --- a/README.md +++ b/README.md @@ -104,16 +104,9 @@ Some states like to be fancy and call themselves commonwealths: [, , , ] ``` -There's also a list of obsolete territories: - -```python ->>> us.states.OBSOLETE -[, , ] -``` - -And a list of associated states — sovereign nations in free association with +There's a list of associated states, sovereign nations in free association with the United States under the Compact of Free Association. They are not US -states or territories, and are not included in `STATES_AND_TERRITORIES` or +states or territories and are not included in `STATES_AND_TERRITORIES` or returned by `lookup()`: ```python @@ -121,6 +114,13 @@ returned by `lookup()`: [, , ] ``` +And a list of obsolete territories: + +```python +>>> us.states.OBSOLETE +[, , ] +``` + The state lookup method allows matching by FIPS code, abbreviation, and name: ```python