├── .github └── workflows │ └── python-package.yml ├── .gitignore ├── CHANGELOG.md ├── LICENSE.txt ├── MANIFEST.in ├── README.md ├── pyproject.toml ├── requirements.txt ├── scripts └── conjugation_xml_filter.py ├── setup.cfg ├── setup.py ├── tests ├── test_conjugator.py ├── test_inflectors │ ├── test_inflector_ca.py │ ├── test_inflector_es.py │ ├── test_inflector_fr.py │ ├── test_inflector_it.py │ ├── test_inflector_pt.py │ └── test_inflector_ro.py ├── test_localization.py ├── test_mlconjug.py ├── test_parser │ ├── test_conjugation_template.py │ ├── test_tense_and_person.py │ ├── test_verb_parser.py │ └── test_verbs_parser.py ├── test_string_utils.py ├── test_type_annotations.py └── test_types │ └── test_verbs.py ├── tox.ini └── verbecc ├── __init__.py ├── data ├── models │ └── dummy-file-because-github-doesnt-like-large-files.md └── xml │ ├── conjugations │ ├── conjugations-ca.xml │ ├── conjugations-es.xml │ ├── conjugations-fr.xml │ ├── conjugations-it.xml │ ├── conjugations-pt.xml │ └── conjugations-ro.xml │ └── verbs │ ├── verbs-ca.xml │ ├── verbs-es.xml │ ├── verbs-fr.xml │ ├── verbs-it.xml │ ├── verbs-pt.xml │ └── verbs-ro.xml └── src ├── __init__.py ├── conjugator ├── __init__.py ├── conjugation_object.py └── conjugator.py ├── defs ├── __init__.py ├── constants │ ├── __init__.py │ ├── config.py │ ├── grammar_defines.py │ └── localization.py └── types │ ├── __init__.py │ ├── alternates_behavior.py │ ├── conjugation.py │ ├── data │ ├── conjugation_template.py │ ├── conjugations.py │ ├── element.py │ ├── mood_template.py │ ├── person_ending.py │ ├── tense_template.py │ ├── verb.py │ └── verbs.py │ ├── exceptions.py │ ├── gender.py │ ├── lang │ └── es │ │ ├── lang_specific_options_es.py │ │ └── voseo_options.py │ ├── lang_code.py │ ├── lang_specific_options.py │ ├── mood.py │ ├── participle_inflection.py │ ├── person.py │ └── tense.py ├── inflectors ├── __init__.py ├── inflector.py ├── inflector_factory.py └── lang │ ├── __init__.py │ ├── inflector_ca.py │ ├── inflector_es.py │ ├── inflector_fr.py │ ├── inflector_it.py │ ├── inflector_pt.py │ └── inflector_ro.py ├── mlconjug ├── __init__.py └── mlconjug.py ├── parsers ├── __init__.py ├── conjugation_template_parser.py ├── conjugations_parser.py ├── mood_template_parser.py ├── parser.py ├── person_ending_parser.py ├── tense_template_parser.py ├── verb_parser.py └── verbs_parser.py └── utils ├── __init__.py ├── string_utils.py └── utils.py /.github/workflows/python-package.yml: -------------------------------------------------------------------------------- 1 | # This workflow will install Python dependencies, run tests and lint with a variety of Python versions 2 | # For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-python 3 | 4 | name: Python package 5 | 6 | on: 7 | push: 8 | branches: [ "main" ] 9 | pull_request: 10 | branches: [ "main" ] 11 | 12 | jobs: 13 | build: 14 | 15 | runs-on: ubuntu-latest 16 | strategy: 17 | fail-fast: false 18 | matrix: 19 | python-version: ["3.9", "3.10", "3.11", "3.12", "3.13", "3.14"] 20 | 21 | steps: 22 | - uses: actions/checkout@v4 23 | - name: Set up Python ${{ matrix.python-version }} 24 | uses: actions/setup-python@v3 25 | with: 26 | python-version: ${{ matrix.python-version }} 27 | - name: Install dependencies 28 | run: | 29 | python -m pip install --upgrade pip 30 | python -m pip install flake8 pytest 31 | if [ -f requirements.txt ]; then pip install -r requirements.txt; fi 32 | - name: Lint with flake8 33 | run: | 34 | # stop the build if there are Python syntax errors or undefined names 35 | flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics 36 | # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide 37 | flake8 . --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics 38 | - name: Test with pytest 39 | run: | 40 | pytest 41 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .eggs 2 | *.egg-info 3 | .tox/ 4 | __pycache__ 5 | dist 6 | build 7 | .coverage 8 | coverage.xml 9 | .vscode 10 | verbecc/data/models/*.zip 11 | *.log -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # verbecc Changelog 2 | 3 | - 1.11.7 [TBR] 4 | - Cont. refactoring 5 | - Separating XML parsing code from logical types 6 | 7 | - 1.11.6 [26 October 2025] 8 | - Fixed Voseo conjugation for irregular verb `ser` for the subjuntivo (no vowel accents) 9 | - Misc. cleanup 10 | - Promoted applicable `Inflector` methods to public 11 | 12 | - 1.11.5 [24 October 2025] 13 | - Fixed Spanish Voseo imperativo afirmativo 14 | 15 | - 1.11.4 [24 October 2025] 16 | - Added support for Spanish Voseo 17 | 18 | - 1.11.3 [19 October 2025] 19 | - improved typing 20 | - changed `Language` enum to `LangCodeISO639_1` (suggest `from verbecc import LangCodeISO639_1 as Lang`) 21 | 22 | - 1.12.2 [17 October 2025] 23 | - Added typing for mood and tense using `StrEnum` (backwards-compatible with string values) 24 | - Fixed typo in new `Language` enum 25 | - Corrected Romanian conditional tense spelling from `conditional` to `condițional` 26 | 27 | - 1.11.1 [13 October 2025] 28 | - Fixed issues with Italian 29 | - Further typing improvements 30 | - Added `gender` option to top-level `conjugate` method 31 | 32 | - 1.11.0 [12 October 2025] 33 | - (mega refactor) 34 | - **Changes should be transparent to users of top level `Conjugator.conjugate` function, however in sub-level conjugate methods the `alternate: bool` parameter has been replaced with the `alternate_options: AlternateOptions` parameter.** 35 | - **Officially dropping support for python <=3.8. Python 3.8 has been EOL for over a year now. Update to python 3.9 or later. Now supporting Python 3.9, 3.10, 3.11, 3.12, 3.13 and 3.14.** 36 | - Significant refactoring 37 | - Eliminated a lot of code duplication introduced during initial implementation of `include_alternates` option 38 | - Moved most language-specific conjugation logic into the `Inflector` sub-classes 39 | - Moved most language-agnostic conjugation logic into `Conjugator` 40 | - Improved typing, now have typehint definitions for all returned data structures 41 | - Organized source tree into subdirectories 42 | - Added fixtures to optimize unit tests 43 | - Updated dependencies 44 | 45 | - 1.10.5 [5 October 2025] 46 | - Fixed issue #26 (issue with compound verb conjugations with `include_alternates=True`) 47 | 48 | - 1.10.4 49 | - Improved French conjugation templates 50 | 51 | - 1.10.3 [28 September 2025] 52 | - GitLab actions integration 53 | - added `importlib_resources` to `requirements.txt` 54 | 55 | - 1.10.2 [28 September 2025] 56 | - Improved Italian conjugation template (split participle into _presente_ and _passato_) 57 | - Improved Italian conjugation (verbs conjugated with _essere_) 58 | 59 | - 1.10.1 [28 September 2025] 60 | - Properly conjugate h non aspiré en FR 61 | - Reverted back to uncompressed XML files 62 | 63 | - 1.10.0 [28 September 2025] 64 | - Switched from deprecated `pkg_resources` library to new `importlib_resources` library 65 | - Compressed XML files 66 | 67 | - 1.9.7 [5 January 2024] 68 | - Added option to include alternate conjugations 69 | - Added option to not conjugate pronouns e.g. return _apprends_ rather than _j'apprends_ 70 | - Example: `include_alternates=False, conjugate_pronouns=True` (equivalent to classic verbecc behavior) 71 | ```json 72 | "condicional": { 73 | "present": [ 74 | "jo seria", 75 | "tu series", 76 | "ell seria", 77 | "nosaltres seríem", 78 | "vosaltres seríeu", 79 | "ells serien", 80 | ] 81 | }, 82 | ``` 83 | - Example: `include_alternates=True, conjugate_pronouns=False` (observe now a list of one or more conjugations is returned in place of the scalar value) 84 | ```json 85 | "condicional": { 86 | "present": [ 87 | ["seria", "fora"], 88 | ["series", "fores"], 89 | ["seria", "fora"], 90 | ["seríem", "fórem"], 91 | ["seríeu", "fóreu"], 92 | ["serien", "foren"], 93 | ] 94 | }, 95 | ``` 96 | 97 | - 1.9.6 [26 December 2023] 98 | - Improved Catalan Support 99 | - Added remaining missing templates for all 8616 verbs 100 | - See `test_inflector_ca.test_all_verbs_have_templates` 101 | 102 | - 1.9.5 [24 December 2023] 103 | - Improved Catalan Support 104 | - Added more missing templates (7+) 105 | - TODO: Still missing 9 templates for 28 out of 8616 verbs 106 | - See `test_inflector_ca.test_all_verbs_have_templates` 107 | 108 | - 1.9.4 [23 December 2023] 109 | - Improved Catalan Support 110 | - Added more missing templates (8+) 111 | - TODO: Still missing 26 templates for 172 out of 8616 verbs 112 | - See `test_inflector_ca.test_all_verbs_have_templates` 113 | 114 | - 1.9.3 [22 December 2023] 115 | - Improved Catalan support 116 | - Added more missing verb conjugation templates 117 | - Can now conjugate 8578 verbs using 42 templates 118 | - TODO: Still missing 38 templates for 200+ verbs 119 | - See `test_inflector_ca.test_all_verbs_have_templates` 120 | - Made Catalan inflector template matching more loose 121 | - Added `verbecc.string_utils.get_common_letter_count` 122 | - Now matches if template ending has len()-1 chars in common with infinitive ending (not counting accents) 123 | - E.g. Not just `aure` and `eure` match, but also `çar` and `cer` 124 | - Enhanced conjugation template syntax: now supports stem-changing verbs through two new features: 125 | - 1. New stem-modifying XML attribute: `modify-stem="strip-accents"` 126 | - 2. Stem-modifying delete operator '`-`' 127 | - e.g. 128 | ```xml 129 |