diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index ecddf68..751dbad 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -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 @@ -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. diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ecd5aa..d467be0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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: @@ -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` @@ -24,17 +68,30 @@ - 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` @@ -42,21 +99,33 @@ - `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`: @@ -64,28 +133,31 @@ - `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` @@ -93,12 +165,27 @@ - `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 diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 73861df..fdbe3d7 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -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 @@ -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 diff --git a/README.md b/README.md index a35b328..4d1f712 100644 --- a/README.md +++ b/README.md @@ -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.