backrefs 5.7.post1__tar.gz → 5.9__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. {backrefs-5.7.post1 → backrefs-5.9}/LICENSE.md +1 -1
  2. {backrefs-5.7.post1 → backrefs-5.9}/PKG-INFO +8 -10
  3. {backrefs-5.7.post1 → backrefs-5.9}/README.md +4 -6
  4. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/__meta__.py +1 -1
  5. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/_bre_parse.py +1 -1
  6. backrefs-5.9/backrefs/_bregex_typing.py +6 -0
  7. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/bre.py +19 -26
  8. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/changelog.md +13 -3
  9. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/refs.md +3 -3
  10. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/usage.md +1 -1
  11. {backrefs-5.7.post1 → backrefs-5.9}/hatch_build.py +1 -1
  12. {backrefs-5.7.post1 → backrefs-5.9}/mkdocs.yml +1 -3
  13. {backrefs-5.7.post1 → backrefs-5.9}/pyproject.toml +5 -3
  14. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bre.py +6 -6
  15. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bregex.py +10 -6
  16. backrefs-5.9/tools/unicodedata/16.0.0.zip +0 -0
  17. {backrefs-5.7.post1 → backrefs-5.9}/tools/unipropgen.py +33 -34
  18. backrefs-5.7.post1/backrefs/_bregex_typing.py +0 -13
  19. backrefs-5.7.post1/tools/unicodedata/11.0.0.zip +0 -0
  20. backrefs-5.7.post1/tools/unicodedata/12.1.0.zip +0 -0
  21. {backrefs-5.7.post1 → backrefs-5.9}/.coveragerc +0 -0
  22. {backrefs-5.7.post1 → backrefs-5.9}/.gitignore +0 -0
  23. {backrefs-5.7.post1 → backrefs-5.9}/.pyspelling.yml +0 -0
  24. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/__init__.py +0 -0
  25. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/_bregex_parse.py +0 -0
  26. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/bregex.py +0 -0
  27. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/py.typed +0 -0
  28. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/uniprops/__init__.py +0 -0
  29. {backrefs-5.7.post1 → backrefs-5.9}/backrefs/util.py +0 -0
  30. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/.snippets/links.md +0 -0
  31. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/contributing.md +0 -0
  32. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/license.md +0 -0
  33. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/security.md +0 -0
  34. {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/index.md +0 -0
  35. {backrefs-5.7.post1 → backrefs-5.9}/docs/theme/announce.html +0 -0
  36. {backrefs-5.7.post1 → backrefs-5.9}/requirements/docs.txt +0 -0
  37. {backrefs-5.7.post1 → backrefs-5.9}/requirements/lint.txt +0 -0
  38. {backrefs-5.7.post1 → backrefs-5.9}/requirements/test.txt +0 -0
  39. {backrefs-5.7.post1 → backrefs-5.9}/tests/__init__.py +0 -0
  40. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_age.py +0 -0
  41. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bidiclass.py +0 -0
  42. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bidipairedbrackettype.py +0 -0
  43. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_binary.py +0 -0
  44. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_block.py +0 -0
  45. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_canonicalcombiningclass.py +0 -0
  46. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_decompositiontype.py +0 -0
  47. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_eastasianwidth.py +0 -0
  48. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_generalcategory.py +0 -0
  49. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_graphemeclusterbreak.py +0 -0
  50. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_hangulsyllabletype.py +0 -0
  51. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_indicpositionalcategory.py +0 -0
  52. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_indicsylabiccategory.py +0 -0
  53. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_joininggroup.py +0 -0
  54. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_joiningtype.py +0 -0
  55. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_linebreak.py +0 -0
  56. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_numerictype.py +0 -0
  57. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_numericvalue.py +0 -0
  58. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_quickcheck.py +0 -0
  59. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_script.py +0 -0
  60. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_scriptextensions.py +0 -0
  61. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_sentencebreak.py +0 -0
  62. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_uniprops.py +0 -0
  63. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_versions.py +0 -0
  64. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_verticalorientation.py +0 -0
  65. {backrefs-5.7.post1 → backrefs-5.9}/tests/test_wordbreak.py +0 -0
  66. {backrefs-5.7.post1 → backrefs-5.9}/tools/__init__.py +0 -0
  67. {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/13.0.0.zip +0 -0
  68. {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/14.0.0.zip +0 -0
  69. {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/15.0.0.zip +0 -0
  70. {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/15.1.0.zip +0 -0
  71. {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/LICENSE +0 -0
  72. {backrefs-5.7.post1 → backrefs-5.9}/tools/unidatadownload.py +0 -0
@@ -1,6 +1,6 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2015 - 2023 Isaac Muse
3
+ Copyright (c) 2015 - 2025 Isaac Muse
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining a copy
6
6
  of this software and associated documentation files (the "Software"), to deal
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.3
1
+ Metadata-Version: 2.4
2
2
  Name: backrefs
3
- Version: 5.7.post1
3
+ Version: 5.9
4
4
  Summary: A wrapper around re and regex that adds additional back references.
5
5
  Project-URL: Homepage, https://github.com/facelessuser/backrefs
6
6
  Author-email: Isaac Muse <Isaac.Muse@gmail.com>
@@ -13,27 +13,26 @@ Classifier: Intended Audience :: Developers
13
13
  Classifier: License :: OSI Approved :: MIT License
14
14
  Classifier: Operating System :: OS Independent
15
15
  Classifier: Programming Language :: Python :: 3
16
- Classifier: Programming Language :: Python :: 3.8
17
16
  Classifier: Programming Language :: Python :: 3.9
18
17
  Classifier: Programming Language :: Python :: 3.10
19
18
  Classifier: Programming Language :: Python :: 3.11
20
19
  Classifier: Programming Language :: Python :: 3.12
21
20
  Classifier: Programming Language :: Python :: 3.13
21
+ Classifier: Programming Language :: Python :: 3.14
22
22
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
23
23
  Classifier: Typing :: Typed
24
- Requires-Python: >=3.8
24
+ Requires-Python: >=3.9
25
25
  Provides-Extra: extras
26
26
  Requires-Dist: regex; extra == 'extras'
27
27
  Description-Content-Type: text/markdown
28
28
 
29
29
  [![Donate via PayPal][donate-image]][donate-link]
30
- [![Discord][discord-image]][discord-link]
31
30
  [![Build][github-ci-image]][github-ci-link]
32
31
  [![Coverage Status][codecov-image]][codecov-link]
33
32
  [![PyPI Version][pypi-image]][pypi-link]
34
33
  [![PyPI Downloads][pypi-down]][pypi-link]
35
34
  [![PyPI - Python Version][python-image]][pypi-link]
36
- ![License][license-image-mit]
35
+ [![License][license-image-mit]][license-link]
37
36
 
38
37
  # Backrefs
39
38
 
@@ -43,7 +42,7 @@ Python's Re and/or Regex. The supported back references actually vary depending
43
42
  used as the engine may already have support for some.
44
43
 
45
44
  ```python
46
- from backrefs import bre
45
+ >>> from backrefs import bre
47
46
  >>> pattern = bre.compile(r'(\p{Letter}+)')
48
47
  >>> pattern.sub(r'\C\1\E', 'sometext')
49
48
  'SOMETEXT'
@@ -57,10 +56,8 @@ https://facelessuser.github.io/backrefs/
57
56
 
58
57
  MIT
59
58
 
60
- [github-ci-image]: https://github.com/facelessuser/backrefs/workflows/build/badge.svg?branch=master&event=push
59
+ [github-ci-image]: https://github.com/facelessuser/backrefs/workflows/build/badge.svg
61
60
  [github-ci-link]: https://github.com/facelessuser/backrefs/actions?query=workflow%3Abuild+branch%3Amaster
62
- [discord-image]: https://img.shields.io/discord/678289859768745989?logo=discord&logoColor=aaaaaa&color=mediumpurple&labelColor=333333
63
- [discord-link]:https://discord.gg/TWs8Tgr
64
61
  [codecov-image]: https://img.shields.io/codecov/c/github/facelessuser/backrefs/master.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333
65
62
  [codecov-link]: https://codecov.io/github/facelessuser/backrefs
66
63
  [pypi-image]: https://img.shields.io/pypi/v/backrefs.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333
@@ -68,6 +65,7 @@ MIT
68
65
  [pypi-link]: https://pypi.python.org/pypi/backrefs
69
66
  [python-image]: https://img.shields.io/pypi/pyversions/backrefs?logo=python&logoColor=aaaaaa&labelColor=333333
70
67
  [license-image-mit]: https://img.shields.io/badge/license-MIT-blue.svg?labelColor=333333
68
+ [license-link]: https://github.com/facelessuser/backrefs/blob/main/LICENSE.md
71
69
  [donate-image]: https://img.shields.io/badge/Donate-PayPal-3fabd1?logo=paypal
72
70
  [donate-link]: https://www.paypal.me/facelessuser
73
71
 
@@ -1,11 +1,10 @@
1
1
  [![Donate via PayPal][donate-image]][donate-link]
2
- [![Discord][discord-image]][discord-link]
3
2
  [![Build][github-ci-image]][github-ci-link]
4
3
  [![Coverage Status][codecov-image]][codecov-link]
5
4
  [![PyPI Version][pypi-image]][pypi-link]
6
5
  [![PyPI Downloads][pypi-down]][pypi-link]
7
6
  [![PyPI - Python Version][python-image]][pypi-link]
8
- ![License][license-image-mit]
7
+ [![License][license-image-mit]][license-link]
9
8
 
10
9
  # Backrefs
11
10
 
@@ -15,7 +14,7 @@ Python's Re and/or Regex. The supported back references actually vary depending
15
14
  used as the engine may already have support for some.
16
15
 
17
16
  ```python
18
- from backrefs import bre
17
+ >>> from backrefs import bre
19
18
  >>> pattern = bre.compile(r'(\p{Letter}+)')
20
19
  >>> pattern.sub(r'\C\1\E', 'sometext')
21
20
  'SOMETEXT'
@@ -29,10 +28,8 @@ https://facelessuser.github.io/backrefs/
29
28
 
30
29
  MIT
31
30
 
32
- [github-ci-image]: https://github.com/facelessuser/backrefs/workflows/build/badge.svg?branch=master&event=push
31
+ [github-ci-image]: https://github.com/facelessuser/backrefs/workflows/build/badge.svg
33
32
  [github-ci-link]: https://github.com/facelessuser/backrefs/actions?query=workflow%3Abuild+branch%3Amaster
34
- [discord-image]: https://img.shields.io/discord/678289859768745989?logo=discord&logoColor=aaaaaa&color=mediumpurple&labelColor=333333
35
- [discord-link]:https://discord.gg/TWs8Tgr
36
33
  [codecov-image]: https://img.shields.io/codecov/c/github/facelessuser/backrefs/master.svg?logo=codecov&logoColor=aaaaaa&labelColor=333333
37
34
  [codecov-link]: https://codecov.io/github/facelessuser/backrefs
38
35
  [pypi-image]: https://img.shields.io/pypi/v/backrefs.svg?logo=pypi&logoColor=aaaaaa&labelColor=333333
@@ -40,6 +37,7 @@ MIT
40
37
  [pypi-link]: https://pypi.python.org/pypi/backrefs
41
38
  [python-image]: https://img.shields.io/pypi/pyversions/backrefs?logo=python&logoColor=aaaaaa&labelColor=333333
42
39
  [license-image-mit]: https://img.shields.io/badge/license-MIT-blue.svg?labelColor=333333
40
+ [license-link]: https://github.com/facelessuser/backrefs/blob/main/LICENSE.md
43
41
  [donate-image]: https://img.shields.io/badge/Donate-PayPal-3fabd1?logo=paypal
44
42
  [donate-link]: https://www.paypal.me/facelessuser
45
43
 
@@ -193,5 +193,5 @@ def parse_version(ver: str) -> Version:
193
193
  return Version(major, minor, micro, release, pre, post, dev)
194
194
 
195
195
 
196
- __version_info__ = Version(5, 7, 0, "final", post=1)
196
+ __version_info__ = Version(5, 9, 0, "final")
197
197
  __version__ = __version_info__._get_canonical()
@@ -204,7 +204,7 @@ class _SearchParser(Generic[AnyStr]):
204
204
  c = next(i)
205
205
  if c.upper() in _ASCII_LETTERS:
206
206
  prop.append(c)
207
- elif not brackets and c != '{' or brackets and c != ':':
207
+ elif (not brackets and c != '{') or (brackets and c != ':'):
208
208
  raise SyntaxError(f"Unicode property missing '{{' at {i.index - 1}!")
209
209
  else:
210
210
  c = next(i)
@@ -0,0 +1,6 @@
1
+ """Typing objects for the Regex library."""
2
+ import regex # type: ignore[import]
3
+ from typing import _alias # type: ignore[attr-defined]
4
+
5
+ Pattern = _alias(type(regex.compile('')), 1)
6
+ Match = _alias(type(regex.compile('').match('')), 1)
@@ -481,24 +481,22 @@ def match(
481
481
  pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
482
482
  string: AnyStr,
483
483
  flags: int | _re.RegexFlag = 0,
484
- *args: Any,
485
484
  **kwargs: Any
486
485
  ) -> Match[AnyStr] | None:
487
486
  """Apply `match` after applying backrefs."""
488
487
 
489
- return _re.match(_apply_search_backrefs(pattern, flags), string, flags, *args, **kwargs)
488
+ return _re.match(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
490
489
 
491
490
 
492
491
  def fullmatch(
493
492
  pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
494
493
  string: AnyStr,
495
494
  flags: int | _re.RegexFlag = 0,
496
- *args: Any,
497
495
  **kwargs: Any
498
496
  ) -> Match[AnyStr] | None:
499
497
  """Apply `fullmatch` after applying backrefs."""
500
498
 
501
- return _re.fullmatch(_apply_search_backrefs(pattern, flags), string, flags, *args, **kwargs)
499
+ return _re.fullmatch(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
502
500
 
503
501
 
504
502
  def split(
@@ -506,36 +504,39 @@ def split(
506
504
  string: AnyStr,
507
505
  maxsplit: int = 0,
508
506
  flags: int | _re.RegexFlag = 0,
509
- *args: Any,
510
507
  **kwargs: Any
511
508
  ) -> list[AnyStr]:
512
509
  """Apply `split` after applying backrefs."""
513
510
 
514
- return _re.split(_apply_search_backrefs(pattern, flags), string, maxsplit, flags, *args, **kwargs)
511
+ return _re.split(
512
+ _apply_search_backrefs(pattern, flags),
513
+ string,
514
+ maxsplit=maxsplit,
515
+ flags=flags,
516
+ **kwargs
517
+ )
515
518
 
516
519
 
517
520
  def findall(
518
521
  pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
519
522
  string: AnyStr,
520
523
  flags: int | _re.RegexFlag = 0,
521
- *args: Any,
522
524
  **kwargs: Any
523
525
  ) -> list[AnyStr] | list[tuple[AnyStr, ...]]:
524
526
  """Apply `findall` after applying backrefs."""
525
527
 
526
- return _re.findall(_apply_search_backrefs(pattern, flags), string, flags, *args, **kwargs)
528
+ return _re.findall(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
527
529
 
528
530
 
529
531
  def finditer(
530
532
  pattern: AnyStr | Pattern[AnyStr] | Bre[AnyStr],
531
533
  string: AnyStr,
532
534
  flags: int | _re.RegexFlag = 0,
533
- *args: Any,
534
535
  **kwargs: Any
535
536
  ) -> Iterator[Match[AnyStr]]:
536
537
  """Apply `finditer` after applying backrefs."""
537
538
 
538
- return _re.finditer(_apply_search_backrefs(pattern, flags), string, flags, *args, **kwargs)
539
+ return _re.finditer(_apply_search_backrefs(pattern, flags), string, flags=flags, **kwargs)
539
540
 
540
541
 
541
542
  def sub(
@@ -544,7 +545,6 @@ def sub(
544
545
  string: AnyStr,
545
546
  count: int = 0,
546
547
  flags: int | _re.RegexFlag = 0,
547
- *args: Any,
548
548
  **kwargs: Any
549
549
  ) -> AnyStr:
550
550
  """Apply `sub` after applying backrefs."""
@@ -559,9 +559,8 @@ def sub(
559
559
  pattern,
560
560
  (compile_replace(pattern, repl) if is_replace or is_string else repl),
561
561
  string,
562
- count,
563
- 0,
564
- *args,
562
+ count=count,
563
+ flags=0,
565
564
  **kwargs
566
565
  )
567
566
 
@@ -572,7 +571,6 @@ def subf(
572
571
  string: AnyStr,
573
572
  count: int = 0,
574
573
  flags: int | _re.RegexFlag = 0,
575
- *args: Any,
576
574
  **kwargs: Any
577
575
  ) -> AnyStr:
578
576
  """Apply `sub` with format style replace."""
@@ -588,9 +586,8 @@ def subf(
588
586
  pattern,
589
587
  (compile_replace(pattern, repl, flags=rflags) if is_replace or is_string else repl),
590
588
  string,
591
- count,
592
- 0,
593
- *args,
589
+ count=count,
590
+ flags=0,
594
591
  **kwargs
595
592
  )
596
593
 
@@ -601,7 +598,6 @@ def subn(
601
598
  string: AnyStr,
602
599
  count: int = 0,
603
600
  flags: int | _re.RegexFlag = 0,
604
- *args: Any,
605
601
  **kwargs: Any
606
602
  ) -> tuple[AnyStr, int]:
607
603
  """Apply `subn` with format style replace."""
@@ -616,9 +612,8 @@ def subn(
616
612
  pattern,
617
613
  (compile_replace(pattern, repl) if is_replace or is_string else repl),
618
614
  string,
619
- count,
620
- 0,
621
- *args,
615
+ count=count,
616
+ flags=0,
622
617
  **kwargs
623
618
  )
624
619
 
@@ -629,7 +624,6 @@ def subfn(
629
624
  string: AnyStr,
630
625
  count: int = 0,
631
626
  flags: int | _re.RegexFlag = 0,
632
- *args: Any,
633
627
  **kwargs: Any
634
628
  ) -> tuple[AnyStr, int]:
635
629
  """Apply `subn` after applying backrefs."""
@@ -645,9 +639,8 @@ def subfn(
645
639
  pattern,
646
640
  (compile_replace(pattern, repl, flags=rflags) if is_replace or is_string else repl),
647
641
  string,
648
- count,
649
- 0,
650
- *args,
642
+ count=count,
643
+ flags=0,
651
644
  **kwargs
652
645
  )
653
646
 
@@ -1,5 +1,15 @@
1
1
  # Changelog
2
2
 
3
+ ## 5.9
4
+
5
+ - **NEW**: Add support for Python 3.14.
6
+ - **ENHANCE**: Switch to deploying with PyPI's "Trusted Publisher".
7
+
8
+ ## 5.8
9
+
10
+ - **NEW**: Drop Python 3.8.
11
+ - **FIX**: Deprecation warnings.
12
+
3
13
  ## 5.7
4
14
 
5
15
  - **NEW**: Add support for Python 3.13 beta.
@@ -46,9 +56,9 @@
46
56
  - **FIX**: Match Re and Regex handling when doing a non-format replacement that references a group that is present in
47
57
  the search pattern but has no actual captures. Such a case should not fail, but simply return an empty string for
48
58
  the group.
49
- - **FIX**: Format replacements that that have groups with no captures will yield an empty string as the only capture
50
- as long as the user does not try to index into any captures as there are no actual captures. This behavior was a bug
51
- in Regex that we duplicated and should now be fixed in the latest Regex (mrabarnett/mrab-regex#439) as well as in
59
+ - **FIX**: Format replacements that have groups with no captures will yield an empty string as the only capture as
60
+ long as the user does not try to index into any captures as there are no actual captures. This behavior was a bug in
61
+ Regex that we duplicated and should now be fixed in the latest Regex (mrabarnett/mrab-regex#439) as well as in
52
62
  Backrefs.
53
63
 
54
64
  ## 5.1
@@ -23,7 +23,7 @@ Back\ References | Description
23
23
  `\P{UnicodeProperty}` | Inverse Unicode property character class. Can be used in character classes `[]`. See [Unicode Properties](#unicode-properties) for more info.
24
24
  `\PX` | Inverse Unicode property character class where `X` is the uppercase letter that represents the General Category property. For instance, `\PL` would be equivalent to `\P{L}` or `\P{Letter}`.
25
25
  `[[:alnum:]]` | Though not really a back reference, support for POSIX style character classes is available. See [POSIX Style Properties](#posix-style-properties) for more info.
26
- `\N{UnicodeName}` | Named characters are are normally ignored in Re, but Backrefs adds support for them.
26
+ `\N{UnicodeName}` | Named characters are normally ignored in Re, but Backrefs adds support for them.
27
27
  `\m` | Start word boundary. Translates to `\b(?=\w)`.
28
28
  `\M` | End word boundary. Translates to `\b(?<=\w)`.
29
29
  `\h` | **Deprecated: Use `\p{Horiz_Space}` instead.** Horizontal whitespace. Equivalent to using `[[:blank:]]` or `[\t\p{Zs}]`.
@@ -73,7 +73,7 @@ Back\ References | Description
73
73
  `\U` | Wide Unicode character `\U00000057`. Re doesn't translate this notation in raw strings (`#!py3 r"..."`), and Regex doesn't in format templates in raw strings (`#!py3 r"{} {}"`). This adds support for them.
74
74
  `\u` | Narrow Unicode character `\u0057`. Re doesn't translate this notation in raw strings (`#!py3 r"..."`), and Regex doesn't in format templates in raw strings (`#!py3 r"{} {}"`). This adds support for them.
75
75
  `\x` | Byte character `\x57`. Re doesn't translate this notation in raw strings (`#!py3 r"..."`), and Regex doesn't in format templates in raw strings (`#!py3 r"{} {}"`). This adds support for them.
76
- `\N{UnicodeName}` | Named characters are are normally ignored in Re, but Backrefs adds support for them.
76
+ `\N{UnicodeName}` | Named characters are normally ignored in Re, but Backrefs adds support for them.
77
77
 
78
78
  /// tip
79
79
  Complex configurations of casing should work fine.
@@ -199,7 +199,7 @@ Block properties have a similar short form as Script and Binary properties. For
199
199
  a block. If we wanted to match characters in the `Basic_Latin` block, we could use the syntax `\p{InBasic_Latin}`. This
200
200
  would be the same as `\p{Block: Basic_Latin}` or `\p{Basic_Latin}`.
201
201
 
202
- /// warn | Short Name Conflicts
202
+ /// warning | Short Name Conflicts
203
203
  When it comes to short names, each new Unicode version, there is a risk that new properties could cause conflicts
204
204
  with existing names and/or aliases. Currently, most of the conflicts involve the Block properties. To reduce
205
205
  friction, they are evaluated last.
@@ -135,7 +135,7 @@ why.
135
135
  1. Regex's original implementation is very much like it's non-format style replacement accept for two differences: you
136
136
  can access individual captures and you cannot use Python string back references such as specifying Unicode via
137
137
  `\u<code>`, etc. In Backrefs, we've enhanced the syntax -- for both Re and Regex -- to allow back references to work
138
- along side brace replacements. This means you can use string back references and and built-in Backrefs features like
138
+ along side brace replacements. This means you can use string back references and built-in Backrefs features like
139
139
  `\C...\E` or `\L...\E`.
140
140
 
141
141
  ```pycon3
@@ -74,12 +74,12 @@ class CustomMetadataHook(MetadataHookInterface):
74
74
  'License :: OSI Approved :: MIT License',
75
75
  'Operating System :: OS Independent',
76
76
  'Programming Language :: Python :: 3',
77
- 'Programming Language :: Python :: 3.8',
78
77
  'Programming Language :: Python :: 3.9',
79
78
  'Programming Language :: Python :: 3.10',
80
79
  'Programming Language :: Python :: 3.11',
81
80
  'Programming Language :: Python :: 3.12',
82
81
  'Programming Language :: Python :: 3.13',
82
+ 'Programming Language :: Python :: 3.14',
83
83
  'Topic :: Software Development :: Libraries :: Python Modules',
84
84
  'Typing :: Typed'
85
85
  ]
@@ -4,7 +4,7 @@ repo_url: https://github.com/facelessuser/backrefs
4
4
  edit_uri: tree/master/docs/src/markdown
5
5
  site_description: A library to add additional back references to regular expressions.
6
6
  copyright: |
7
- Copyright &copy; 2015 - 2023 <a href="https://github.com/facelessuser" target="_blank" rel="noopener">Isaac Muse</a>
7
+ Copyright &copy; 2015 - 2025 <a href="https://github.com/facelessuser" target="_blank" rel="noopener">Isaac Muse</a>
8
8
 
9
9
  docs_dir: docs/src/markdown
10
10
  theme:
@@ -152,8 +152,6 @@ extra:
152
152
  social:
153
153
  - icon: fontawesome/brands/github
154
154
  link: https://github.com/facelessuser
155
- - icon: fontawesome/brands/discord
156
- link: https://discord.gg/TWs8Tgr
157
155
 
158
156
  plugins:
159
157
  - search
@@ -9,7 +9,7 @@ name = "backrefs"
9
9
  description = "A wrapper around re and regex that adds additional back references."
10
10
  readme = "README.md"
11
11
  license = "MIT"
12
- requires-python = ">=3.8"
12
+ requires-python = ">=3.9"
13
13
  authors = [
14
14
  { name = "Isaac Muse", email = "Isaac.Muse@gmail.com" },
15
15
  ]
@@ -125,6 +125,8 @@ lint.ignore = [
125
125
  "RUF012",
126
126
  "RUF005",
127
127
  "PGH004",
128
+ "RUF022",
129
+ "RUF023",
128
130
  "RUF100"
129
131
  ]
130
132
 
@@ -133,7 +135,7 @@ legacy_tox_ini = """
133
135
  [tox]
134
136
  isolated_build = true
135
137
  envlist =
136
- py38,py39,py310,py311,py312,
138
+ py39,py310,py311,py312,py313,py314,
137
139
  lint
138
140
 
139
141
  [testenv]
@@ -155,7 +157,7 @@ passenv = *
155
157
  deps=
156
158
  -r requirements/docs.txt
157
159
  commands=
158
- {envpython} -m mkdocs build --clean --verbose --strict
160
+ {envbindir}/mkdocs build --clean --verbose --strict
159
161
  {envbindir}/pyspelling
160
162
 
161
163
  [testenv:lint]
@@ -947,17 +947,17 @@ class TestReplaceTemplate(unittest.TestCase):
947
947
  def test_format_conversions(self):
948
948
  """Test string format conversion paths."""
949
949
 
950
- self.assertTrue(bre.subf('test', r'{0.index}', 'test').startswith('<built-in method'))
950
+ self.assertTrue(bre.subf('test', r'{0.index}', 'test').startswith(('<built-in method', '<bound method')))
951
951
  self.assertEqual(bre.subf('test', r'{0.__class__.__name__}', 'test'), 'str')
952
- self.assertTrue(bre.subf('test', r'{0.index!s}', 'test').startswith('<built-in method'))
952
+ self.assertTrue(bre.subf('test', r'{0.index!s}', 'test').startswith(('<built-in method', '<bound method')))
953
953
  self.assertEqual(bre.subf('test', r'{0.__class__.__name__!s}', 'test'), 'str')
954
- self.assertTrue(bre.subf('test', r'{0.index!a}', 'test').startswith('<built-in method'))
954
+ self.assertTrue(bre.subf('test', r'{0.index!a}', 'test').startswith(('<built-in method', '<bound method')))
955
955
 
956
- self.assertTrue(bre.subf(b'test', br'{0.index}', b'test').startswith(b'<built-in method'))
956
+ self.assertTrue(bre.subf(b'test', br'{0.index}', b'test').startswith((b'<built-in method', b'<bound method')))
957
957
  self.assertEqual(bre.subf(b'test', br'{0.__class__.__name__}', b'test'), b'bytes')
958
- self.assertTrue(bre.subf(b'test', br'{0.index!s}', b'test').startswith(b'<built-in method'))
958
+ self.assertTrue(bre.subf(b'test', br'{0.index!s}', b'test').startswith((b'<built-in method', b'<bound method')))
959
959
  self.assertEqual(bre.subf(b'test', br'{0.__class__.__name__!s}', b'test'), b'bytes')
960
- self.assertTrue(bre.subf('test', r'{0.index!a}', 'test').startswith('<built-in method'))
960
+ self.assertTrue(bre.subf('test', r'{0.index!a}', 'test').startswith(('<built-in method', '<bound method')))
961
961
 
962
962
  def test_incompatible_strings(self):
963
963
  """Test incompatible string types."""
@@ -693,17 +693,21 @@ class TestReplaceTemplate(unittest.TestCase):
693
693
  def test_format_conversions(self):
694
694
  """Test string format conversion paths."""
695
695
 
696
- self.assertTrue(bregex.subf('test', r'{0.index}', 'test').startswith('<built-in method'))
696
+ self.assertTrue(bregex.subf('test', r'{0.index}', 'test').startswith(('<built-in method', '<bound method')))
697
697
  self.assertEqual(bregex.subf('test', r'{0.__class__.__name__}', 'test'), 'str')
698
- self.assertTrue(bregex.subf('test', r'{0.index!s}', 'test').startswith('<built-in method'))
698
+ self.assertTrue(bregex.subf('test', r'{0.index!s}', 'test').startswith(('<built-in method', '<bound method')))
699
699
  self.assertEqual(bregex.subf('test', r'{0.__class__.__name__!s}', 'test'), 'str')
700
- self.assertTrue(bregex.subf('test', r'{0.index!a}', 'test').startswith('<built-in method'))
700
+ self.assertTrue(bregex.subf('test', r'{0.index!a}', 'test').startswith(('<built-in method', '<bound method')))
701
701
 
702
- self.assertTrue(bregex.subf(b'test', br'{0.index}', b'test').startswith(b'<built-in method'))
702
+ self.assertTrue(bregex.subf(
703
+ b'test', br'{0.index}', b'test').startswith((b'<built-in method', b'<bound method'))
704
+ )
703
705
  self.assertEqual(bregex.subf(b'test', br'{0.__class__.__name__}', b'test'), b'bytes')
704
- self.assertTrue(bregex.subf(b'test', br'{0.index!s}', b'test').startswith(b'<built-in method'))
706
+ self.assertTrue(
707
+ bregex.subf(b'test', br'{0.index!s}', b'test').startswith((b'<built-in method', b'<bound method'))
708
+ )
705
709
  self.assertEqual(bregex.subf(b'test', br'{0.__class__.__name__!s}', b'test'), b'bytes')
706
- self.assertTrue(bregex.subf('test', r'{0.index!a}', 'test').startswith('<built-in method'))
710
+ self.assertTrue(bregex.subf('test', r'{0.index!a}', 'test').startswith(('<built-in method', '<bound method')))
707
711
 
708
712
  def test_incompatible_strings(self):
709
713
  """Test incompatible string types."""
@@ -1,7 +1,6 @@
1
1
  """Generate a Unicode prop table for Python builds."""
2
2
  import sys
3
3
  import unicodedata
4
- import codecs
5
4
  import os
6
5
  import re
7
6
 
@@ -201,7 +200,7 @@ def discover_categories():
201
200
 
202
201
  # NF Quick Check categories
203
202
  file_name = os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedNormalizationProps.txt')
204
- with codecs.open(file_name, 'r', 'utf-8') as uf:
203
+ with open(file_name, 'r', encoding='utf-8') as uf:
205
204
  for line in uf:
206
205
  if not line.startswith('#'):
207
206
  data = line.split('#')[0].split(';')
@@ -227,7 +226,7 @@ def discover_categories():
227
226
  binary_props.append(('emoji-data.txt', None))
228
227
 
229
228
  for filename, include in binary_props:
230
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, filename), 'r', 'utf-8') as uf:
229
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, filename), 'r', encoding='utf-8') as uf:
231
230
  for line in uf:
232
231
  if not line.startswith('#'):
233
232
  data = line.split('#')[0].split(';')
@@ -245,7 +244,7 @@ def discover_categories():
245
244
  def gen_blocks(output, ascii_props=False, append=False, prefix="", aliases=None):
246
245
  """Generate Unicode blocks."""
247
246
 
248
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
247
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
249
248
  if not append:
250
249
  f.write(HEADER.format(UNIVERSION, TYPING))
251
250
  f.write('%s_blocks: dict[str, str] = {' % prefix)
@@ -257,7 +256,7 @@ def gen_blocks(output, ascii_props=False, append=False, prefix="", aliases=None)
257
256
  max_range = MAXUNICODE
258
257
  formatter = uniformat
259
258
 
260
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'Blocks.txt'), 'r', 'utf-8') as uf:
259
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'Blocks.txt'), 'r', encoding='utf-8') as uf:
261
260
  for line in uf:
262
261
  if not line.startswith('#'):
263
262
  data = line.split(';')
@@ -321,7 +320,7 @@ def gen_ccc(output, ascii_props=False, append=False, prefix="", aliases=None):
321
320
  for v in aliases.get('canonicalcombiningclass', {}).values():
322
321
  obj[v] = []
323
322
 
324
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedCombiningClass.txt'), 'r', 'utf-8') as uf:
323
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedCombiningClass.txt'), 'r', encoding='utf-8') as uf:
325
324
  for line in uf:
326
325
  if not line.startswith('#'):
327
326
  data = line.split('#')[0].split(';')
@@ -350,7 +349,7 @@ def gen_ccc(output, ascii_props=False, append=False, prefix="", aliases=None):
350
349
  # Convert characters values to ranges
351
350
  char2range(obj, is_bytes=ascii_props)
352
351
 
353
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
352
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
354
353
  if not append:
355
354
  f.write(HEADER.format(UNIVERSION, TYPING))
356
355
  # Write out the Unicode properties
@@ -382,13 +381,13 @@ def gen_scripts(
382
381
  obj2[v] = []
383
382
 
384
383
  alias = {}
385
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'PropertyValueAliases.txt'), 'r', 'utf-8') as uf:
384
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'PropertyValueAliases.txt'), 'r', encoding='utf-8') as uf:
386
385
  for line in uf:
387
386
  if line.startswith('sc ;'):
388
387
  values = line.split(';')
389
388
  alias[format_name(values[1].strip())] = format_name(values[2].strip())
390
389
 
391
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, file_name_ext), 'r', 'utf-8') as uf:
390
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, file_name_ext), 'r', encoding='utf-8') as uf:
392
391
  for line in uf:
393
392
  if not line.startswith('#'):
394
393
  data = line.split('#')[0].split(';')
@@ -404,7 +403,7 @@ def gen_scripts(
404
403
 
405
404
  obj2[ext].extend(span)
406
405
 
407
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, file_name), 'r', 'utf-8') as uf:
406
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, file_name), 'r', encoding='utf-8') as uf:
408
407
  for line in uf:
409
408
  if not line.startswith('#'):
410
409
  data = line.split('#')[0].split(';')
@@ -439,7 +438,7 @@ def gen_scripts(
439
438
  char2range(obj, is_bytes=ascii_props)
440
439
  char2range(obj2, is_bytes=ascii_props)
441
440
 
442
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
441
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
443
442
  if not append:
444
443
  f.write(HEADER.format(UNIVERSION, TYPING))
445
444
  # Write out the Unicode properties
@@ -454,7 +453,7 @@ def gen_scripts(
454
453
  f.write(',\n')
455
454
  i += 1
456
455
 
457
- with codecs.open(output_ext, 'a' if append else 'w', 'utf-8') as f:
456
+ with open(output_ext, 'a' if append else 'w', encoding='utf-8') as f:
458
457
  if not append:
459
458
  f.write(HEADER.format(UNIVERSION, TYPING))
460
459
  # Write out the Unicode properties
@@ -482,7 +481,7 @@ def gen_enum(
482
481
  for v in aliases.get(format_name(obj_name), {}).values():
483
482
  obj[v] = []
484
483
 
485
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, file_name), 'r', 'utf-8') as uf:
484
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, file_name), 'r', encoding='utf-8') as uf:
486
485
  for line in uf:
487
486
  if not line.startswith('#'):
488
487
  data = line.split('#')[0].split(';')
@@ -508,7 +507,7 @@ def gen_enum(
508
507
  # Convert characters values to ranges
509
508
  char2range(obj, is_bytes=ascii_props)
510
509
 
511
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
510
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
512
511
  if not append:
513
512
  f.write(HEADER.format(UNIVERSION, TYPING))
514
513
  # Write out the Unicode properties
@@ -535,7 +534,7 @@ def gen_age(output, ascii_props=False, append=False, prefix="", aliases=None):
535
534
  obj[v] = []
536
535
 
537
536
  all_chars = (ALL_CHARS - ASCII_UNUSED) if ascii_props else ALL_CHARS
538
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedAge.txt'), 'r', 'utf-8') as uf:
537
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedAge.txt'), 'r', encoding='utf-8') as uf:
539
538
  for line in uf:
540
539
  if not line.startswith('#'):
541
540
  data = line.split('#')[0].split(';')
@@ -564,7 +563,7 @@ def gen_age(output, ascii_props=False, append=False, prefix="", aliases=None):
564
563
  # Convert characters values to ranges
565
564
  char2range(obj, is_bytes=ascii_props)
566
565
 
567
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
566
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
568
567
  if not append:
569
568
  f.write(HEADER.format(UNIVERSION, TYPING))
570
569
  # Write out the Unicode properties
@@ -586,7 +585,7 @@ def gen_nf_quick_check(output, ascii_props=False, append=False, prefix="", alias
586
585
  nf = {}
587
586
  all_chars = (ALL_CHARS - ASCII_UNUSED) if ascii_props else ALL_CHARS
588
587
  file_name = os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedNormalizationProps.txt')
589
- with codecs.open(file_name, 'r', 'utf-8') as uf:
588
+ with open(file_name, 'r', encoding='utf-8') as uf:
590
589
  for line in uf:
591
590
  if not line.startswith('#'):
592
591
  data = line.split('#')[0].split(';')
@@ -626,7 +625,7 @@ def gen_nf_quick_check(output, ascii_props=False, append=False, prefix="", alias
626
625
  # Convert characters values to ranges
627
626
  char2range(nf, is_bytes=ascii_props)
628
627
 
629
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
628
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
630
629
  if not append:
631
630
  f.write(HEADER.format(UNIVERSION, TYPING))
632
631
  for key, value in sorted(nf.items()):
@@ -670,7 +669,7 @@ def gen_binary(table, output, ascii_props=False, append=False, prefix="", aliase
670
669
  binary['vertspace'] = [x for x in binary['vertspace'] if x <= max_range]
671
670
 
672
671
  for filename, include in binary_props:
673
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, filename), 'r', 'utf-8') as uf:
672
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, filename), 'r', encoding='utf-8') as uf:
674
673
  for line in uf:
675
674
  if not line.startswith('#'):
676
675
  data = line.split('#')[0].split(';')
@@ -687,7 +686,7 @@ def gen_binary(table, output, ascii_props=False, append=False, prefix="", aliase
687
686
  continue
688
687
  binary[name].extend(span)
689
688
 
690
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'CompositionExclusions.txt'), 'r', 'utf-8') as uf:
689
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'CompositionExclusions.txt'), 'r', encoding='utf-8') as uf:
691
690
  name = 'compositionexclusion'
692
691
  for line in uf:
693
692
  if not line.startswith('#'):
@@ -703,7 +702,7 @@ def gen_binary(table, output, ascii_props=False, append=False, prefix="", aliase
703
702
  binary[name].extend(span)
704
703
 
705
704
  file_name = os.path.join(HOME, 'unicodedata', UNIVERSION, 'DerivedNormalizationProps.txt')
706
- with codecs.open(file_name, 'r', 'utf-8') as uf:
705
+ with open(file_name, 'r', encoding='utf-8') as uf:
707
706
  name = "fullcompositionexclusion"
708
707
  for line in uf:
709
708
  if not line.startswith('#'):
@@ -720,7 +719,7 @@ def gen_binary(table, output, ascii_props=False, append=False, prefix="", aliase
720
719
  binary[name] = []
721
720
  binary[name].extend(span)
722
721
 
723
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', 'utf-8') as uf:
722
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', encoding='utf-8') as uf:
724
723
  name = 'bidimirrored'
725
724
  for line in uf:
726
725
  data = line.strip().split(';')
@@ -744,9 +743,9 @@ def gen_binary(table, output, ascii_props=False, append=False, prefix="", aliase
744
743
  # One off Unicode property found under https://unicode.org/reports/tr18/#Compatibility_Properties
745
744
  # `Word: [\p{alnum}\p{M}\p{Pc}\p{JoinControl}]`
746
745
  s = set(binary["alnum"])
747
- s |= set(table['m']['c'])
748
- s |= set(table['m']['e'])
749
- s |= set(table['m']['n'])
746
+ for k, v in table['m'].items():
747
+ if not k.startswith('^'):
748
+ s |= set(v)
750
749
  s |= set(table["p"]["c"])
751
750
  s |= set(binary["joincontrol"])
752
751
  binary["word"] = list(s)
@@ -759,7 +758,7 @@ def gen_binary(table, output, ascii_props=False, append=False, prefix="", aliase
759
758
  # Convert characters values to ranges
760
759
  char2range(binary, is_bytes=ascii_props)
761
760
 
762
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
761
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
763
762
  if not append:
764
763
  f.write(HEADER.format(UNIVERSION, TYPING))
765
764
  # Write out the Unicode properties
@@ -786,7 +785,7 @@ def gen_bidi(output, ascii_props=False, append=False, prefix="", aliases=None):
786
785
  bidi_class[v] = []
787
786
 
788
787
  max_range = MAXVALIDASCII if ascii_props else MAXUNICODE
789
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', 'utf-8') as uf:
788
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', encoding='utf-8') as uf:
790
789
  for line in uf:
791
790
  data = line.strip().split(';')
792
791
  if data:
@@ -810,7 +809,7 @@ def gen_bidi(output, ascii_props=False, append=False, prefix="", aliases=None):
810
809
  # Convert characters values to ranges
811
810
  char2range(bidi_class, is_bytes=ascii_props)
812
811
 
813
- with codecs.open(output, 'a' if append else 'w', 'utf-8') as f:
812
+ with open(output, 'a' if append else 'w', encoding='utf-8') as f:
814
813
  if not append:
815
814
  f.write(HEADER.format(UNIVERSION, TYPING))
816
815
  f.write('%s_bidi_classes: dict[str, str] = {\n' % prefix)
@@ -913,7 +912,7 @@ def gen_alias(nonbinary, binary, output):
913
912
  'catalog', 'enumerated', 'numeric', 'miscellaneous'
914
913
  )
915
914
 
916
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'PropertyAliases.txt'), 'r', 'utf-8') as uf:
915
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'PropertyAliases.txt'), 'r', encoding='utf-8') as uf:
917
916
  div = False
918
917
  capture = False
919
918
  name = None
@@ -952,7 +951,7 @@ def gen_alias(nonbinary, binary, output):
952
951
  for d in data[1:]:
953
952
  alias[name][d] = data[0]
954
953
 
955
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'PropertyValueAliases.txt'), 'r', 'utf-8') as uf:
954
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'PropertyValueAliases.txt'), 'r', encoding='utf-8') as uf:
956
955
  for line in uf:
957
956
  m = alias_re.match(line)
958
957
  if m:
@@ -992,7 +991,7 @@ def gen_alias(nonbinary, binary, output):
992
991
  alias['binary']['h'] = 'horizspace'
993
992
  alias['binary']['v'] = 'vertspace'
994
993
 
995
- with codecs.open(output, 'w', 'utf-8') as f:
994
+ with open(output, 'w', encoding='utf-8') as f:
996
995
  f.write(HEADER.format(UNIVERSION, TYPING))
997
996
  f.write('%s_alias: dict[str, dict[str, str]] = {\n' % prefix)
998
997
  count = len(alias) - 1
@@ -1037,7 +1036,7 @@ def gen_properties(output, files, aliases, ascii_props=False, append=False):
1037
1036
  # before sending it through.
1038
1037
  table = {'l': {'c': []}}
1039
1038
  itable = {'l': {}}
1040
- with codecs.open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', 'utf-8') as uf:
1039
+ with open(os.path.join(HOME, 'unicodedata', UNIVERSION, 'UnicodeData.txt'), 'r', encoding='utf-8') as uf:
1041
1040
  for line in uf:
1042
1041
  data = line.strip().split(';')
1043
1042
  if data:
@@ -1194,7 +1193,7 @@ def gen_properties(output, files, aliases, ascii_props=False, append=False):
1194
1193
  for k1, v1 in itable.items():
1195
1194
  table[k1]['^'] = v1['^']
1196
1195
 
1197
- with codecs.open(files['gc'], 'a' if append else 'w', 'utf-8') as f:
1196
+ with open(files['gc'], 'a' if append else 'w', encoding='utf-8') as f:
1198
1197
  if not append:
1199
1198
  f.write(HEADER.format(UNIVERSION, TYPING))
1200
1199
  # Write out the Unicode properties
@@ -1219,7 +1218,7 @@ def gen_properties(output, files, aliases, ascii_props=False, append=False):
1219
1218
  i += 1
1220
1219
 
1221
1220
  if not append:
1222
- with codecs.open(os.path.join(output, '__init__.py'), 'w') as f:
1221
+ with open(os.path.join(output, '__init__.py'), 'w') as f:
1223
1222
  f.write(HEADER.format(UNIVERSION, ''))
1224
1223
  for x in sorted(files):
1225
1224
  f.write('from .%s import * # noqa\n' % os.path.basename(files[x])[:-3])
@@ -1,13 +0,0 @@
1
- """Typing objects for the Regex library."""
2
- from typing import AnyStr
3
- import regex # type: ignore[import]
4
- import sys
5
-
6
- from typing import _alias # type: ignore[attr-defined]
7
-
8
- if sys.version_info >= (3, 9):
9
- Pattern = _alias(type(regex.compile('')), 1)
10
- Match = _alias(type(regex.compile('').match('')), 1)
11
- else:
12
- Pattern = _alias(type(regex.compile('')), AnyStr)
13
- Match = _alias(type(regex.compile('').match('')), AnyStr)
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes