aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authornatsuoto <[email protected]>2026-07-11 17:10:05 +0530
committernatsuoto <[email protected]>2026-07-11 17:10:05 +0530
commitef2e40b7eb1c5c29a9ec5f203e2927dc42a533e2 (patch)
treefd1ad74c079af76f6d1d31d8920ec6b212ca3851
parentef0d136cb9c6517c39bf0d693663034791eb0508 (diff)
downloadedify-ef2e40b7eb1c5c29a9ec5f203e2927dc42a533e2.tar.xz
edify-ef2e40b7eb1c5c29a9ec5f203e2927dc42a533e2.zip
refactor(library): rewrite geo/postal to inline patterns; delete RegexBackedPattern escape hatch
-rw-r--r--edify/library/_support/regex.py43
-rw-r--r--edify/library/_support/zip.py272
-rw-r--r--edify/library/address/cidr.py17
-rw-r--r--edify/library/address/ip.py36
-rw-r--r--edify/library/address/path.py15
-rw-r--r--edify/library/address/ptr.py7
-rw-r--r--edify/library/address/socket.py10
-rw-r--r--edify/library/color/color.py6
-rw-r--r--edify/library/contact/email.py21
-rw-r--r--edify/library/contact/phone.py7
-rw-r--r--edify/library/financial/wallet.py8
-rw-r--r--edify/library/geo/coordinate.py22
-rw-r--r--edify/library/geo/postal.py242
-rw-r--r--edify/library/media/extension.py9
-rw-r--r--edify/library/media/glob.py10
-rw-r--r--edify/library/medical/medical.py20
-rw-r--r--edify/library/numeric/integer.py8
-rw-r--r--edify/library/numeric/number.py10
-rw-r--r--edify/library/numeric/ratio.py9
-rw-r--r--edify/library/publishing/arxiv.py7
-rw-r--r--edify/library/publishing/pmc.py9
-rw-r--r--edify/library/publishing/pmid.py8
-rw-r--r--edify/library/software/ref.py23
-rw-r--r--edify/library/temporal/cron.py7
-rw-r--r--edify/library/temporal/datetime.py61
-rw-r--r--edify/library/temporal/duration.py29
-rw-r--r--edify/library/temporal/epoch.py10
-rw-r--r--edify/library/temporal/interval.py57
-rw-r--r--edify/library/temporal/offset.py6
-rw-r--r--edify/library/temporal/time.py41
-rw-r--r--edify/library/temporal/timestamp.py10
-rw-r--r--edify/library/temporal/timezone.py7
-rw-r--r--edify/library/text/alpha.py8
-rw-r--r--edify/library/text/alphanumeric.py8
-rw-r--r--edify/library/text/ascii.py8
-rw-r--r--edify/library/text/base.py19
-rw-r--r--edify/library/text/emoji.py2
-rw-r--r--edify/library/text/numeric.py8
-rw-r--r--edify/library/text/printable.py12
-rw-r--r--edify/library/text/script.py21
-rw-r--r--edify/library/text/unicode.py12
-rw-r--r--edify/library/text/word.py8
-rw-r--r--tests/library/media/regex.test.py13
-rw-r--r--tests/library/password.test.py4
44 files changed, 451 insertions, 719 deletions
diff --git a/edify/library/_support/regex.py b/edify/library/_support/regex.py
deleted file mode 100644
index 69ab05b..0000000
--- a/edify/library/_support/regex.py
+++ /dev/null
@@ -1,43 +0,0 @@
-"""Private base class for validators whose regex is authored as a raw string.
-
-Used by the built-in library validators that carry a regex too dense to author
-as a fluent chain (RFC 5322 email, full IPv6 form, etc.). The base class stores
-the raw regex string, compiles it once at construction time, and threads it
-through :meth:`to_regex_string`, :meth:`to_regex`, and :meth:`__call__` so the
-resulting instance is indistinguishable from a fluent-chain :class:`Pattern`
-for the purposes of ``isinstance``, ``.match()``, and the ``pattern(value)``
-call form.
-"""
-
-from __future__ import annotations
-
-import re
-
-from edify.pattern.composition import Pattern
-from edify.result.regex import Regex
-
-
-class RegexBackedPattern(Pattern):
- """A :class:`Pattern` whose emitted regex is a pre-authored raw string.
-
- Attributes:
- raw_regex_string: The exact regex string emitted by :meth:`to_regex_string`.
- """
-
- def __init__(self, raw_regex_string: str) -> None:
- super().__init__()
- self._raw_regex_string = raw_regex_string
- self._compiled_regex = re.compile(raw_regex_string)
-
- @property
- def raw_regex_string(self) -> str:
- """Return the raw regex string this pattern was constructed from."""
- return self._raw_regex_string
-
- def to_regex_string(self) -> str:
- """Return the raw regex string verbatim."""
- return self._raw_regex_string
-
- def to_regex(self) -> Regex:
- """Return a :class:`Regex` wrapping the pre-compiled pattern."""
- return Regex(self._raw_regex_string, self._compiled_regex, ())
diff --git a/edify/library/_support/zip.py b/edify/library/_support/zip.py
deleted file mode 100644
index 9695a9d..0000000
--- a/edify/library/_support/zip.py
+++ /dev/null
@@ -1,272 +0,0 @@
-# flake8: noqa
-
-ZIP_LOCALES = [
- {"abbrev": "AF", "name": "Afghanistan", "zip": "[0-9]{4}"},
- {"abbrev": "AL", "name": "Albania", "zip": "(120|122)[0-9]{2}"},
- {"abbrev": "DZ", "name": "Algeria", "zip": "[0-9]{5}"},
- {"abbrev": "AS", "name": "American Samoa", "zip": "[0-9]{5}"},
- {"abbrev": "AD", "name": "Andorra", "zip": "[0-9]{5}"},
- {"abbrev": "AO", "name": "Angola"},
- {"abbrev": "AI", "name": "Anguilla", "zip": "AI-2640"},
- {"abbrev": "AG", "name": "Antigua and Barbuda"},
- {"abbrev": "AR", "name": "Argentina", "zip": "[A-Z]{1}[0-9]{4}[A-Z]{3}"},
- {"abbrev": "AM", "name": "Armenia", "zip": "[0-9]{4}"},
- {"abbrev": "AW", "name": "Aruba"},
- {"abbrev": "AU", "name": "Australia", "zip": "[0-9]{4}"},
- {"abbrev": "AT", "name": "Austria", "zip": "[0-9]{4}"},
- {"abbrev": "AZ", "name": "Azerbaijan", "zip": "[0-9]{4}"},
- {"abbrev": "BS", "name": "Bahamas"},
- {"abbrev": "BH", "name": "Bahrain"},
- {"abbrev": "BD", "name": "Bangladesh", "zip": "[0-9]{4}"},
- {"abbrev": "BB", "name": "Barbados", "zip": "BB[0-9]{5}"},
- {"abbrev": "BY", "name": "Belarus", "zip": "[0-9]{6}"},
- {"abbrev": "BE", "name": "Belgium", "zip": "[0-9]{4}"},
- {"abbrev": "BZ", "name": "Belize"},
- {"abbrev": "BJ", "name": "Benin"},
- {"abbrev": "BM", "name": "Bermuda", "zip": "[A-Z]{2}[0-9]{2}"},
- {"abbrev": "BT", "name": "Bhutan", "zip": "[0-9]{5}"},
- {"abbrev": "BO", "name": "Bolivia"},
- {"abbrev": "BQ", "name": "Bonaire"},
- {"abbrev": "BA", "name": "Bosnia and Herzegovina", "zip": "[0-9]{5}"},
- {"abbrev": "BW", "name": "Botswana"},
- {"abbrev": "BR", "name": "Brazil", "zip": "[0-9]{5}-[0-9]{3}"},
- {"abbrev": "BN", "name": "Brunei", "zip": "[A-Z]{2}[0-9]{4}"},
- {"abbrev": "BG", "name": "Bulgaria", "zip": "[0-9]{4}"},
- {"abbrev": "BF", "name": "Burkina Faso"},
- {"abbrev": "BI", "name": "Burundi"},
- {"abbrev": "KH", "name": "Cambodia", "zip": "[0-9]{5}"},
- {"abbrev": "CM", "name": "Cameroon"},
- {"abbrev": "CA", "name": "Canada", "zip": "[A-Z][0-9][A-Z] ?[0-9][A-Z][0-9]"},
- {"abbrev": "CI", "name": "Canary Islands", "zip": "[0-9]{5}"},
- {"abbrev": "CV", "name": "Cape Verde", "zip": "[0-9]{4}"},
- {"abbrev": "KY", "name": "Cayman Islands", "zip": "[A-Z]{2}[0-9]-[0-9]{4}"},
- {"abbrev": "CF", "name": "Central African Republic"},
- {"abbrev": "TD", "name": "Chad"},
- {"abbrev": "CI", "name": "Channel Islands", "zip": "[A-Z]{2}[0-9]{2}"},
- {"abbrev": "CL", "name": "Chile", "zip": "[0-9]{7}"},
- {"abbrev": "CN", "name": "China, People's Republic", "zip": "[0-9]{6}"},
- {"abbrev": "CO", "name": "Colombia", "zip": "[0-9]{6}"},
- {"abbrev": "KM", "name": "Comoros"},
- {"abbrev": "CG", "name": "Congo"},
- {"abbrev": "CD", "name": "Congo, The Democratic Republic of"},
- {"abbrev": "CK", "name": "Cook Islands"},
- {"abbrev": "CR", "name": "Costa Rica", "zip": "[0-9]{5}"},
- {"abbrev": "CI", "name": "Côte d'Ivoire"},
- {"abbrev": "HR", "name": "Croatia", "zip": "[0-9]{5}"},
- {"abbrev": "CU", "name": "Cuba", "zip": "[0-9]{5}"},
- {"abbrev": "CW", "name": "Curacao"},
- {"abbrev": "CY", "name": "Cyprus", "zip": "[0-9]{4}"},
- {"abbrev": "CZ", "name": "Czech Republic", "zip": "[0-9]{3} [0-9]{2}"},
- {"abbrev": "DK", "name": "Denmark", "zip": "[0-9]{5}"},
- {"abbrev": "DJ", "name": "Djibouti"},
- {"abbrev": "DM", "name": "Dominica"},
- {"abbrev": "DO", "name": "Dominican Republic", "zip": "[0-9]{5}"},
- {"abbrev": "TL", "name": "East Timor"},
- {"abbrev": "EC", "name": "Ecuador", "zip": "[0-9]{6}"},
- {"abbrev": "EG", "name": "Egypt", "zip": "[0-9]{5}"},
- {"abbrev": "SV", "name": "El Salvador", "zip": "[0-9]{4}"},
- {"abbrev": "ER", "name": "Eritrea"},
- {"abbrev": "EE", "name": "Estonia", "zip": "[0-9]{5}"},
- {"abbrev": "ET", "name": "Ethiopia", "zip": "[0-9]{4}"},
- {"abbrev": "FK", "name": "Falkland Islands", "zip": "FIQQ 1ZZ"},
- {"abbrev": "FO", "name": "Faroe Islands", "zip": "[0-9]{3}"},
- {"abbrev": "FJ", "name": "Fiji"},
- {"abbrev": "FI", "name": "Finland", "zip": "[0-9]{5}"},
- {"abbrev": "FR", "name": "France", "zip": "[0-9]{5}"},
- {"abbrev": "PF", "name": "French Polynesia", "zip": "987[0-9]{2}", "range": ["98700", "98790"]},
- {"abbrev": "GA", "name": "Gabon"},
- {"abbrev": "GM", "name": "Gambia"},
- {"abbrev": "GE", "name": "Georgia"},
- {"abbrev": "DE", "name": "Germany", "zip": "[0-9]{5}"},
- {"abbrev": "GH", "name": "Ghana"},
- {"abbrev": "GI", "name": "Gibraltar", "zip": "GX11 1AA"},
- {"abbrev": "GR", "name": "Greece", "zip": "[0-9]{3} [0-9]{2}"},
- {"abbrev": "GL", "name": "Greenland", "zip": "[0-9]{4}"},
- {"abbrev": "GD", "name": "Grenada"},
- {"abbrev": "GP", "name": "Guadeloupe", "zip": "971[0-9]{2}", "range": ["97100", "97190"]},
- {"abbrev": "GU", "name": "Guam", "zip": "\\d{5}(?:[-\\s]\\d{4})?", "range": ["96910", "96932"]},
- {"abbrev": "GT", "name": "Guatemala", "zip": "[0-9]{5}"},
- {
- "abbrev": "GG",
- "name": "Guernsey",
- "zip": "([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\\s?[0-9][A-Za-z]{2})",
- },
- {"abbrev": "GW", "name": "Guinea-Bissau", "zip": "[0-9]{4}"},
- {"abbrev": "GQ", "name": "Guinea-Equatorial"},
- {"abbrev": "GN", "name": "Guinea Republic", "zip": "[0-9]{3}"},
- {"abbrev": "GY", "name": "Guyana (British)"},
- {"abbrev": "GF", "name": "Guyana (French)", "zip": "973[0-9]{2}", "range": ["97300", "97390"]},
- {"abbrev": "HT", "name": "Haiti", "zip": "[0-9]{4}"},
- {"abbrev": "HN", "name": "Honduras", "zip": "[0-9]{5}"},
- {"abbrev": "HK", "name": "Hong Kong"},
- {"abbrev": "HU", "name": "Hungary", "zip": "[0-9]{4}"},
- {"abbrev": "IS", "name": "Iceland", "zip": "[0-9]{3}"},
- {"abbrev": "IN", "name": "India", "zip": "^(?!0{1})\\d{6}$"},
- {"abbrev": "ID", "name": "Indonesia", "zip": "[0-9]{5}"},
- {"abbrev": "IR", "name": "Iran", "zip": "[0-9]{5}"},
- {"abbrev": "IQ", "name": "Iraq", "zip": "[0-9]{5}"},
- {
- "abbrev": "IE",
- "name": "Ireland, Republic of",
- "zip": "(?:^[AC-FHKNPRTV-Y][0-9]{2}|D6W)[ -]?[0-9AC-FHKNPRTV-Y]{4}$",
- },
- {"abbrev": "FK", "name": "Islas Malvinas", "zip": "FIQQ 1ZZ"},
- {"abbrev": "IL", "name": "Israel", "zip": "[0-9]{5}|[0-9]{7}"},
- {"abbrev": "IT", "name": "Italy", "zip": "[0-9]{5}"},
- {"abbrev": "CI", "name": "Ivory Coast"},
- {"abbrev": "JM", "name": "Jamaica"},
- {"abbrev": "JP", "name": "Japan", "zip": "[0-9]{3}-[0-9]{4}"},
- {
- "abbrev": "JE",
- "name": "Jersey",
- "zip": "([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\\s?[0-9][A-Za-z]{2})",
- },
- {"abbrev": "JO", "name": "Jordan", "zip": "[0-9]{5}"},
- {"abbrev": "KZ", "name": "Kazakhstan", "zip": "[0-9]{6}"},
- {"abbrev": "KE", "name": "Kenya", "zip": "[0-9]{5}"},
- {"abbrev": "KI", "name": "Kiribati"},
- {"abbrev": "KR", "name": "Korea, Republic of", "zip": "[0-9]{5}"},
- {"abbrev": "KP", "name": "Korea, The D.P.R of"},
- {"abbrev": "XK", "name": "Kosovo", "zip": "[0-9]{5}"},
- {"abbrev": "KW", "name": "Kuwait", "zip": "[0-9]{5}"},
- {"abbrev": "KG", "name": "Kyrgyzstan", "zip": "[0-9]{6}"},
- {"abbrev": "LA", "name": "Laos", "zip": "[0-9]{5}"},
- {"abbrev": "LV", "name": "Latvia", "zip": "LV-[0-9]{4}"},
- {"abbrev": "LB", "name": "Lebanon", "zip": "[0-9]{4} [0-9]{4}"},
- {"abbrev": "LS", "name": "Lesotho", "zip": "[0-9]{3}"},
- {"abbrev": "LR", "name": "Liberia", "zip": "[0-9]{4}"},
- {"abbrev": "LY", "name": "Libya"},
- {"abbrev": "LI", "name": "Liechtenstein", "zip": "[0-9]{4}", "range": ["9485", "9498"]},
- {"abbrev": "LT", "name": "Lithuania", "zip": "LT-[0-9]{5}"},
- {"abbrev": "LU", "name": "Luxembourg", "zip": "[0-9]{4}"},
- {"abbrev": "MO", "name": "Macau"},
- {"abbrev": "MK", "name": "Macedonia, Republic of", "zip": "[0-9]{4}"},
- {"abbrev": "MG", "name": "Madagascar", "zip": "[0-9]{3}"},
- {"abbrev": "MW", "name": "Malawi"},
- {"abbrev": "MY", "name": "Malaysia", "zip": "[0-9]{5}"},
- {"abbrev": "MV", "name": "Maldives", "zip": "[0-9]{5}"},
- {"abbrev": "ML", "name": "Mali"},
- {"abbrev": "MT", "name": "Malta", "zip": "[A-Z]{3} [0-9]{4}"},
- {
- "abbrev": "MH",
- "name": "Marshall Islands",
- "zip": "\\d{5}(?:[-\\s]\\d{4})?",
- "range": ["96960", "96970"],
- },
- {"abbrev": "MQ", "name": "Martinique", "zip": "972[0-9]{2}", "range": ["97200", "97290"]},
- {"abbrev": "MR", "name": "Mauritania"},
- {"abbrev": "MU", "name": "Mauritius", "zip": "[0-9]{5}"},
- {"abbrev": "YT", "name": "Mayotte", "zip": "976[0-9]{2}", "range": ["97600", "97690"]},
- {"abbrev": "MX", "name": "Mexico", "zip": "[0-9]{5}"},
- {"abbrev": "MD", "name": "Moldova, Republic of", "zip": "MD-?[0-9]{4}"},
- {"abbrev": "MC", "name": "Monaco", "zip": "980[0-9]{2}"},
- {"abbrev": "MN", "name": "Mongolia", "zip": "[0-9]{5}"},
- {"abbrev": "ME", "name": "Montenegro", "zip": "[0-9]{5}"},
- {
- "abbrev": "MS",
- "name": "Montserrat",
- "zip": "MSR [0-9]{4}",
- "range": ["MSR 1110", "MSR 1350"],
- },
- {"abbrev": "MA", "name": "Morocco", "zip": "[0-9]{5}"},
- {"abbrev": "MZ", "name": "Mozambique", "zip": "[0-9]{4}"},
- {"abbrev": "MM", "name": "Myanmar", "zip": "[0-9]{5}"},
- {"abbrev": "NA", "name": "Namibia"},
- {"abbrev": "NR", "name": "Nauru"},
- {"abbrev": "NP", "name": "Nepal", "zip": "[0-9]{5}"},
- {"abbrev": "NL", "name": "Netherlands", "zip": "(?:NL-)?(\\d{4})\\s*([A-Z]{2})"},
- {"abbrev": "NC", "name": "New Caledonia", "zip": "988[0-9]{2}", "range": ["96950", "96952"]},
- {"abbrev": "NZ", "name": "New Zealand", "zip": "[0-9]{4}"},
- {"abbrev": "NI", "name": "Nicaragua"},
- {"abbrev": "NE", "name": "Niger", "zip": "[0-9]{4}"},
- {"abbrev": "NG", "name": "Nigeria", "zip": "[0-9]{6}"},
- {"abbrev": "NU", "name": "Niue"},
- {"abbrev": "MP", "name": "Northern Mariana Islands", "zip": "^\\d{5}(?:[-\\s]\\d{4})?$"},
- {"abbrev": "NO", "name": "Norway", "zip": "[0-9]{4}"},
- {"abbrev": "OM", "name": "Oman", "zip": "[0-9]{3}"},
- {"abbrev": "PK", "name": "Pakistan", "zip": "[0-9]{5}"},
- {"abbrev": "PW", "name": "Palau", "zip": "\\d{5}(?:[-\\s]\\d{4})?"},
- {"abbrev": "PA", "name": "Panama", "zip": "[0-9]{4}"},
- {"abbrev": "PG", "name": "Papua New Guinea", "zip": "[0-9]{3}"},
- {"abbrev": "PY", "name": "Paraguay", "zip": "[0-9]{4}"},
- {"abbrev": "PE", "name": "Peru", "zip": "[0-9]{5}"},
- {"abbrev": "PH", "name": "Philippines", "zip": "[0-9]{4}"},
- {"abbrev": "PL", "name": "Poland", "zip": "[0-9]{2}-[0-9]{3}"},
- {"abbrev": "PT", "name": "Portugal", "zip": "[0-9]{4}-[0-9]{3}"},
- {"abbrev": "PR", "name": "Puerto Rico", "zip": "\\d{5}(?:[-\\s]\\d{4})?"},
- {"abbrev": "QA", "name": "Qatar"},
- {"abbrev": "RE", "name": "Réunion", "zip": "974[0-9]{2}", "range": ["97400", "97490"]},
- {"abbrev": "RO", "name": "Romania", "zip": "[0-9]{6}"},
- {"abbrev": "RU", "name": "Russian Federation", "zip": "[0-9]{6}"},
- {"abbrev": "RW", "name": "Rwanda"},
- {"abbrev": "MP", "name": "Saipan", "zip": "96950"},
- {"abbrev": "WS", "name": "Samoa", "zip": "WS[0-9]{4}"},
- {"abbrev": "ST", "name": "Sao Tome and Principe"},
- {"abbrev": "SA", "name": "Saudi Arabia", "zip": "[0-9]{5}(-[0-9]{4})?"},
- {"abbrev": "SN", "name": "Senegal", "zip": "[0-9]{5}"},
- {"abbrev": "RS", "name": "Serbia", "zip": "[0-9]{5}"},
- {"abbrev": "SC", "name": "Seychelles"},
- {"abbrev": "SL", "name": "Sierra Leone"},
- {"abbrev": "SG", "name": "Singapore", "zip": "[0-9]{6}"},
- {"abbrev": "SK", "name": "Slovakia", "zip": "[0-9]{3} [0-9]{2}"},
- {"abbrev": "SI", "name": "Slovenia", "zip": "[0-9]{4}"},
- {"abbrev": "SB", "name": "Solomon Islands"},
- {"abbrev": "SO", "name": "Somalia", "zip": "[A-Z]{2} [0-9]{5}"},
- {"abbrev": "ZA", "name": "South Africa", "zip": "[0-9]{4}"},
- {"abbrev": "SS", "name": "South Sudan"},
- {"abbrev": "ES", "name": "Spain", "zip": "[0-9]{5}"},
- {"abbrev": "LK", "name": "Sri Lanka", "zip": "[0-9]{4}"},
- {"abbrev": "BL", "name": "St. Barthélemy", "zip": "[0-9]{5}", "range": ["97100", "97190"]},
- {"abbrev": "VI", "name": "St. Croix", "zip": "[0-9]{5}"},
- {"abbrev": "SE", "name": "St. Eustatius"},
- {"abbrev": "SH", "name": "St. Helena", "zip": "STHL 1ZZ"},
- {"abbrev": "AG", "name": "St. John", "zip": "\\d{5}(?:[-\\s]\\d{4})?"},
- {"abbrev": "KN", "name": "St. Kitts and Nevis", "zip": "[A-Z]{2}[0-9]{4}"},
- {"abbrev": "LC", "name": "St. Lucia", "zip": "[A-Z]{2}[0-9]{2} [0-9]{3}"},
- {"abbrev": "SX", "name": "St. Maarten"},
- {"abbrev": "VI", "name": "St. Thomas"},
- {"abbrev": "VC", "name": "St. Vincent and the Grenadines", "zip": "VC[0-9]{4}"},
- {"abbrev": "SD", "name": "Sudan", "zip": "[0-9]{5}"},
- {"abbrev": "SR", "name": "Suriname"},
- {"abbrev": "SZ", "name": "Swaziland", "zip": "[A-Z]{1}[0-9]{3}"},
- {"abbrev": "SE", "name": "Sweden", "zip": "[0-9]{3} [0-9]{2}"},
- {"abbrev": "CH", "name": "Switzerland", "zip": "[0-9]{4}"},
- {"abbrev": "SY", "name": "Syria"},
- {"abbrev": "PF", "name": "Tahiti", "zip": "[0-9]{5}"},
- {"abbrev": "TW", "name": "Taiwan", "zip": "[0-9]{3}(-[0-9]{2})?"},
- {"abbrev": "TZ", "name": "Tanzania", "zip": "[0-9]{5}"},
- {"abbrev": "TH", "name": "Thailand", "zip": "[0-9]{5}"},
- {"abbrev": "TG", "name": "Togo"},
- {"abbrev": "TO", "name": "Tonga"},
- {"abbrev": "VG", "name": "Tortola", "zip": "VG[0-9]{4}"},
- {"abbrev": "TT", "name": "Trinidad and Tobago", "zip": "[0-9]{6}"},
- {"abbrev": "TN", "name": "Tunisia", "zip": "[0-9]{4}"},
- {"abbrev": "TR", "name": "Turkey", "zip": "[0-9]{5}"},
- {"abbrev": "TM", "name": "Turkmenistan", "zip": "[0-9]{6}"},
- {"abbrev": "TC", "name": "Turks and Caicos Islands", "zip": "TKCA 1ZZ"},
- {"abbrev": "TV", "name": "Tuvalu"},
- {"abbrev": "UG", "name": "Uganda"},
- {"abbrev": "UA", "name": "Ukraine", "zip": "[0-9]{5}"},
- {"abbrev": "AE", "name": "United Arab Emirates"},
- {
- "abbrev": "GB",
- "name": "United Kingdom",
- "zip": "([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\\s?[0-9][A-Za-z]{2})",
- },
- {"abbrev": "US", "name": "United States of America", "zip": "^[0-9]{5}(?:-[0-9]{4})?$"},
- {"abbrev": "UY", "name": "Uruguay", "zip": "[0-9]{5}"},
- {"abbrev": "UZ", "name": "Uzbekistan", "zip": "[0-9]{6}"},
- {"abbrev": "VU", "name": "Vanuatu"},
- {"abbrev": "VE", "name": "Venezuela", "zip": "[0-9]{4}(-[A-Z]{1})?"},
- {"abbrev": "VN", "name": "Vietnam", "zip": "[0-9]{6}"},
- {"abbrev": "VG", "name": "Virgin Islands (British)", "zip": "VG[0-9]{4}"},
- {
- "abbrev": "VI",
- "name": "Virgin Islands (US)",
- "range": ["00801", "00851"],
- "zip": "\\d{5}(?:[-\\s]\\d{4})?",
- },
- {"abbrev": "YE", "name": "Yemen"},
- {"abbrev": "ZM", "name": "Zambia", "zip": "[0-9]{5}"},
- {"abbrev": "ZW", "name": "Zimbabwe"},
-]
diff --git a/edify/library/address/cidr.py b/edify/library/address/cidr.py
index a2b9454..388cdb7 100644
--- a/edify/library/address/cidr.py
+++ b/edify/library/address/cidr.py
@@ -17,15 +17,7 @@ _ipv4_prefix = any_of(
Pattern().optional().any_of_chars("12").digit(),
)
-_hextet = (
- Pattern()
- .between(1, 4)
- .any_of()
- .range("0", "9")
- .range("a", "f")
- .range("A", "F")
- .end()
-)
+_hextet = Pattern().between(1, 4).any_of().range("0", "9").range("a", "f").range("A", "F").end()
_ipv6_prefix = any_of(
Pattern().string("12").any_of().range("0", "8").end(),
@@ -57,12 +49,7 @@ _ipv6_cidr = (
.subexpression(_ipv6_prefix)
)
-cidr = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_ipv4_cidr, _ipv6_cidr))
- .end_of_input()
-)
+cidr = Pattern().start_of_input().subexpression(any_of(_ipv4_cidr, _ipv6_cidr)).end_of_input()
"""Callable :class:`Pattern` for CIDR notation: IPv4 address + ``/0``-``/32``
or IPv6 address + ``/0``-``/128``.
"""
diff --git a/edify/library/address/ip.py b/edify/library/address/ip.py
index e51ea54..d085164 100644
--- a/edify/library/address/ip.py
+++ b/edify/library/address/ip.py
@@ -10,15 +10,7 @@ def _hex_group() -> Pattern:
return Pattern().between(1, 4).subexpression(hex_any)
-_ipv4 = (
- Pattern()
- .subexpression(octet)
- .exactly(3)
- .group()
- .char(".")
- .subexpression(octet)
- .end()
-)
+_ipv4 = Pattern().subexpression(octet).exactly(3).group().char(".").subexpression(octet).end()
def _b1() -> Pattern:
@@ -34,15 +26,7 @@ def _b1() -> Pattern:
def _b2() -> Pattern:
- return (
- Pattern()
- .between(1, 7)
- .group()
- .subexpression(_hex_group())
- .char(":")
- .end()
- .char(":")
- )
+ return Pattern().between(1, 7).group().subexpression(_hex_group()).char(":").end().char(":")
def _b3() -> Pattern:
@@ -95,14 +79,7 @@ def _b9() -> Pattern:
.char(":")
.group()
.any_of()
- .subexpression(
- Pattern()
- .between(1, 7)
- .group()
- .char(":")
- .subexpression(_hex_group())
- .end()
- )
+ .subexpression(Pattern().between(1, 7).group().char(":").subexpression(_hex_group()).end())
.char(":")
.end()
.end()
@@ -205,10 +182,5 @@ _ipv6 = any_of(
_b_hybrid(),
)
-ip = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_ipv4, _ipv6))
- .end_of_input()
-)
+ip = Pattern().start_of_input().subexpression(any_of(_ipv4, _ipv6)).end_of_input()
"""Callable :class:`Pattern` for IPv4 dotted-quad or any IPv6 form."""
diff --git a/edify/library/address/path.py b/edify/library/address/path.py
index 529f225..40f91ca 100644
--- a/edify/library/address/path.py
+++ b/edify/library/address/path.py
@@ -34,7 +34,7 @@ _windows = (
.one_or_more()
.group()
.one_or_more()
- .anything_but_chars("\\/:*?\"<>|\r\n")
+ .anything_but_chars('\\/:*?"<>|\r\n')
.optional()
.char("\\")
.end()
@@ -43,24 +43,19 @@ _unc = (
Pattern()
.string("\\\\")
.one_or_more()
- .anything_but_chars("\\/:*?\"<>|\r\n")
+ .anything_but_chars('\\/:*?"<>|\r\n')
.char("\\")
.one_or_more()
- .anything_but_chars("\\/:*?\"<>|\r\n")
+ .anything_but_chars('\\/:*?"<>|\r\n')
.zero_or_more()
.group()
.char("\\")
.zero_or_more()
- .anything_but_chars("\\/:*?\"<>|\r\n")
+ .anything_but_chars('\\/:*?"<>|\r\n')
.end()
)
-path = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_posix, _windows, _unc))
- .end_of_input()
-)
+path = Pattern().start_of_input().subexpression(any_of(_posix, _windows, _unc)).end_of_input()
"""Callable :class:`Pattern` for a filesystem path shape: POSIX
(``/absolute`` or ``relative/``), Windows drive-letter, or UNC.
"""
diff --git a/edify/library/address/ptr.py b/edify/library/address/ptr.py
index a8020d6..14d70ed 100644
--- a/edify/library/address/ptr.py
+++ b/edify/library/address/ptr.py
@@ -33,12 +33,7 @@ _ipv6_ptr = (
.char(".")
)
-ptr = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_ipv4_ptr, _ipv6_ptr))
- .end_of_input()
-)
+ptr = Pattern().start_of_input().subexpression(any_of(_ipv4_ptr, _ipv6_ptr)).end_of_input()
"""Callable :class:`Pattern` for the reverse-DNS PTR shape: IPv4
``d.c.b.a.in-addr.arpa`` or IPv6 32-nibble ``…ip6.arpa`` form.
"""
diff --git a/edify/library/address/socket.py b/edify/library/address/socket.py
index 020c7dc..2fa29c7 100644
--- a/edify/library/address/socket.py
+++ b/edify/library/address/socket.py
@@ -5,15 +5,7 @@ from __future__ import annotations
from edify import Pattern, any_of
from edify.library._support.atoms import octet
-_ipv4 = (
- Pattern()
- .subexpression(octet)
- .exactly(3)
- .group()
- .char(".")
- .subexpression(octet)
- .end()
-)
+_ipv4 = Pattern().subexpression(octet).exactly(3).group().char(".").subexpression(octet).end()
_ipv6_bracket = (
Pattern()
.char("[")
diff --git a/edify/library/color/color.py b/edify/library/color/color.py
index 7503cc3..3102afd 100644
--- a/edify/library/color/color.py
+++ b/edify/library/color/color.py
@@ -123,10 +123,6 @@ color = any_of(
.whitespace_char()
.char(")")
.end_of_input(),
- Pattern()
- .start_of_input()
- .between(3, 20)
- .letter()
- .end_of_input(),
+ Pattern().start_of_input().between(3, 20).letter().end_of_input(),
)
"""Callable :class:`Pattern` for any common CSS colour shape."""
diff --git a/edify/library/contact/email.py b/edify/library/contact/email.py
index dc98cdd..903691c 100644
--- a/edify/library/contact/email.py
+++ b/edify/library/contact/email.py
@@ -79,12 +79,7 @@ _basic_domain = (
.subexpression(_domain_label())
)
-_basic = (
- Pattern()
- .subexpression(_basic_local)
- .char("@")
- .subexpression(_basic_domain)
-)
+_basic = Pattern().subexpression(_basic_local).char("@").subexpression(_basic_domain)
def _quoted_text() -> Pattern:
@@ -193,19 +188,9 @@ _ip_literal = (
_rfc_local = any_of(_basic_local, _quoted_local)
_rfc_domain = any_of(_basic_domain, _ip_literal)
-_rfc = (
- Pattern()
- .subexpression(_rfc_local)
- .char("@")
- .subexpression(_rfc_domain)
-)
+_rfc = Pattern().subexpression(_rfc_local).char("@").subexpression(_rfc_domain)
-email = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_basic, _rfc))
- .end_of_input()
-)
+email = Pattern().start_of_input().subexpression(any_of(_basic, _rfc)).end_of_input()
"""Callable :class:`Pattern` that accepts either the common permissive email
shape or the full RFC 5322 mailbox shape.
"""
diff --git a/edify/library/contact/phone.py b/edify/library/contact/phone.py
index 2293f5d..6ef4ed8 100644
--- a/edify/library/contact/phone.py
+++ b/edify/library/contact/phone.py
@@ -49,12 +49,7 @@ _international = (
)
_short = Pattern().between(2, 4).digit()
-phone = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_international, _short))
- .end_of_input()
-)
+phone = Pattern().start_of_input().subexpression(any_of(_international, _short)).end_of_input()
"""Callable :class:`Pattern` for phone-number shapes: permissive international
form (optional ``+``, country code, area code, and dash/dot/space separators)
or 2-4 digit short-code fallback.
diff --git a/edify/library/financial/wallet.py b/edify/library/financial/wallet.py
index 6d6b106..e5f05bc 100644
--- a/edify/library/financial/wallet.py
+++ b/edify/library/financial/wallet.py
@@ -19,13 +19,7 @@ _bitcoin_legacy = (
)
_bitcoin_bech32 = (
- Pattern()
- .string("bc1")
- .between(25, 89)
- .any_of()
- .range("a", "z")
- .range("0", "9")
- .end()
+ Pattern().string("bc1").between(25, 89).any_of().range("a", "z").range("0", "9").end()
)
_ethereum = (
diff --git a/edify/library/geo/coordinate.py b/edify/library/geo/coordinate.py
index d69bdd4..ea9450d 100644
--- a/edify/library/geo/coordinate.py
+++ b/edify/library/geo/coordinate.py
@@ -4,16 +4,7 @@ from __future__ import annotations
from edify import Pattern, any_of
-_lat_ninety = (
- Pattern()
- .string("90")
- .optional()
- .group()
- .char(".")
- .one_or_more()
- .char("0")
- .end()
-)
+_lat_ninety = Pattern().string("90").optional().group().char(".").one_or_more().char("0").end()
_lat_below_ninety = (
Pattern()
@@ -28,16 +19,7 @@ _lat_below_ninety = (
.end()
)
-_lon_one_eighty = (
- Pattern()
- .string("180")
- .optional()
- .group()
- .char(".")
- .one_or_more()
- .char("0")
- .end()
-)
+_lon_one_eighty = Pattern().string("180").optional().group().char(".").one_or_more().char("0").end()
_lon_below_one_eighty_integer = any_of(
Pattern().char("1").range("0", "7").digit(),
diff --git a/edify/library/geo/postal.py b/edify/library/geo/postal.py
index be8e869..0f52cb6 100644
--- a/edify/library/geo/postal.py
+++ b/edify/library/geo/postal.py
@@ -2,20 +2,236 @@
from __future__ import annotations
-import re
+from edify import Pattern, any_of
-from edify.library._support.regex import RegexBackedPattern
-from edify.library._support.zip import ZIP_LOCALES
+_digit3 = Pattern().exactly(3).digit()
+_digit4 = Pattern().exactly(4).digit()
+_digit5 = Pattern().exactly(5).digit()
+_digit6 = Pattern().exactly(6).digit()
+_digit7 = Pattern().exactly(7).digit()
-_alternatives: list[str] = []
-for _entry in ZIP_LOCALES:
- _raw = _entry.get("zip")
- if not _raw:
- continue
- _stripped = _raw.strip("^$")
- _alternatives.append(f"(?:{_stripped})")
+_alnum_upper = Pattern().any_of().range("A", "Z").range("0", "9").end()
-postal = RegexBackedPattern(rf"^(?:{'|'.join(_alternatives)})$")
-"""Callable :class:`Pattern` that accepts any known postal/ZIP shape by locale."""
+_prefix_120_or_122 = (
+ Pattern().group().any_of().string("120").string("122").end().end().exactly(2).digit()
+)
+
+_netherlands = (
+ Pattern()
+ .optional()
+ .group()
+ .string("NL-")
+ .end()
+ .exactly(4)
+ .digit()
+ .zero_or_more()
+ .whitespace_char()
+ .exactly(2)
+ .uppercase()
+)
+
+_eircode_prefix = (
+ Pattern()
+ .any_of()
+ .char("A")
+ .range("C", "F")
+ .char("H")
+ .char("K")
+ .char("N")
+ .char("P")
+ .char("R")
+ .char("T")
+ .range("V", "Y")
+ .end()
+ .exactly(2)
+ .digit()
+)
+_eircode = (
+ Pattern()
+ .group()
+ .any_of()
+ .subexpression(_eircode_prefix)
+ .string("D6W")
+ .end()
+ .end()
+ .optional()
+ .any_of_chars(" -")
+ .exactly(4)
+ .any_of()
+ .range("0", "9")
+ .char("A")
+ .range("C", "F")
+ .char("H")
+ .char("K")
+ .char("N")
+ .char("P")
+ .char("R")
+ .char("T")
+ .range("V", "Y")
+ .end()
+)
+
+_uk_gir = Pattern().string("GIR 0AA")
+
+_uk_alpha_upper_lower = Pattern().any_of().range("A", "Z").range("a", "z").end()
+_uk_alpha_no_ilo_upper_lower = (
+ Pattern().any_of().range("A", "H").range("J", "Y").range("a", "h").range("j", "y").end()
+)
+
+_uk_outward = any_of(
+ Pattern().subexpression(_uk_alpha_upper_lower).between(1, 2).digit(),
+ Pattern()
+ .subexpression(_uk_alpha_upper_lower)
+ .subexpression(_uk_alpha_no_ilo_upper_lower)
+ .between(1, 2)
+ .digit(),
+ Pattern().subexpression(_uk_alpha_upper_lower).digit().subexpression(_uk_alpha_upper_lower),
+ Pattern()
+ .subexpression(_uk_alpha_upper_lower)
+ .subexpression(_uk_alpha_no_ilo_upper_lower)
+ .digit()
+ .optional()
+ .subexpression(_uk_alpha_upper_lower),
+)
+
+_uk_full = (
+ Pattern()
+ .subexpression(_uk_outward)
+ .optional()
+ .whitespace_char()
+ .digit()
+ .exactly(2)
+ .subexpression(_uk_alpha_upper_lower)
+)
+
+_uk = any_of(_uk_gir, _uk_full)
-del re, _alternatives, _entry, _raw, _stripped
+_lit_96950 = Pattern().string("96950")
+_prefix_971 = Pattern().string("971").exactly(2).digit()
+_prefix_972 = Pattern().string("972").exactly(2).digit()
+_prefix_973 = Pattern().string("973").exactly(2).digit()
+_prefix_974 = Pattern().string("974").exactly(2).digit()
+_prefix_976 = Pattern().string("976").exactly(2).digit()
+_prefix_980 = Pattern().string("980").exactly(2).digit()
+_prefix_987 = Pattern().string("987").exactly(2).digit()
+_prefix_988 = Pattern().string("988").exactly(2).digit()
+
+_ai_2640 = Pattern().string("AI-2640")
+_bb_plus_5 = Pattern().string("BB").exactly(5).digit()
+_fiqq = Pattern().string("FIQQ 1ZZ")
+_gx11 = Pattern().string("GX11 1AA")
+_lt_5 = Pattern().string("LT-").exactly(5).digit()
+_lv_4 = Pattern().string("LV-").exactly(4).digit()
+_md_4 = Pattern().string("MD").optional().char("-").exactly(4).digit()
+_msr_4 = Pattern().string("MSR ").exactly(4).digit()
+_sthl = Pattern().string("STHL 1ZZ")
+_tkca = Pattern().string("TKCA 1ZZ")
+_vc_4 = Pattern().string("VC").exactly(4).digit()
+_vg_4 = Pattern().string("VG").exactly(4).digit()
+_ws_4 = Pattern().string("WS").exactly(4).digit()
+
+_2_dash_3 = Pattern().exactly(2).digit().char("-").exactly(3).digit()
+_3_sp_2 = Pattern().exactly(3).digit().whitespace_char().exactly(2).digit()
+_3_opt_dash_2 = Pattern().exactly(3).digit().optional().group().char("-").exactly(2).digit().end()
+_3_dash_4 = Pattern().exactly(3).digit().char("-").exactly(4).digit()
+_4_sp_4 = Pattern().exactly(4).digit().whitespace_char().exactly(4).digit()
+_4_opt_dash_letter = Pattern().exactly(4).digit().optional().group().char("-").uppercase().end()
+_4_dash_3 = Pattern().exactly(4).digit().char("-").exactly(3).digit()
+_5_opt_dash_4 = Pattern().exactly(5).digit().optional().group().char("-").exactly(4).digit().end()
+_5_dash_3 = Pattern().exactly(5).digit().char("-").exactly(3).digit()
+_5_or_7 = any_of(_digit5, _digit7)
+
+_ca = (
+ Pattern()
+ .uppercase()
+ .digit()
+ .uppercase()
+ .optional()
+ .whitespace_char()
+ .digit()
+ .uppercase()
+ .digit()
+)
+_upper1_digit3 = Pattern().uppercase().exactly(3).digit()
+_upper1_digit4_upper3 = Pattern().uppercase().exactly(4).digit().exactly(3).uppercase()
+_upper2_sp_digit5 = Pattern().exactly(2).uppercase().whitespace_char().exactly(5).digit()
+_upper2_digit1_dash_digit4 = Pattern().exactly(2).uppercase().digit().char("-").exactly(4).digit()
+_upper2_digit2_sp_digit3 = (
+ Pattern().exactly(2).uppercase().exactly(2).digit().whitespace_char().exactly(3).digit()
+)
+_upper2_digit2 = Pattern().exactly(2).uppercase().exactly(2).digit()
+_upper2_digit4 = Pattern().exactly(2).uppercase().exactly(4).digit()
+_upper3_sp_digit4 = Pattern().exactly(3).uppercase().whitespace_char().exactly(4).digit()
+
+_us_dash_or_space = (
+ Pattern()
+ .exactly(5)
+ .digit()
+ .optional()
+ .group()
+ .any_of_chars("-")
+ .subexpression(Pattern().any_of().char("-").whitespace_char().end())
+ .exactly(4)
+ .digit()
+ .end()
+)
+
+_india = Pattern().assert_not_ahead().char("0").end().exactly(6).digit()
+
+_all_locales = any_of(
+ _prefix_120_or_122,
+ _netherlands,
+ _eircode,
+ _uk,
+ _lit_96950,
+ _prefix_971,
+ _prefix_972,
+ _prefix_973,
+ _prefix_974,
+ _prefix_976,
+ _prefix_980,
+ _prefix_987,
+ _prefix_988,
+ _ai_2640,
+ _bb_plus_5,
+ _fiqq,
+ _gx11,
+ _lt_5,
+ _lv_4,
+ _md_4,
+ _msr_4,
+ _sthl,
+ _tkca,
+ _vc_4,
+ _vg_4,
+ _ws_4,
+ _2_dash_3,
+ _3_sp_2,
+ _digit3,
+ _3_opt_dash_2,
+ _3_dash_4,
+ _4_sp_4,
+ _digit4,
+ _4_opt_dash_letter,
+ _4_dash_3,
+ _digit5,
+ _5_opt_dash_4,
+ _5_dash_3,
+ _5_or_7,
+ _digit6,
+ _digit7,
+ _ca,
+ _upper1_digit3,
+ _upper1_digit4_upper3,
+ _upper2_sp_digit5,
+ _upper2_digit1_dash_digit4,
+ _upper2_digit2_sp_digit3,
+ _upper2_digit2,
+ _upper2_digit4,
+ _upper3_sp_digit4,
+ _us_dash_or_space,
+ _india,
+)
+
+postal = Pattern().start_of_input().subexpression(_all_locales).end_of_input()
+"""Callable :class:`Pattern` that accepts any known postal/ZIP shape by locale."""
diff --git a/edify/library/media/extension.py b/edify/library/media/extension.py
index 2a350bd..f9f5baf 100644
--- a/edify/library/media/extension.py
+++ b/edify/library/media/extension.py
@@ -4,12 +4,5 @@ from __future__ import annotations
from edify import Pattern
-extension = (
- Pattern()
- .start_of_input()
- .char(".")
- .between(1, 10)
- .alphanumeric()
- .end_of_input()
-)
+extension = Pattern().start_of_input().char(".").between(1, 10).alphanumeric().end_of_input()
"""Callable :class:`Pattern` for a file extension: dot + 1-10 alphanumeric."""
diff --git a/edify/library/media/glob.py b/edify/library/media/glob.py
index 4a4cfde..e18f482 100644
--- a/edify/library/media/glob.py
+++ b/edify/library/media/glob.py
@@ -6,15 +6,7 @@ from edify import Pattern
def _not_ctrl() -> Pattern:
- return (
- Pattern()
- .assert_not_ahead()
- .any_of()
- .range("\x00", "\x1f")
- .end()
- .end()
- .any_char()
- )
+ return Pattern().assert_not_ahead().any_of().range("\x00", "\x1f").end().end().any_char()
glob = (
diff --git a/edify/library/medical/medical.py b/edify/library/medical/medical.py
index e702681..97c4d16 100644
--- a/edify/library/medical/medical.py
+++ b/edify/library/medical/medical.py
@@ -7,23 +7,29 @@ from edify import Pattern, any_of
_snomed = Pattern().between(6, 18).digit()
_icd = (
Pattern()
- .any_of().range("A", "T").range("V", "Z").end()
+ .any_of()
+ .range("A", "T")
+ .range("V", "Z")
+ .end()
.digit()
- .any_of().range("A", "Z").range("0", "9").end()
+ .any_of()
+ .range("A", "Z")
+ .range("0", "9")
+ .end()
.optional()
.group()
.char(".")
.between(1, 4)
- .any_of().range("A", "Z").range("0", "9").end()
+ .any_of()
+ .range("A", "Z")
+ .range("0", "9")
+ .end()
.end()
)
_npi = Pattern().exactly(10).digit()
_loinc = Pattern().between(1, 7).digit().char("-").digit()
medical = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_snomed, _icd, _npi, _loinc))
- .end_of_input()
+ Pattern().start_of_input().subexpression(any_of(_snomed, _icd, _npi, _loinc)).end_of_input()
)
"""Callable :class:`Pattern` for medical-coding-system codes."""
diff --git a/edify/library/numeric/integer.py b/edify/library/numeric/integer.py
index 5737758..ef1d13b 100644
--- a/edify/library/numeric/integer.py
+++ b/edify/library/numeric/integer.py
@@ -5,12 +5,6 @@ from __future__ import annotations
from edify import Pattern
integer = (
- Pattern()
- .start_of_input()
- .optional()
- .any_of_chars("+-")
- .one_or_more()
- .digit()
- .end_of_input()
+ Pattern().start_of_input().optional().any_of_chars("+-").one_or_more().digit().end_of_input()
)
"""Callable :class:`Pattern` for a signed decimal integer."""
diff --git a/edify/library/numeric/number.py b/edify/library/numeric/number.py
index 8f316f5..109375e 100644
--- a/edify/library/numeric/number.py
+++ b/edify/library/numeric/number.py
@@ -10,15 +10,7 @@ def _sign() -> Pattern:
_int = Pattern().subexpression(_sign()).one_or_more().digit()
-_dec = (
- Pattern()
- .subexpression(_sign())
- .one_or_more()
- .digit()
- .char(".")
- .one_or_more()
- .digit()
-)
+_dec = Pattern().subexpression(_sign()).one_or_more().digit().char(".").one_or_more().digit()
_ldec = Pattern().subexpression(_sign()).char(".").one_or_more().digit()
_sci_dec = (
Pattern()
diff --git a/edify/library/numeric/ratio.py b/edify/library/numeric/ratio.py
index 49ae1c7..bf797e5 100644
--- a/edify/library/numeric/ratio.py
+++ b/edify/library/numeric/ratio.py
@@ -5,13 +5,6 @@ from __future__ import annotations
from edify import Pattern
ratio = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .digit()
- .char(":")
- .one_or_more()
- .digit()
- .end_of_input()
+ Pattern().start_of_input().one_or_more().digit().char(":").one_or_more().digit().end_of_input()
)
"""Callable :class:`Pattern` for a ratio shape: ``digits:digits``."""
diff --git a/edify/library/publishing/arxiv.py b/edify/library/publishing/arxiv.py
index c65f7cb..27dacd3 100644
--- a/edify/library/publishing/arxiv.py
+++ b/edify/library/publishing/arxiv.py
@@ -39,10 +39,5 @@ _old = (
.end()
)
-arxiv = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_new, _old))
- .end_of_input()
-)
+arxiv = Pattern().start_of_input().subexpression(any_of(_new, _old)).end_of_input()
"""Callable :class:`Pattern` for an arXiv identifier."""
diff --git a/edify/library/publishing/pmc.py b/edify/library/publishing/pmc.py
index f70e8a8..944876e 100644
--- a/edify/library/publishing/pmc.py
+++ b/edify/library/publishing/pmc.py
@@ -4,12 +4,5 @@ from __future__ import annotations
from edify import Pattern
-pmc = (
- Pattern()
- .start_of_input()
- .string("PMC")
- .between(1, 9)
- .digit()
- .end_of_input()
-)
+pmc = Pattern().start_of_input().string("PMC").between(1, 9).digit().end_of_input()
"""Callable :class:`Pattern` for a PubMed Central identifier."""
diff --git a/edify/library/publishing/pmid.py b/edify/library/publishing/pmid.py
index 85134ef..a7e6476 100644
--- a/edify/library/publishing/pmid.py
+++ b/edify/library/publishing/pmid.py
@@ -4,11 +4,5 @@ from __future__ import annotations
from edify import Pattern
-pmid = (
- Pattern()
- .start_of_input()
- .between(1, 8)
- .digit()
- .end_of_input()
-)
+pmid = Pattern().start_of_input().between(1, 8).digit().end_of_input()
"""Callable :class:`Pattern` for a PubMed identifier (1-8 digits)."""
diff --git a/edify/library/software/ref.py b/edify/library/software/ref.py
index ba9d253..c8f55e5 100644
--- a/edify/library/software/ref.py
+++ b/edify/library/software/ref.py
@@ -31,14 +31,7 @@ def _forbidden_incl_slash() -> Pattern:
)
-_sha = (
- Pattern()
- .between(7, 40)
- .any_of()
- .range("a", "f")
- .range("0", "9")
- .end()
-)
+_sha = Pattern().between(7, 40).any_of().range("a", "f").range("0", "9").end()
_refs = (
Pattern()
.string("refs/")
@@ -53,17 +46,7 @@ _refs = (
.one_or_more()
.subexpression(_forbidden())
)
-_bare = (
- Pattern()
- .subexpression(_forbidden_incl_slash())
- .between(0, 127)
- .subexpression(_forbidden())
-)
+_bare = Pattern().subexpression(_forbidden_incl_slash()).between(0, 127).subexpression(_forbidden())
-ref = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_sha, _refs, _bare))
- .end_of_input()
-)
+ref = Pattern().start_of_input().subexpression(any_of(_sha, _refs, _bare)).end_of_input()
"""Callable :class:`Pattern` for a git ref: SHA, ``refs/heads/…``, or bare branch/tag name."""
diff --git a/edify/library/temporal/cron.py b/edify/library/temporal/cron.py
index ada3d89..3c35e59 100644
--- a/edify/library/temporal/cron.py
+++ b/edify/library/temporal/cron.py
@@ -42,12 +42,7 @@ _expr = (
.subexpression(_field)
)
-cron = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_alias, _expr))
- .end_of_input()
-)
+cron = Pattern().start_of_input().subexpression(any_of(_alias, _expr)).end_of_input()
"""Callable :class:`Pattern` for cron-expression shapes: shortcut aliases
(``@daily`` etc.) or 5-/6-field whitespace-separated expressions.
"""
diff --git a/edify/library/temporal/datetime.py b/edify/library/temporal/datetime.py
index 1e659d3..ad54099 100644
--- a/edify/library/temporal/datetime.py
+++ b/edify/library/temporal/datetime.py
@@ -8,39 +8,72 @@ from edify import Pattern, any_of
def _iso_extended() -> Pattern:
return (
Pattern()
- .exactly(4).digit().char("-").exactly(2).digit().char("-").exactly(2).digit()
+ .exactly(4)
+ .digit()
+ .char("-")
+ .exactly(2)
+ .digit()
+ .char("-")
+ .exactly(2)
+ .digit()
.any_of_chars("Tt ")
- .exactly(2).digit().char(":").exactly(2).digit()
- .optional().group().char(":").exactly(2).digit()
- .optional().group().char(".").one_or_more().digit().end()
+ .exactly(2)
+ .digit()
+ .char(":")
+ .exactly(2)
+ .digit()
+ .optional()
+ .group()
+ .char(":")
+ .exactly(2)
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
.end()
- .optional().group().any_of()
+ .end()
+ .optional()
+ .group()
+ .any_of()
.any_of_chars("Zz")
.subexpression(
Pattern().any_of_chars("+-").exactly(2).digit().optional().char(":").exactly(2).digit()
)
- .end().end()
+ .end()
+ .end()
)
def _iso_basic() -> Pattern:
return (
Pattern()
- .exactly(4).digit().exactly(2).digit().exactly(2).digit()
+ .exactly(4)
+ .digit()
+ .exactly(2)
+ .digit()
+ .exactly(2)
+ .digit()
.any_of_chars("Tt")
- .exactly(2).digit().exactly(2).digit().exactly(2).digit()
- .optional().group().any_of()
+ .exactly(2)
+ .digit()
+ .exactly(2)
+ .digit()
+ .exactly(2)
+ .digit()
+ .optional()
+ .group()
+ .any_of()
.any_of_chars("Zz")
.subexpression(Pattern().any_of_chars("+-").exactly(4).digit())
- .end().end()
+ .end()
+ .end()
)
datetime = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_iso_extended(), _iso_basic()))
- .end_of_input()
+ Pattern().start_of_input().subexpression(any_of(_iso_extended(), _iso_basic())).end_of_input()
)
"""Callable :class:`Pattern` for combined date-time shapes: ISO 8601 /
RFC 3339 forms with ``T`` or space separator, optional fractional seconds,
diff --git a/edify/library/temporal/duration.py b/edify/library/temporal/duration.py
index 40129fe..6f7a9ea 100644
--- a/edify/library/temporal/duration.py
+++ b/edify/library/temporal/duration.py
@@ -10,8 +10,14 @@ def _num_with_letter(letter: str) -> Pattern:
Pattern()
.optional()
.group()
- .one_or_more().digit()
- .optional().group().char(".").one_or_more().digit().end()
+ .one_or_more()
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
+ .end()
.char(letter)
.end()
)
@@ -21,13 +27,19 @@ def _duration_body() -> Pattern:
return (
Pattern()
.char("P")
- .assert_ahead().any_char().end()
+ .assert_ahead()
+ .any_char()
+ .end()
.subexpression(_num_with_letter("Y"))
.subexpression(_num_with_letter("M"))
.subexpression(_num_with_letter("W"))
.subexpression(_num_with_letter("D"))
- .optional().group()
- .char("T").assert_ahead().digit().end()
+ .optional()
+ .group()
+ .char("T")
+ .assert_ahead()
+ .digit()
+ .end()
.subexpression(_num_with_letter("H"))
.subexpression(_num_with_letter("M"))
.subexpression(_num_with_letter("S"))
@@ -35,12 +47,7 @@ def _duration_body() -> Pattern:
)
-duration = (
- Pattern()
- .start_of_input()
- .subexpression(_duration_body())
- .end_of_input()
-)
+duration = Pattern().start_of_input().subexpression(_duration_body()).end_of_input()
"""Callable :class:`Pattern` for the ISO 8601 duration shape:
``PnYnMnDTnHnMnS`` with optional fractional components.
"""
diff --git a/edify/library/temporal/epoch.py b/edify/library/temporal/epoch.py
index fec49bb..ffd958e 100644
--- a/edify/library/temporal/epoch.py
+++ b/edify/library/temporal/epoch.py
@@ -4,15 +4,7 @@ from __future__ import annotations
from edify import Pattern
-epoch = (
- Pattern()
- .start_of_input()
- .optional()
- .char("-")
- .between(1, 10)
- .digit()
- .end_of_input()
-)
+epoch = Pattern().start_of_input().optional().char("-").between(1, 10).digit().end_of_input()
"""Callable :class:`Pattern` for a Unix epoch-seconds value: optional sign
followed by 1-10 digits (fits in a 32-bit signed integer).
"""
diff --git a/edify/library/temporal/interval.py b/edify/library/temporal/interval.py
index e1397b6..745ad97 100644
--- a/edify/library/temporal/interval.py
+++ b/edify/library/temporal/interval.py
@@ -8,18 +8,41 @@ from edify import Pattern, any_of
def _iso_extended() -> Pattern:
return (
Pattern()
- .exactly(4).digit().char("-").exactly(2).digit().char("-").exactly(2).digit()
+ .exactly(4)
+ .digit()
+ .char("-")
+ .exactly(2)
+ .digit()
+ .char("-")
+ .exactly(2)
+ .digit()
.any_of_chars("Tt ")
- .exactly(2).digit().char(":").exactly(2).digit()
- .optional().group().char(":").exactly(2).digit()
- .optional().group().char(".").one_or_more().digit().end()
+ .exactly(2)
+ .digit()
+ .char(":")
+ .exactly(2)
+ .digit()
+ .optional()
+ .group()
+ .char(":")
+ .exactly(2)
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
.end()
- .optional().group().any_of()
+ .end()
+ .optional()
+ .group()
+ .any_of()
.any_of_chars("Zz")
.subexpression(
Pattern().any_of_chars("+-").exactly(2).digit().optional().char(":").exactly(2).digit()
)
- .end().end()
+ .end()
+ .end()
)
@@ -28,8 +51,14 @@ def _num_with_letter(letter: str) -> Pattern:
Pattern()
.optional()
.group()
- .one_or_more().digit()
- .optional().group().char(".").one_or_more().digit().end()
+ .one_or_more()
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .one_or_more()
+ .digit()
+ .end()
.char(letter)
.end()
)
@@ -39,13 +68,19 @@ def _duration_body() -> Pattern:
return (
Pattern()
.char("P")
- .assert_ahead().any_char().end()
+ .assert_ahead()
+ .any_char()
+ .end()
.subexpression(_num_with_letter("Y"))
.subexpression(_num_with_letter("M"))
.subexpression(_num_with_letter("W"))
.subexpression(_num_with_letter("D"))
- .optional().group()
- .char("T").assert_ahead().digit().end()
+ .optional()
+ .group()
+ .char("T")
+ .assert_ahead()
+ .digit()
+ .end()
.subexpression(_num_with_letter("H"))
.subexpression(_num_with_letter("M"))
.subexpression(_num_with_letter("S"))
diff --git a/edify/library/temporal/offset.py b/edify/library/temporal/offset.py
index b72bf40..55a0943 100644
--- a/edify/library/temporal/offset.py
+++ b/edify/library/temporal/offset.py
@@ -15,11 +15,7 @@ offset = (
.any_of()
.char("Z")
.subexpression(
- Pattern()
- .any_of_chars("+-")
- .subexpression(_hh)
- .optional().char(":")
- .range("0", "5").digit()
+ Pattern().any_of_chars("+-").subexpression(_hh).optional().char(":").range("0", "5").digit()
)
.end()
.end_of_input()
diff --git a/edify/library/temporal/time.py b/edify/library/temporal/time.py
index 5b2b2f5..65e74bf 100644
--- a/edify/library/temporal/time.py
+++ b/edify/library/temporal/time.py
@@ -10,9 +10,20 @@ _h24 = (
.subexpression(Pattern().char("2").range("0", "3"))
.subexpression(Pattern().optional().any_of_chars("01").digit())
.end()
- .char(":").range("0", "5").digit()
- .optional().group().char(":").range("0", "5").digit()
- .optional().group().char(".").between(1, 6).digit().end()
+ .char(":")
+ .range("0", "5")
+ .digit()
+ .optional()
+ .group()
+ .char(":")
+ .range("0", "5")
+ .digit()
+ .optional()
+ .group()
+ .char(".")
+ .between(1, 6)
+ .digit()
+ .end()
.end()
)
@@ -22,18 +33,22 @@ _h12 = (
.subexpression(Pattern().char("1").range("0", "2"))
.subexpression(Pattern().optional().char("0").range("1", "9"))
.end()
- .char(":").range("0", "5").digit()
- .optional().group().char(":").range("0", "5").digit().end()
- .optional().whitespace_char()
- .any_of_chars("AaPp").any_of_chars("Mm")
+ .char(":")
+ .range("0", "5")
+ .digit()
+ .optional()
+ .group()
+ .char(":")
+ .range("0", "5")
+ .digit()
+ .end()
+ .optional()
+ .whitespace_char()
+ .any_of_chars("AaPp")
+ .any_of_chars("Mm")
)
-time = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_h24, _h12))
- .end_of_input()
-)
+time = Pattern().start_of_input().subexpression(any_of(_h24, _h12)).end_of_input()
"""Callable :class:`Pattern` for clock-time shapes: 24-hour
``HH:MM[:SS[.ffffff]]`` or 12-hour ``H:MM[:SS] AM/PM``.
"""
diff --git a/edify/library/temporal/timestamp.py b/edify/library/temporal/timestamp.py
index 2cf4ed2..ec4fbba 100644
--- a/edify/library/temporal/timestamp.py
+++ b/edify/library/temporal/timestamp.py
@@ -4,15 +4,7 @@ from __future__ import annotations
from edify import Pattern
-timestamp = (
- Pattern()
- .start_of_input()
- .optional()
- .char("-")
- .between(10, 13)
- .digit()
- .end_of_input()
-)
+timestamp = Pattern().start_of_input().optional().char("-").between(10, 13).digit().end_of_input()
"""Callable :class:`Pattern` for a Unix epoch timestamp in seconds or
milliseconds: optional sign followed by 10-13 digits.
"""
diff --git a/edify/library/temporal/timezone.py b/edify/library/temporal/timezone.py
index 2bf5b54..1a6b329 100644
--- a/edify/library/temporal/timezone.py
+++ b/edify/library/temporal/timezone.py
@@ -33,12 +33,7 @@ _short = any_of(
)
_abbrev = Pattern().between(2, 5).uppercase()
-timezone = (
- Pattern()
- .start_of_input()
- .subexpression(any_of(_iana, _short, _abbrev))
- .end_of_input()
-)
+timezone = Pattern().start_of_input().subexpression(any_of(_iana, _short, _abbrev)).end_of_input()
"""Callable :class:`Pattern` for the timezone shape:
IANA region/city (``America/Los_Angeles``), or short abbreviation
(``UTC``, ``PST``, ``EST``, …).
diff --git a/edify/library/text/alpha.py b/edify/library/text/alpha.py
index 538aff8..e31e516 100644
--- a/edify/library/text/alpha.py
+++ b/edify/library/text/alpha.py
@@ -4,11 +4,5 @@ from __future__ import annotations
from edify import Pattern
-alpha = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .letter()
- .end_of_input()
-)
+alpha = Pattern().start_of_input().one_or_more().letter().end_of_input()
"""Callable :class:`Pattern` for a letters-only string."""
diff --git a/edify/library/text/alphanumeric.py b/edify/library/text/alphanumeric.py
index 6d3cadc..899b5ae 100644
--- a/edify/library/text/alphanumeric.py
+++ b/edify/library/text/alphanumeric.py
@@ -4,11 +4,5 @@ from __future__ import annotations
from edify import Pattern
-alphanumeric = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .alphanumeric()
- .end_of_input()
-)
+alphanumeric = Pattern().start_of_input().one_or_more().alphanumeric().end_of_input()
"""Callable :class:`Pattern` for a letters-and-digits-only string."""
diff --git a/edify/library/text/ascii.py b/edify/library/text/ascii.py
index 4412196..42abfde 100644
--- a/edify/library/text/ascii.py
+++ b/edify/library/text/ascii.py
@@ -4,13 +4,7 @@ from __future__ import annotations
from edify import Pattern
-ascii = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .range("\x20", "\x7E")
- .end_of_input()
-)
+ascii = Pattern().start_of_input().one_or_more().range("\x20", "\x7e").end_of_input()
"""Callable :class:`Pattern` for a printable-ASCII-only string
(``0x20``-``0x7E`` — space through tilde).
"""
diff --git a/edify/library/text/base.py b/edify/library/text/base.py
index 959d7a0..77b3680 100644
--- a/edify/library/text/base.py
+++ b/edify/library/text/base.py
@@ -4,24 +4,9 @@ from __future__ import annotations
from edify import Pattern, any_of
-_base16 = (
- Pattern()
- .one_or_more()
- .any_of()
- .range("0", "9")
- .range("A", "F")
- .range("a", "f")
- .end()
-)
+_base16 = Pattern().one_or_more().any_of().range("0", "9").range("A", "F").range("a", "f").end()
_base32 = (
- Pattern()
- .one_or_more()
- .any_of()
- .range("A", "Z")
- .range("2", "7")
- .end()
- .zero_or_more()
- .char("=")
+ Pattern().one_or_more().any_of().range("A", "Z").range("2", "7").end().zero_or_more().char("=")
)
_base58 = (
Pattern()
diff --git a/edify/library/text/emoji.py b/edify/library/text/emoji.py
index ec1caa8..b32b7ba 100644
--- a/edify/library/text/emoji.py
+++ b/edify/library/text/emoji.py
@@ -9,7 +9,7 @@ emoji = (
.start_of_input()
.one_or_more()
.any_of()
- .range("\U0001F300", "\U0001FAFF")
+ .range("\U0001f300", "\U0001faff")
.range("☀", "➿")
.end()
.end_of_input()
diff --git a/edify/library/text/numeric.py b/edify/library/text/numeric.py
index 67b6bc5..36950c3 100644
--- a/edify/library/text/numeric.py
+++ b/edify/library/text/numeric.py
@@ -4,11 +4,5 @@ from __future__ import annotations
from edify import Pattern
-numeric = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .digit()
- .end_of_input()
-)
+numeric = Pattern().start_of_input().one_or_more().digit().end_of_input()
"""Callable :class:`Pattern` for a digits-only string."""
diff --git a/edify/library/text/printable.py b/edify/library/text/printable.py
index 96e2382..af2e238 100644
--- a/edify/library/text/printable.py
+++ b/edify/library/text/printable.py
@@ -10,21 +10,15 @@ def _not_ctrl() -> Pattern:
Pattern()
.assert_not_ahead()
.any_of()
- .range("\x00", "\x1F")
- .char("\x7F")
+ .range("\x00", "\x1f")
+ .char("\x7f")
.end()
.end()
.any_char()
)
-printable = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .subexpression(_not_ctrl())
- .end_of_input()
-)
+printable = Pattern().start_of_input().one_or_more().subexpression(_not_ctrl()).end_of_input()
"""Callable :class:`Pattern` for a printable-character string
(anything except ASCII control codes ``0x00``-``0x1F`` and ``0x7F``).
"""
diff --git a/edify/library/text/script.py b/edify/library/text/script.py
index d5e053d..154df33 100644
--- a/edify/library/text/script.py
+++ b/edify/library/text/script.py
@@ -4,27 +4,10 @@ from __future__ import annotations
from edify import Pattern, any_of
-_latin = (
- Pattern()
- .one_or_more()
- .any_of()
- .range("A", "Z")
- .range("a", "z")
- .range("À", "ɏ")
- .end()
-)
+_latin = Pattern().one_or_more().any_of().range("A", "Z").range("a", "z").range("À", "ɏ").end()
_cyrillic = Pattern().one_or_more().range("Ѐ", "ӿ")
_greek = Pattern().one_or_more().range("Ͱ", "Ͽ")
-_cjk = (
- Pattern()
- .one_or_more()
- .any_of()
- .range("一", "鿿")
- .range("぀", "ゟ")
- .range("゠", "ヿ") # noqa: RUF001
- .range("가", "힯")
- .end()
-)
+_cjk = Pattern().one_or_more().any_of().range("一", "鿿").range("぀", "ヿ").range("가", "힯").end()
_arabic = Pattern().one_or_more().range("؀", "ۿ")
_hebrew = Pattern().one_or_more().range("֐", "׿")
_devanagari = Pattern().one_or_more().range("ऀ", "ॿ")
diff --git a/edify/library/text/unicode.py b/edify/library/text/unicode.py
index a6d95ae..abb6a42 100644
--- a/edify/library/text/unicode.py
+++ b/edify/library/text/unicode.py
@@ -10,19 +10,13 @@ def _not_ctrl() -> Pattern:
Pattern()
.assert_not_ahead()
.any_of()
- .range("\x00", "\x1F")
- .char("\x7F")
+ .range("\x00", "\x1f")
+ .char("\x7f")
.end()
.end()
.any_char()
)
-unicode = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .subexpression(_not_ctrl())
- .end_of_input()
-)
+unicode = Pattern().start_of_input().one_or_more().subexpression(_not_ctrl()).end_of_input()
"""Callable :class:`Pattern` for any Unicode string containing no control codes."""
diff --git a/edify/library/text/word.py b/edify/library/text/word.py
index 7fbaff6..d7a7c47 100644
--- a/edify/library/text/word.py
+++ b/edify/library/text/word.py
@@ -4,13 +4,7 @@ from __future__ import annotations
from edify import Pattern
-word = (
- Pattern()
- .start_of_input()
- .one_or_more()
- .word()
- .end_of_input()
-)
+word = Pattern().start_of_input().one_or_more().word().end_of_input()
"""Callable :class:`Pattern` for a word-character string:
letters, digits, and underscore.
"""
diff --git a/tests/library/media/regex.test.py b/tests/library/media/regex.test.py
new file mode 100644
index 0000000..c1c687c
--- /dev/null
+++ b/tests/library/media/regex.test.py
@@ -0,0 +1,13 @@
+from edify.library import regex
+
+
+def test_valid_regex():
+ assert regex(r"^\d+$")
+
+
+def test_invalid_regex():
+ assert not regex(r"(?P<name>")
+
+
+def test_non_string():
+ assert not regex(42)
diff --git a/tests/library/password.test.py b/tests/library/password.test.py
index ec3b627..45b1672 100644
--- a/tests/library/password.test.py
+++ b/tests/library/password.test.py
@@ -13,3 +13,7 @@ def test_password():
)
is False
)
+
+
+def test_password_rejects_non_string():
+ assert password(42) is False