legalsuffix 0.0.1a2__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.
- legalsuffix-0.0.1a2/LICENSE +21 -0
- legalsuffix-0.0.1a2/PKG-INFO +108 -0
- legalsuffix-0.0.1a2/README.md +99 -0
- legalsuffix-0.0.1a2/pyproject.toml +52 -0
- legalsuffix-0.0.1a2/setup.cfg +4 -0
- legalsuffix-0.0.1a2/src/legalsuffix/__init__.py +27 -0
- legalsuffix-0.0.1a2/src/legalsuffix/constants.py +6 -0
- legalsuffix-0.0.1a2/src/legalsuffix/data/suffixes.csv +4003 -0
- legalsuffix-0.0.1a2/src/legalsuffix/loader.py +97 -0
- legalsuffix-0.0.1a2/src/legalsuffix/matching.py +199 -0
- legalsuffix-0.0.1a2/src/legalsuffix/models.py +75 -0
- legalsuffix-0.0.1a2/src/legalsuffix/parser.py +64 -0
- legalsuffix-0.0.1a2/src/legalsuffix/validation.py +18 -0
- legalsuffix-0.0.1a2/src/legalsuffix.egg-info/PKG-INFO +108 -0
- legalsuffix-0.0.1a2/src/legalsuffix.egg-info/SOURCES.txt +20 -0
- legalsuffix-0.0.1a2/src/legalsuffix.egg-info/dependency_links.txt +1 -0
- legalsuffix-0.0.1a2/src/legalsuffix.egg-info/top_level.txt +1 -0
- legalsuffix-0.0.1a2/tests/test_loader.py +115 -0
- legalsuffix-0.0.1a2/tests/test_matching.py +118 -0
- legalsuffix-0.0.1a2/tests/test_matching_data.py +28 -0
- legalsuffix-0.0.1a2/tests/test_parser.py +63 -0
- legalsuffix-0.0.1a2/tests/test_validation.py +53 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Slava Nazimkov
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: legalsuffix
|
|
3
|
+
Version: 0.0.1a2
|
|
4
|
+
Summary: Detect, normalize, and strip legal entity suffixes.
|
|
5
|
+
Requires-Python: >=3.12
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
License-File: LICENSE
|
|
8
|
+
Dynamic: license-file
|
|
9
|
+
|
|
10
|
+

|
|
11
|
+
|
|
12
|
+
# legalsuffix
|
|
13
|
+
|
|
14
|
+

|
|
15
|
+
[](https://www.python.org/)
|
|
16
|
+
[](LICENSE)
|
|
17
|
+
|
|
18
|
+
Detect, normalize, and strip legal entity suffixes (LLC, LTD, GmbH, OOO, 株式会社…) in 20+ languages. Parse company names safely.
|
|
19
|
+
|
|
20
|
+
# Operations
|
|
21
|
+
|
|
22
|
+
The package exposes these operations from `legalsuffix`. Country and language
|
|
23
|
+
filters are optional; country codes use ISO 3166-1 alpha-2 and language codes use
|
|
24
|
+
ISO 639-1 two-letter codes.
|
|
25
|
+
|
|
26
|
+
```python
|
|
27
|
+
from legalsuffix import (
|
|
28
|
+
get_suffixes,
|
|
29
|
+
match_legal_suffix,
|
|
30
|
+
normalize_legal_suffix,
|
|
31
|
+
parse_company_name,
|
|
32
|
+
strip_legal_suffix,
|
|
33
|
+
)
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### Get suffix records
|
|
37
|
+
|
|
38
|
+
`get_suffixes` returns `LegalSuffix` records. Filters are optional.
|
|
39
|
+
|
|
40
|
+
```python
|
|
41
|
+
suffixes = get_suffixes(country_code="DE", language_code="de")
|
|
42
|
+
for suffix in suffixes[:5]:
|
|
43
|
+
print(suffix.elf_code, suffix.entity_legal_form_name_local_name)
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
### Match a suffix
|
|
47
|
+
|
|
48
|
+
`match_legal_suffix` finds a legal form in the company name. Some registry names
|
|
49
|
+
place the legal form before additional descriptive text. It returns `None` if
|
|
50
|
+
there is no match. The end offset is exclusive.
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
company = "Musterfirma GmbH"
|
|
54
|
+
match = match_legal_suffix(company, country_code="DE")
|
|
55
|
+
if match is not None:
|
|
56
|
+
print(match.suffix) # "GmbH"
|
|
57
|
+
print(match.start_pos, match.end_pos) # 12 16
|
|
58
|
+
print(match.records[0].elf_code) # ELF code for this legal form
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Normalize a suffix
|
|
62
|
+
|
|
63
|
+
Normalization trims surrounding whitespace, ignores punctuation and accents,
|
|
64
|
+
and lowercases the suffix.
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
normalize_legal_suffix(" GmbH. ") # "gmbh"
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### Parse a company name
|
|
71
|
+
|
|
72
|
+
`parse_company_name` returns the company name with the matched legal form
|
|
73
|
+
removed, along with the optional suffix match. Text after the form is preserved.
|
|
74
|
+
|
|
75
|
+
```python
|
|
76
|
+
parsed = parse_company_name("Musterfirma GmbH", country_code="DE")
|
|
77
|
+
print(parsed.name) # "Musterfirma"
|
|
78
|
+
if parsed.suffix is not None:
|
|
79
|
+
print(parsed.suffix.suffix) # "GmbH"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### Strip a suffix
|
|
83
|
+
|
|
84
|
+
`strip_legal_suffix` removes the recognized legal form and preserves any text
|
|
85
|
+
that follows it.
|
|
86
|
+
|
|
87
|
+
```python
|
|
88
|
+
strip_legal_suffix("Musterfirma GmbH", country_code="DE") # "Musterfirma"
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
Country codes use ISO 3166-1 alpha-2, and language codes use ISO 639-1 two-letter
|
|
92
|
+
codes.
|
|
93
|
+
|
|
94
|
+
# Development hooks
|
|
95
|
+
|
|
96
|
+
Install the pre-commit hook to run the unit tests and refresh the coverage
|
|
97
|
+
badge before a commit that changes a Python file under `src/`:
|
|
98
|
+
|
|
99
|
+
```shell
|
|
100
|
+
uv run pre-commit install
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
If the badge changes, stage `README.md` and retry the commit so the updated
|
|
104
|
+
coverage is included.
|
|
105
|
+
|
|
106
|
+
# Data Source
|
|
107
|
+
|
|
108
|
+
ISO 20275: Entity Legal Forms Code List: [Entity Legal Forms Code List (Version 1.6 )](https://www.gleif.org/lei-data/code-lists/iso-20275-entity-legal-forms-code-list/2026-02-19-elf-code-list-v1.6.xlsx)
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+

|
|
2
|
+
|
|
3
|
+
# legalsuffix
|
|
4
|
+
|
|
5
|
+

|
|
6
|
+
[](https://www.python.org/)
|
|
7
|
+
[](LICENSE)
|
|
8
|
+
|
|
9
|
+
Detect, normalize, and strip legal entity suffixes (LLC, LTD, GmbH, OOO, 株式会社…) in 20+ languages. Parse company names safely.
|
|
10
|
+
|
|
11
|
+
# Operations
|
|
12
|
+
|
|
13
|
+
The package exposes these operations from `legalsuffix`. Country and language
|
|
14
|
+
filters are optional; country codes use ISO 3166-1 alpha-2 and language codes use
|
|
15
|
+
ISO 639-1 two-letter codes.
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from legalsuffix import (
|
|
19
|
+
get_suffixes,
|
|
20
|
+
match_legal_suffix,
|
|
21
|
+
normalize_legal_suffix,
|
|
22
|
+
parse_company_name,
|
|
23
|
+
strip_legal_suffix,
|
|
24
|
+
)
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
### Get suffix records
|
|
28
|
+
|
|
29
|
+
`get_suffixes` returns `LegalSuffix` records. Filters are optional.
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
suffixes = get_suffixes(country_code="DE", language_code="de")
|
|
33
|
+
for suffix in suffixes[:5]:
|
|
34
|
+
print(suffix.elf_code, suffix.entity_legal_form_name_local_name)
|
|
35
|
+
```
|
|
36
|
+
|
|
37
|
+
### Match a suffix
|
|
38
|
+
|
|
39
|
+
`match_legal_suffix` finds a legal form in the company name. Some registry names
|
|
40
|
+
place the legal form before additional descriptive text. It returns `None` if
|
|
41
|
+
there is no match. The end offset is exclusive.
|
|
42
|
+
|
|
43
|
+
```python
|
|
44
|
+
company = "Musterfirma GmbH"
|
|
45
|
+
match = match_legal_suffix(company, country_code="DE")
|
|
46
|
+
if match is not None:
|
|
47
|
+
print(match.suffix) # "GmbH"
|
|
48
|
+
print(match.start_pos, match.end_pos) # 12 16
|
|
49
|
+
print(match.records[0].elf_code) # ELF code for this legal form
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Normalize a suffix
|
|
53
|
+
|
|
54
|
+
Normalization trims surrounding whitespace, ignores punctuation and accents,
|
|
55
|
+
and lowercases the suffix.
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
normalize_legal_suffix(" GmbH. ") # "gmbh"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
### Parse a company name
|
|
62
|
+
|
|
63
|
+
`parse_company_name` returns the company name with the matched legal form
|
|
64
|
+
removed, along with the optional suffix match. Text after the form is preserved.
|
|
65
|
+
|
|
66
|
+
```python
|
|
67
|
+
parsed = parse_company_name("Musterfirma GmbH", country_code="DE")
|
|
68
|
+
print(parsed.name) # "Musterfirma"
|
|
69
|
+
if parsed.suffix is not None:
|
|
70
|
+
print(parsed.suffix.suffix) # "GmbH"
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
### Strip a suffix
|
|
74
|
+
|
|
75
|
+
`strip_legal_suffix` removes the recognized legal form and preserves any text
|
|
76
|
+
that follows it.
|
|
77
|
+
|
|
78
|
+
```python
|
|
79
|
+
strip_legal_suffix("Musterfirma GmbH", country_code="DE") # "Musterfirma"
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Country codes use ISO 3166-1 alpha-2, and language codes use ISO 639-1 two-letter
|
|
83
|
+
codes.
|
|
84
|
+
|
|
85
|
+
# Development hooks
|
|
86
|
+
|
|
87
|
+
Install the pre-commit hook to run the unit tests and refresh the coverage
|
|
88
|
+
badge before a commit that changes a Python file under `src/`:
|
|
89
|
+
|
|
90
|
+
```shell
|
|
91
|
+
uv run pre-commit install
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If the badge changes, stage `README.md` and retry the commit so the updated
|
|
95
|
+
coverage is included.
|
|
96
|
+
|
|
97
|
+
# Data Source
|
|
98
|
+
|
|
99
|
+
ISO 20275: Entity Legal Forms Code List: [Entity Legal Forms Code List (Version 1.6 )](https://www.gleif.org/lei-data/code-lists/iso-20275-entity-legal-forms-code-list/2026-02-19-elf-code-list-v1.6.xlsx)
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "legalsuffix"
|
|
3
|
+
version = "0.0.1a2"
|
|
4
|
+
description = "Detect, normalize, and strip legal entity suffixes."
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.12"
|
|
7
|
+
dependencies = []
|
|
8
|
+
|
|
9
|
+
[build-system]
|
|
10
|
+
requires = ["setuptools>=68"]
|
|
11
|
+
build-backend = "setuptools.build_meta"
|
|
12
|
+
|
|
13
|
+
[tool.setuptools.packages.find]
|
|
14
|
+
where = ["src"]
|
|
15
|
+
|
|
16
|
+
[tool.setuptools.package-data]
|
|
17
|
+
legalsuffix = ["data/*.csv"]
|
|
18
|
+
|
|
19
|
+
[dependency-groups]
|
|
20
|
+
dev = [
|
|
21
|
+
"pre-commit>=4.2.0",
|
|
22
|
+
"ruff>=0.12.4",
|
|
23
|
+
"pyright>=1.1.403",
|
|
24
|
+
"coverage>=7.17.2",
|
|
25
|
+
]
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
[tool.pyright]
|
|
29
|
+
venvPath = "."
|
|
30
|
+
venv = ".venv"
|
|
31
|
+
exclude = [
|
|
32
|
+
"**/__pycache__",
|
|
33
|
+
"**/.venv",
|
|
34
|
+
"**/htmlcov",
|
|
35
|
+
"**/.pytest_cache"
|
|
36
|
+
]
|
|
37
|
+
pythonVersion = "3.12"
|
|
38
|
+
typeCheckingMode = "basic"
|
|
39
|
+
|
|
40
|
+
|
|
41
|
+
[tool.ruff]
|
|
42
|
+
line-length = 120
|
|
43
|
+
|
|
44
|
+
[tool.ruff.lint]
|
|
45
|
+
select = [
|
|
46
|
+
"E", # pycodestyle errors
|
|
47
|
+
"F", # pyflakes
|
|
48
|
+
"I", # isort
|
|
49
|
+
"N", # pep8-naming
|
|
50
|
+
"UP", # pyupgrade
|
|
51
|
+
"B", # flake8-bugbear
|
|
52
|
+
]
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
"""Public API for detecting and working with legal suffixes.
|
|
2
|
+
|
|
3
|
+
Example:
|
|
4
|
+
>>> from legalsuffix import parse_company_name
|
|
5
|
+
>>> parsed = parse_company_name("Acme GmbH", country_code="DE")
|
|
6
|
+
>>> parsed.name
|
|
7
|
+
'Acme'
|
|
8
|
+
>>> parsed.suffix.suffix
|
|
9
|
+
'GmbH'
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
from .loader import get_suffixes
|
|
13
|
+
from .matching import match_legal_suffix, normalize_legal_suffix, parse_company_name, strip_legal_suffix
|
|
14
|
+
from .models import LegalSuffix, LegalSuffixMatch, ParsedCompanyName
|
|
15
|
+
|
|
16
|
+
__version__ = "0.0.1a2"
|
|
17
|
+
|
|
18
|
+
__all__ = [
|
|
19
|
+
"LegalSuffix",
|
|
20
|
+
"LegalSuffixMatch",
|
|
21
|
+
"ParsedCompanyName",
|
|
22
|
+
"get_suffixes",
|
|
23
|
+
"match_legal_suffix",
|
|
24
|
+
"normalize_legal_suffix",
|
|
25
|
+
"parse_company_name",
|
|
26
|
+
"strip_legal_suffix",
|
|
27
|
+
]
|