Skip to content

Commit efd5bde

Browse files
authored
Merge pull request #100 from mdevolde/master
Migrate to pyproject.toml and modernize project configuration, fix some issues
2 parents 8dff2a3 + a9eafbf commit efd5bde

17 files changed

+261
-144
lines changed

.github/workflows/test.yml

+36-11
Original file line numberDiff line numberDiff line change
@@ -12,30 +12,55 @@ on:
1212
jobs:
1313
build:
1414

15-
runs-on: ubuntu-20.04
15+
runs-on: ubuntu-22.04
1616
strategy:
1717
matrix:
18-
python-version: [3.6, 3.7, 3.8]
18+
python-version: ["3.9", "3.10", "3.11"]
1919

2020
steps:
2121
- uses: actions/checkout@v2
22+
2223
- name: Set up Python ${{ matrix.python-version }}
23-
uses: actions/setup-python@v2
24+
uses: actions/setup-python@v4
2425
with:
2526
python-version: ${{ matrix.python-version }}
27+
28+
- name: Set up JDK 21
29+
uses: actions/setup-java@v3
30+
with:
31+
distribution: 'temurin'
32+
java-version: '21'
33+
34+
- name: Create and activate virtualenv
35+
run: |
36+
python -m venv venv
37+
source venv/bin/activate
38+
python -m pip install --upgrade pip
39+
2640
- name: Install dependencies
2741
run: |
28-
python -m pip install --upgrade pip setuptools wheel
29-
pip install pytest pytest-xdist # Testing packages
30-
python setup.py install_egg_info # Workaround https://github.com/pypa/pip/issues/4537
31-
pip install -e . # Run pytest
42+
source venv/bin/activate
43+
pip install setuptools wheel build pytest pytest-xdist
44+
python -m build --sdist --wheel
45+
pip install dist/*.whl
46+
47+
- name: Verify installed packages
48+
run: |
49+
source venv/bin/activate
50+
pip list
51+
3252
- name: Import language_tool_python
3353
run: |
54+
source venv/bin/activate
3455
printf "import language_tool_python\n" | python
56+
3557
- name: Test with pytest
3658
run: |
59+
source venv/bin/activate
3760
pytest -vx --dist=loadfile -n auto
38-
#- name: Run command-line tests
39-
# run: |
40-
# ./tests/test_local.bash # Test command-line with local server
41-
# ./tests/test_remote.bash # Test command-line with remote server
61+
62+
- name: Run additional tests in bash scripts for Ubuntu
63+
run: |
64+
source venv/bin/activate
65+
bash tests/test_local.bash
66+
bash tests/test_remote.bash

.gitignore

+9
Original file line numberDiff line numberDiff line change
@@ -8,3 +8,12 @@ __pycache__/
88
build/
99
dist/
1010
language_tool_python/LanguageTool-*/
11+
language_tool_python-*/
12+
pytest-cache-files-*/
13+
.env
14+
.venv
15+
env/
16+
venv/
17+
ENV/
18+
env.bak/
19+
venv.bak/

MANIFEST.in

+11-8
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,12 @@
1-
exclude Makefile
2-
include COPYING
3-
include README.rst
41
include run_doctest.py
5-
include test.bash
6-
include test.py
7-
include test_remote.bash
8-
include requirements.txt
9-
exclude language_tool_python/Language-Tool-*
2+
include tests/test_local.bash
3+
include tests/test_remote.bash
4+
prune pytest-cache-files-*/
5+
prune env/
6+
prune .env
7+
prune .venv
8+
prune env/
9+
prune venv/
10+
prune ENV/
11+
prune env.bak/
12+
prune venv.bak/

Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,4 +15,4 @@ check:
1515
./language_tool_python \
1616
$(wildcard ./language_tool_python/*.py) \
1717
$(wildcard *.py)
18-
python setup.py --long-description | rstcheck -
18+
python extract_long_description.py | rstcheck -

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -264,7 +264,7 @@ The default download path is `~/.cache/language_tool_python/`. The LanguageTool
264264

265265
## Prerequisites
266266

267-
- [Python 3.6+](https://www.python.org)
267+
- [Python 3.9+](https://www.python.org)
268268
- [LanguageTool](https://www.languagetool.org) (Java 8.0 or higher)
269269

270270
The installation process should take care of downloading LanguageTool (it may

build_and_publish.sh

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
1-
rm -rf build/ dist/
2-
python setup.py sdist bdist_wheel
1+
rm -rf build/ dist/ *.egg-info/
2+
python -m pip install --upgrade pip setuptools wheel build
3+
python -m build
34
twine check dist/*
45
twine upload dist/* --verbose

extract_long_description.py

+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import toml
2+
import os
3+
4+
with open("pyproject.toml", "rb") as f:
5+
pyproject = toml.loads(f.read().decode('utf-8'))
6+
7+
readme_path = pyproject["project"]["readme"]
8+
9+
if os.path.exists(readme_path):
10+
with open(readme_path, "r", encoding="utf-8") as readme_file:
11+
print(readme_file.read())
12+
else:
13+
raise FileNotFoundError(f"{readme_path} not found.")

language_tool_python/__main__.py

+15-30
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,17 @@
44
import locale
55
import re
66
import sys
7+
from importlib.metadata import version
8+
import toml
79

810
from .server import LanguageTool
911
from .utils import LanguageToolError
1012

11-
import pkg_resources
12-
__version__ = pkg_resources.require("language_tool_python")[0].version
13+
try:
14+
__version__ = version("language_tool_python")
15+
except PackageNotFoundError:
16+
with open("pyproject.toml", "rb") as f:
17+
__version__ = toml.loads(f.read().decode('utf-8'))["project"]["version"]
1318

1419

1520
def parse_args():
@@ -33,6 +38,8 @@ def parse_args():
3338
parser.add_argument('--enabled-only', action='store_true',
3439
help='disable all rules except those specified in '
3540
'--enable')
41+
parser.add_argument('-p', '--picky', action='store_true',
42+
help='If set, additional rules will be activated.')
3643
parser.add_argument(
3744
'--version', action='version',
3845
version='%(prog)s {}'.format(__version__),
@@ -77,14 +84,6 @@ def get_text(filename, encoding, ignore):
7784
return text
7885

7986

80-
def print_unicode(text):
81-
"""Print in a portable manner."""
82-
if sys.version_info[0] < 3:
83-
text = text.encode('utf-8')
84-
85-
print(text)
86-
87-
8887
def main():
8988
args = parse_args()
9089

@@ -109,44 +108,30 @@ def main():
109108
if args.remote_port is not None:
110109
remote_server += ':{}'.format(args.remote_port)
111110
lang_tool = LanguageTool(
111+
language=args.language,
112112
motherTongue=args.mother_tongue,
113113
remote_server=remote_server,
114114
)
115-
guess_language = None
116115

117116
try:
118117
text = get_text(filename, encoding, ignore=args.ignore_lines)
119118
except UnicodeError as exception:
120119
print('{}: {}'.format(filename, exception), file=sys.stderr)
121120
continue
122121

123-
if args.language:
124-
if args.language.lower() == 'auto':
125-
try:
126-
from guess_language import guess_language
127-
except ImportError:
128-
print('guess_language is unavailable.', file=sys.stderr)
129-
return 1
130-
else:
131-
language = guess_language(text)
132-
print('Detected language: {}'.format(language),
133-
file=sys.stderr)
134-
if not language:
135-
return 1
136-
lang_tool.language = language
137-
else:
138-
lang_tool.language = args.language
139-
140122
if not args.spell_check:
141123
lang_tool.disable_spellchecking()
142124

143125
lang_tool.disabled_rules.update(args.disable)
144126
lang_tool.enabled_rules.update(args.enable)
145127
lang_tool.enabled_rules_only = args.enabled_only
146128

129+
if args.picky:
130+
lang_tool.picky = True
131+
147132
try:
148133
if args.apply:
149-
print_unicode(lang_tool.correct(text))
134+
print(lang_tool.correct(text))
150135
else:
151136
for match in lang_tool.check(text):
152137
rule_id = match.ruleId
@@ -162,7 +147,7 @@ def main():
162147
if replacement_text and not message.endswith(('.', '?')):
163148
message += '; suggestions: ' + replacement_text
164149

165-
print_unicode('{}: {}: {}'.format(
150+
print('{}: {}: {}'.format(
166151
filename,
167152
rule_id,
168153
message))

language_tool_python/config_file.py

+13-4
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,12 @@
55
import tempfile
66

77
ALLOWED_CONFIG_KEYS = {
8-
'maxTextLength', 'maxTextHardLength', 'secretTokenKey', 'maxCheckTimeMillis', 'maxErrorsPerWordRate',
9-
'maxSpellingSuggestions', 'maxCheckThreads', 'cacheSize', 'cacheTTLSeconds', 'cacheSize', 'requestLimit',
8+
'maxTextLength', 'maxTextHardLength', 'maxCheckTimeMillis', 'maxErrorsPerWordRate',
9+
'maxSpellingSuggestions', 'maxCheckThreads', 'cacheSize', 'cacheTTLSeconds', 'requestLimit',
1010
'requestLimitInBytes', 'timeoutRequestLimit', 'requestLimitPeriodInSeconds', 'languageModel',
11-
'word2vecModel', 'fasttextModel', 'fasttextBinary', 'maxWorkQueueSize', 'rulesFile', 'warmUp',
11+
'fasttextModel', 'fasttextBinary', 'maxWorkQueueSize', 'rulesFile',
1212
'blockedReferrers', 'premiumOnly', 'disabledRuleIds', 'pipelineCaching', 'maxPipelinePoolSize',
13-
'pipelineCaching', 'pipelineExpireTimeInSeconds', 'pipelinePrewarming'
13+
'pipelineExpireTimeInSeconds', 'pipelinePrewarming'
1414
}
1515
class LanguageToolConfig:
1616
config: Dict[str, Any]
@@ -19,6 +19,15 @@ def __init__(self, config: Dict[str, Any]):
1919
assert set(config.keys()) <= ALLOWED_CONFIG_KEYS, f"unexpected keys in config: {set(config.keys()) - ALLOWED_CONFIG_KEYS}"
2020
assert len(config), "config cannot be empty"
2121
self.config = config
22+
23+
if 'disabledRuleIds' in self.config:
24+
self.config['disabledRuleIds'] = ','.join(self.config['disabledRuleIds'])
25+
if 'blockedReferrers' in self.config:
26+
self.config['blockedReferrers'] = ','.join(self.config['blockedReferrers'])
27+
for key in ["pipelineCaching", "premiumOnly", "pipelinePrewarming"]:
28+
if key in self.config:
29+
self.config[key] = str(bool(self.config[key])).lower()
30+
2231
self.path = self._create_temp_file()
2332

2433
def _create_temp_file(self) -> str:

language_tool_python/download_lt.py

+3-2
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
BASE_URL = os.environ.get('LTP_DOWNLOAD_HOST', 'https://www.languagetool.org/download/')
3232
FILENAME = 'LanguageTool-{version}.zip'
3333

34-
LTP_DOWNLOAD_VERSION = '6.4'
34+
LTP_DOWNLOAD_VERSION = '6.5'
3535

3636
JAVA_VERSION_REGEX = re.compile(
3737
r'^(?:java|openjdk) version "(?P<major1>\d+)(|\.(?P<major2>\d+)\.[^"]+)"',
@@ -114,8 +114,9 @@ def http_get(url, out_file, proxies=None):
114114
total = int(content_length) if content_length is not None else None
115115
if req.status_code == 403: # Not found on AWS
116116
raise Exception('Could not find at URL {}.'.format(url))
117+
version = re.search(r'(\d+\.\d+)', url).group(1)
117118
progress = tqdm.tqdm(unit="B", unit_scale=True, total=total,
118-
desc=f'Downloading LanguageTool {LTP_DOWNLOAD_VERSION}')
119+
desc=f'Downloading LanguageTool {version}')
119120
for chunk in req.iter_content(chunk_size=1024):
120121
if chunk: # filter out keep-alive new chunks
121122
progress.update(len(chunk))

0 commit comments

Comments
 (0)