Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/pull_request_template.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ If applicable, include links to any relevant documentation, articles, or resourc
- [ ] Documentation update (changes to documentation only)
- [ ] Refactor / code style update (non-breaking change that improves code structure or readability)
- [ ] Tests / CI improvement (adding or updating tests or CI configuration only)
- [ ] Chore / maintenance (non-breaking change that does not affect functionality, such as updating dependencies or fixing typos)
- [ ] Other (please describe):

## Checklist
Expand All @@ -32,3 +33,4 @@ If applicable, include links to any relevant documentation, articles, or resourc
- [ ] Updated any relevant documentation.
- [ ] Added comments to your code where necessary.
- [ ] Formatted your code, run the linters, checked types and tests.
- [ ] Added your changes to the [CHANGELOG](./CHANGELOG.md) file, if applicable.
139 changes: 113 additions & 26 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,54 @@
# language_tool_python Changelog
# Changelog

## 3.4.0 (2026-05-15)
- Corrected a bug in `language_tool_python.server.LanguageTool.check` where the LT `/check` endpoint was queried with GET instead of POST.
- Corrected a bug in `language_tool_python.config_file.LanguageToolConfig` where config keys and values could contain line breaks or end with an odd number of backslashes.
- Corrected the default LT download version (from `latest` snapshot to release `6.8`).
All notable changes to this project will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/2.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [Unreleased]

### Added
- Added `premium_key` property to `language_tool_python.server.LanguageTool` to attach a premium API key for LanguageTool API requests.
- Added `premium_username` property to `language_tool_python.server.LanguageTool` to attach a username for premium LanguageTool API requests.
- Added `language_tool_python.match.is_check_match` type guard function to verify that a value is a `CheckMatch` (type from `language_tool_python._internals`).
- Added `language_tool_python.config_file.ConfigValue` public type alias representing all accepted value types for `LanguageToolConfig`.

### Changed
- **Breaking:** Dropped Python 3.9 support, now supports Python 3.10-3.15.
- **Breaking:** Moved internal utilities to a private `_internals` subpackage:
- `language_tool_python.safe_zip` -> `language_tool_python._internals.safe_zip`
- `language_tool_python.utils.parse_url` -> `language_tool_python._internals.utils.parse_url`
- `language_tool_python.utils.get_env_int` -> `language_tool_python._internals.utils.get_env_int`
- `language_tool_python.utils.get_env_float` -> `language_tool_python._internals.utils.get_env_float`
- `language_tool_python.utils.get_language_tool_download_path` -> `language_tool_python._internals.utils.get_language_tool_download_path`
- `language_tool_python.utils.get_locale_language` -> `language_tool_python._internals.utils.get_locale_language`
- `language_tool_python.utils.kill_process_force` -> `language_tool_python._internals.utils.kill_process_force`
- Removed `packaging` as a runtime dependency.
- **Breaking:** Narrowed the type of the `config` parameter of `language_tool_python.config_file.LanguageToolConfig.__init__` from `dict[str, Any]` to `Mapping[str, ConfigValue]`.
- **Breaking:** Changed return type of `language_tool_python.download_lt.LocalLanguageTool.version_into` and `language_tool_python.download_lt.ReleaseLocalLanguageTool.version_into` from `packaging.version.Version` to `tuple[int, int]`.
- Replaced `toml` dependency with `tomli` for Python < 3.11 (fallback for the stdlib `tomllib`).
- Added `typing_extensions` as a dependency for Python < 3.13 (fallback for the stdlib `warnings.deprecated`).

### Fixed
- Corrected a bug in `language_tool_python.config_file.LanguageToolConfig` where directory paths were incorrectly rejected by the path validator.

### Removed
- **Breaking:** Removed all functions and classes previously deprecated in v3.3.0:
- `language_tool_python.download_lt.get_common_prefix`
- `language_tool_python.download_lt.http_get`
- `language_tool_python.download_lt.unzip_file`
- `language_tool_python.download_lt.download_zip`
- `language_tool_python.download_lt.download_lt`
- `language_tool_python.utils.find_existing_language_tool_downloads`
- `language_tool_python.utils.get_language_tool_directory`
- `language_tool_python.utils.get_server_cmd`
- `language_tool_python.utils.get_jar_info`
- `language_tool_python.match.auto_type`

## [3.4.0] - 2026-05-15

> Security hardening for LT downloads: SHA-256 integrity verification, safe ZIP extraction, configurable size limits, and support for LT releases 6.7+.

### Added
- Added SHA-256 verification for downloaded LT zip files.
- Added a bundled `language_tool_python/integrity.toml` manifest containing SHA-256 checksums for LT release/archive downloads.
- Added new env variables for LT download verification:
Expand All @@ -12,7 +57,6 @@
- `LTP_BYPASS_VERIFIED_DOWNLOADS`
- Added a maximum download size limit for LT zip files, configurable with `LTP_MAX_DOWNLOAD_BYTES`.
- Added `language_tool_python.safe_zip.SafeZipExtractor` and `language_tool_python.safe_zip.SafeZipLimits` to extract ZIP files safely.
- Edited LT ZIP extraction to reject unsafe paths, symlinks, unsupported member types, duplicate paths, file/directory conflicts, oversized archives/members, suspicious compression ratios and overwrites of existing paths.
- Added new env variables for safe ZIP extraction limits:
- `LTP_SAFE_ZIP_MAX_ARCHIVE_BYTES`
- `LTP_SAFE_ZIP_MAX_EXTRACTED_BYTES`
Expand All @@ -24,81 +68,124 @@
- Added `LTP_DOWNLOAD_HOST_NEW_RELEASES` to override the new LT release download host.
- Added `language_tool_python.utils.get_env_int` and `language_tool_python.utils.get_env_float`.

## 3.3.1 (2026-05-10)
### Changed
- Edited the default LT download version (from `latest` snapshot to release `6.8`).
- Edited LT ZIP extraction to reject unsafe paths, symlinks, unsupported member types, duplicate paths, file/directory conflicts, oversized archives/members, suspicious compression ratios and overwrites of existing paths.

### Fixed
- Corrected a bug in `language_tool_python.server.LanguageTool.check` where the LT `/check` endpoint was queried with GET instead of POST.
- Corrected a bug in `language_tool_python.config_file.LanguageToolConfig` where config keys and values could contain line breaks or end with an odd number of backslashes.

## [3.3.1] - 2026-05-10

### Changed
- Edited the LanguageTool snapshot current version (from 6.8-SNAPSHOT to 6.9-SNAPSHOT) to allow users to retrieve automatically the latest snapshot version of LT.

## 3.3.0 (2026-03-07)
- Corrected a bug in `language_tool_python.server.LanguageTool._get_valid_spelling_file_path` where the spelling file was always the one for English, even when the LT instance was configured for a different language.
- Corrected a bug in `language_tool_python.server.LanguageTool` where, even if you specified a `language_tool_download_version`, the used LT version was always the latest one present on the system (the download was working correctly, but the downloaded version was not used).
- Corrected the necessary java version for old LT releases (from 1.8 to 1.9).
## [3.3.0] - 2026-03-07

### Added
- Added an abstract class `LocalLanguageTool` that expose an common interface for subclasses who implements some type of LT download.
- Added `ReleaseLocalLanguageTool` class (implementation of `LocalLanguageTool`) that implements the downloading of LT from release/archive page.
- Added `SnapshotLocalLanguageTool` class (implementation of `LocalLanguagetool`) that implements the downloading of LT from snapshot page.

### Changed
- Edited the low limit of the supported LT version (now at release 4.0).

### Deprecated
- Deprecated some funcs (they remain available until version 4.0.0):
- `language_tool_python.download_lt.get_common_prefix`
- `language_tool_python.download_lt.http_get`
- `language_tool_python.download_lt.unzip_file`
- `language_tool_python.download_lt.download_zip`
- `language_tool_python.download_lt.download_lt`
- `language_tool_python.utils.find_existing_language_tool_downloads`
- `language_tool_python.utils._extract_version`
- `language_tool_python.utils.get_language_tool_directory`
- `language_tool_python.utils.get_server_cmd`
- `language_tool_python.utils.get_jar_info`

## 3.2.2 (2026-01-02)
### Fixed
- Corrected a bug in `language_tool_python.server.LanguageTool._get_valid_spelling_file_path` where the spelling file was always the one for English, even when the LT instance was configured for a different language.
- Corrected a bug in `language_tool_python.server.LanguageTool` where, even if you specified a `language_tool_download_version`, the used LT version was always the latest one present on the system (the download was working correctly, but the downloaded version was not used).
- Corrected the necessary java version for old LT releases (from 1.8 to 1.9).

## [3.2.2] - 2026-01-02

### Fixed
- Corrected a bug in `language_tool_python.download_lt.http_get` by adding proper handling of HTTP 403 and other non 200 status codes by raising `language_tool_python.exceptions.PathError`. Previously, in case of such status codes, the function would download an HTML error page instead of the expected zip file, leading to an error when attempting to unzip it.

## 3.2.1 (2025-12-30)
## [3.2.1] - 2025-12-30

### Fixed
- Corrected a bug in `language_tool_python.server._kill_processes` where processes were not being properly waited for after being killed, potentially leading to zombie processes.

## 3.2.0 (2025-12-18)
## [3.2.0] - 2025-12-18

### Added
- Added a `check_matching_regions` method in `language_tool_python.server.LanguageTool`.

## 3.1.0 (2025-11-23)
## [3.1.0] - 2025-11-23

### Added
- Added an optional parameter to `LanguageTool` (`proxies`).
- Added an `proxies` attribute to `LanguageTool` (This attribute is used by the `LanguageTool._query_server` method).
- Added new read-only properties to `LanguageTool`:
- `url`
- `is_remote`
- `host`
- `port`

### Changed
- Edited the documentation of the `LanguageTool` class to improve clarity.

## 3.0.0 (2025-11-20)
## [3.0.0] - 2025-11-20

### What's New:
- Corrected a bug when the default locale is POSIX default (C).
- Corrected a bug when closing `LanguageTool` instances (deadlocks).
- Corrected a bug when comparing LT versions (e.g., '5.8' vs '5.10').
> Major rewrite: snake_case naming conventions, strict Python types, dedicated `exceptions` module, logging, and online documentation.

### Added
- Added new possible values in LT config (`trustXForwardForHeader`, `suggestionsEnabled` and lang keys).
- Added a warning if you forget to explicitly close a `LanguageTool` instance.
- Added online documentation for the package.
- Added logging (and logs) in the package.
- Added raising `exceptions.TimeoutError` in `download_lt.http_get`.
- Added `packaging` as a dependency.
- Moved exception classes to a separate `exceptions` module (no more importable from `utils`).
- Edited raised exceptions in some methods/functions:

### Changed
- **Breaking:** Moved exception classes to a separate `exceptions` module (no more importable from `utils`).
- **Breaking:** Edited raised exceptions in some methods/functions:
- from `AssertionError` to `ValueError` in `config_file.LanguageToolConfig.__init__`
- from `AssertionError` to `exceptions.PathError` in `download_lt.download_lt`
- from `AssertionError` to `ValueError` in `download_lt.download_lt`
- from `AssertionError` to `ValueError` in `server.LanguageTool.__init__`
- from `AssertionError` to `ValueError` in `utils.kill_process_force`
- Edited some camelCase attributes/methods to snake_case:
- **Breaking:** Edited some camelCase attributes/methods to snake_case:
- `server.LanguageTool.motherTongue` to `server.LanguageTool.mother_tongue`
- `server.LanguageTool.newSpellings` to `server.LanguageTool.new_spellings`
- `match.Match.ruleId` to `match.Match.rule_id`
- `match.Match.offsetInContext` to `match.Match.offset_in_context`
- `match.Match.errorLength` to `match.Match.error_length`
- `match.Match.ruleIssueType` to `match.Match.rule_issue_type`
- `match.Match.matchedText` to `match.Match.matched_text`
- Edited types of some params:
- **Breaking:** Edited types of some params:
- `directory_to_extract_to` in `dowload_lt.unzip_file` from `str` to `Path`
- `directory` in `download_lt.download_zip` from `str` to `Path`
- `download_folder` in `utils.find_existing_language_tool_downloads` from `str` to `Path`
- Edited return types of some methods/functions:
- **Breaking:** Edited return types of some methods/functions:
- from `str` to `Path` in `utils.get_language_tool_download_path`
- from `list[str]` to `list[Path]` in `utils.find_existing_language_tool_downloads`
- from `str` to `Path` in `utils.get_language_tool_directory`
- from `tuple[str, str]` to `tuple[Path, Path]` in `utils.get_jar_info`

### Fixed
- Corrected a bug when the default locale is POSIX default (C).
- Corrected a bug when closing `LanguageTool` instances (deadlocks).
- Corrected a bug when comparing LT versions (e.g., '5.8' vs '5.10').

[Unreleased]: https://github.com/jxmorris12/language_tool_python/compare/3.4.0...HEAD
[3.4.0]: https://github.com/jxmorris12/language_tool_python/compare/3.3.1...3.4.0
[3.3.1]: https://github.com/jxmorris12/language_tool_python/compare/3.3.0...3.3.1
[3.3.0]: https://github.com/jxmorris12/language_tool_python/compare/3.2.2...3.3.0
[3.2.2]: https://github.com/jxmorris12/language_tool_python/compare/3.2.1...3.2.2
[3.2.1]: https://github.com/jxmorris12/language_tool_python/compare/3.2.0...3.2.1
[3.2.0]: https://github.com/jxmorris12/language_tool_python/compare/3.1.0...3.2.0
[3.1.0]: https://github.com/jxmorris12/language_tool_python/compare/3.0.0...3.1.0
[3.0.0]: https://github.com/jxmorris12/language_tool_python/compare/2.9.5...3.0.0
5 changes: 3 additions & 2 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ The best contributions are those that try to resolve the [issues](https://github

### 2. Fork the repository and make your changes

If you want to contribute, you first need to fork the repo (and preferably create a branch with a name that says something about the changes you're going to make).
If you want to contribute, you first need to fork the repo and create a branch with a name that says something about the changes you're going to make (e.g., `fix/issue-123`, `feature/new-function`).

To start developing, you can install all the necessary packages in your python environment with this command (optional dependencies will be installed):
```shell
Expand Down Expand Up @@ -47,9 +47,10 @@ Please do not manually bump the version number in [pyproject.toml](./pyproject.t
Before pushing and creating your pull request, you should make sure you've done the following:

- Updated any relevant tests.
- Updated any relevant documentation. This includes docstrings and [README](./README.md) file.
- Updated any relevant documentation. This includes docstrings, [README](./README.md) file, and [sphinx documentation](./docs/source/references).
- Added comments to your code where necessary (especially if the code is not self-explanatory).
- Formatted your code, run the linters and tests.
- Added your changes to the [CHANGELOG](./CHANGELOG.md) file, if applicable. You have to follow the [Keep a Changelog](https://keepachangelog.com/en/2.0.0/) format for this, and make sure to add your changes under the "Unreleased" section.

### 4. Create your pull request

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ For the full API reference, configuration options, CLI usage, and more examples,

## Versioning

This project follows [Semantic Versioning](https://semver.org/) (`MAJOR.MINOR.PATCH`):
This project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html) (`MAJOR.MINOR.PATCH`):

- **PATCH** - backwards-compatible bug fixes.
- **MINOR** - new backwards-compatible features.
Expand Down
Loading