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.
- {backrefs-5.7.post1 → backrefs-5.9}/LICENSE.md +1 -1
- {backrefs-5.7.post1 → backrefs-5.9}/PKG-INFO +8 -10
- {backrefs-5.7.post1 → backrefs-5.9}/README.md +4 -6
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/__meta__.py +1 -1
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/_bre_parse.py +1 -1
- backrefs-5.9/backrefs/_bregex_typing.py +6 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/bre.py +19 -26
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/changelog.md +13 -3
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/refs.md +3 -3
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/usage.md +1 -1
- {backrefs-5.7.post1 → backrefs-5.9}/hatch_build.py +1 -1
- {backrefs-5.7.post1 → backrefs-5.9}/mkdocs.yml +1 -3
- {backrefs-5.7.post1 → backrefs-5.9}/pyproject.toml +5 -3
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bre.py +6 -6
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bregex.py +10 -6
- backrefs-5.9/tools/unicodedata/16.0.0.zip +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unipropgen.py +33 -34
- backrefs-5.7.post1/backrefs/_bregex_typing.py +0 -13
- backrefs-5.7.post1/tools/unicodedata/11.0.0.zip +0 -0
- backrefs-5.7.post1/tools/unicodedata/12.1.0.zip +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/.coveragerc +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/.gitignore +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/.pyspelling.yml +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/__init__.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/_bregex_parse.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/bregex.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/py.typed +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/uniprops/__init__.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/backrefs/util.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/.snippets/links.md +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/contributing.md +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/license.md +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/about/security.md +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/docs/src/markdown/index.md +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/docs/theme/announce.html +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/requirements/docs.txt +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/requirements/lint.txt +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/requirements/test.txt +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/__init__.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_age.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bidiclass.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_bidipairedbrackettype.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_binary.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_block.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_canonicalcombiningclass.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_decompositiontype.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_eastasianwidth.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_generalcategory.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_graphemeclusterbreak.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_hangulsyllabletype.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_indicpositionalcategory.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_indicsylabiccategory.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_joininggroup.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_joiningtype.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_linebreak.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_numerictype.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_numericvalue.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_quickcheck.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_script.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_scriptextensions.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_sentencebreak.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_uniprops.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_versions.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_verticalorientation.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tests/test_wordbreak.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/__init__.py +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/13.0.0.zip +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/14.0.0.zip +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/15.0.0.zip +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/15.1.0.zip +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unicodedata/LICENSE +0 -0
- {backrefs-5.7.post1 → backrefs-5.9}/tools/unidatadownload.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: backrefs
|
|
3
|
-
Version: 5.
|
|
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.
|
|
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
|
|
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
|
|
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,
|
|
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)
|
|
@@ -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,
|
|
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,
|
|
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(
|
|
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,
|
|
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,
|
|
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
|
|
50
|
-
|
|
51
|
-
|
|
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
|
|
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
|
|
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
|
-
///
|
|
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
|
|
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 © 2015 -
|
|
7
|
+
Copyright © 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.
|
|
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
|
-
|
|
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
|
-
{
|
|
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(
|
|
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(
|
|
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."""
|
|
Binary file
|
|
@@ -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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
-
|
|
748
|
-
|
|
749
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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)
|
|
Binary file
|
|
Binary file
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
File without changes
|
|
File without changes
|