├── MANIFEST.in ├── tests ├── __init__.py └── test_main.py ├── testing └── resources │ ├── test_repo │ ├── app_module │ │ ├── __init__.py │ │ ├── static │ │ │ └── description │ │ │ │ └── index.html │ │ ├── README.rst │ │ └── __manifest__.py │ ├── broken_module │ │ ├── xml_empty.xml │ │ ├── xml_semi_empty.po │ │ ├── coding_latin.py │ │ ├── encoding_utf8.py │ │ ├── tests │ │ │ ├── __init__.py │ │ │ ├── xml_not_important_0.xml │ │ │ ├── xml_not_important_1.xml │ │ │ ├── xml_not_important_4.xml │ │ │ ├── xml_not_important_3.xml │ │ │ └── test_model.py │ │ ├── xml_syntax_error.XML │ │ ├── report │ │ │ └── test_report.xml │ │ ├── doc │ │ │ └── index.rst │ │ ├── rst_syntax.rst │ │ ├── wointerpreter_wx.py │ │ ├── skip_file_not_used.xml │ │ ├── interpreter_wx.py │ │ ├── models │ │ │ ├── __init__.py │ │ │ ├── model_inhe1.py │ │ │ └── model_inhe2.py │ │ ├── xml_special_char.xml │ │ ├── __init__.py │ │ ├── lib │ │ │ ├── tab_no_check.js │ │ │ └── broken_example.js │ │ ├── interpreter_wox.py │ │ ├── skip_xml_check_2.xml │ │ ├── broken_example2.js │ │ ├── broken_example.js │ │ ├── report.xml │ │ ├── model_view.xml │ │ ├── demo │ │ │ └── duplicated_id_demo.xml │ │ ├── skip_xml_check.xml │ │ ├── skip_xml_check_3.xml │ │ ├── i18n │ │ │ ├── broken_module.pot │ │ │ └── es.po │ │ ├── ir.model.access.csv │ │ ├── template1.xml │ │ ├── __openerp__.py │ │ ├── model_view_odoo.xml │ │ ├── pylint_oca_broken.py │ │ ├── model_view2.xml │ │ └── model_view_odoo2.xml │ ├── broken_module3 │ │ ├── __init__.py │ │ ├── README.rst │ │ ├── __manifest__.py │ │ ├── migrations │ │ │ └── 8.0.1.0.2 │ │ │ │ └── pre-migration.py │ │ ├── ir.model.access.csv │ │ └── __openerp__.py │ ├── pylint_deprecated_modules │ │ ├── ipdb.py │ │ ├── pdb.py │ │ ├── pudb.py │ │ ├── __init__.py │ │ ├── openerp │ │ │ ├── osv │ │ │ │ └── __init__.py │ │ │ └── __init__.py │ │ └── README.md │ ├── test_module │ │ ├── samples │ │ │ └── my_no_odoo_file.csv │ │ ├── migrations │ │ │ ├── 11.0.1.0.0 │ │ │ │ └── pre-migration.py │ │ │ └── 10.0.1.0.0 │ │ │ │ └── pre-migration.py │ │ ├── __init__.py │ │ ├── static │ │ │ └── src │ │ │ │ └── xml │ │ │ │ └── widget.xml │ │ ├── absolute_import.py │ │ ├── test_example.js │ │ ├── res_partner_unlink.py │ │ ├── README.rst │ │ ├── sale_order_unlink.py │ │ ├── __openerp__.py │ │ ├── osv_expression.py │ │ ├── res_users.xml │ │ ├── security │ │ │ └── ir.model.access.csv │ │ ├── model_view.xml │ │ ├── website_templates.xml │ │ ├── except_pass.py │ │ └── i18n │ │ │ └── fr.po │ ├── womanifest_module │ │ ├── ir.model.access.csv │ │ ├── __init__.py │ │ └── doc │ │ │ └── index.rst │ ├── broken_module2 │ │ ├── i18n │ │ │ └── en.po │ │ ├── migrations │ │ │ └── 2.0 │ │ │ │ └── post-migration.py │ │ ├── __init__.py │ │ ├── tests │ │ │ └── data │ │ │ │ ├── help_test_data.xml │ │ │ │ ├── odoo_data_noupdate_0.xml │ │ │ │ └── odoo_data_noupdate_1.xml │ │ ├── __openerp__.py │ │ ├── README.rst │ │ └── ir.model.access.csv │ ├── eleven_module │ │ ├── migrations │ │ │ ├── 11.0.1.0.1 │ │ │ │ └── pre-migration.py │ │ │ └── 11.0.1.0.0 │ │ │ │ └── not_used_from_manifest.xml │ │ ├── README.rst │ │ ├── tests │ │ │ ├── __init__.py │ │ │ └── test_model1.py │ │ ├── __init__.py │ │ ├── utf8_models.py │ │ ├── __manifest__.py │ │ ├── models.py │ │ └── security │ │ │ └── ir.model.access.csv │ ├── twelve_module │ │ ├── migrations │ │ │ └── 12.0.0.0.0 │ │ │ │ └── pre-migration.py │ │ ├── README.rst │ │ ├── __init__.py │ │ ├── utf8_models.py │ │ ├── models.py │ │ ├── security │ │ │ └── ir.model.access.csv │ │ └── __manifest__.py │ └── no_odoo_module │ │ ├── __init__.py │ │ ├── myfile.py │ │ └── eval_used.py │ ├── test_repo_odoo_namespace │ └── odoo │ │ ├── addons │ │ ├── test_namespace_package_module │ │ │ ├── __init__.py │ │ │ ├── __manifest__.py │ │ │ └── i18n │ │ │ │ └── fr.po │ │ └── __init__.py │ │ └── __init__.py │ └── .pylintrc-odoo-deprecated-model-methods ├── requirements.txt ├── src └── pylint_odoo │ ├── augmentations │ ├── __init__.py │ └── main.py │ ├── __init__.py │ ├── checkers │ ├── __init__.py │ ├── vim_comment.py │ ├── odoo_base_checker.py │ └── custom_logging.py │ ├── plugin.py │ └── misc.py ├── pyproject.toml ├── .pre-commit-hooks.yaml ├── .prettierrc.yml ├── test-requirements.txt ├── .isort.cfg ├── .flake8 ├── .coveragerc ├── .editorconfig ├── .bumpversion.cfg ├── .gitignore ├── setup.cfg ├── setup.py ├── pytest.ini ├── .pylintrc ├── tox.ini ├── .github └── workflows │ ├── test.yml │ └── stale.yml ├── .pre-commit-config.yaml └── README.md /MANIFEST.in: -------------------------------------------------------------------------------- 1 | include requirements.txt 2 | -------------------------------------------------------------------------------- /tests/__init__.py: -------------------------------------------------------------------------------- 1 | from . import test_main 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/app_module/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/xml_empty.xml: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module3/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/ipdb.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/pdb.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/pudb.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /requirements.txt: -------------------------------------------------------------------------------- 1 | pylint-plugin-utils==0.8.* 2 | pylint==3.3.* 3 | -------------------------------------------------------------------------------- /src/pylint_odoo/augmentations/__init__.py: -------------------------------------------------------------------------------- 1 | from . import main 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/xml_semi_empty.po: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/samples/my_no_odoo_file.csv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/womanifest_module/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/i18n/en.po: -------------------------------------------------------------------------------- 1 | PO syntax error 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/migrations/2.0/post-migration.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/openerp/osv/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/migrations/11.0.1.0.0/pre-migration.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/migrations/11.0.1.0.1/pre-migration.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/migrations/12.0.0.0.0/pre-migration.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/coding_latin.py: -------------------------------------------------------------------------------- 1 | # -*- coding: latin-1 -*- 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/encoding_utf8.py: -------------------------------------------------------------------------------- 1 | # -*- encoding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/tests/__init__.py: -------------------------------------------------------------------------------- 1 | from . import test_model 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/__init__.py: -------------------------------------------------------------------------------- 1 | from . import osv_expression 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/womanifest_module/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | -------------------------------------------------------------------------------- /src/pylint_odoo/__init__.py: -------------------------------------------------------------------------------- 1 | __version__ = "9.3.22" 2 | 3 | from .plugin import register 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/README.rst: -------------------------------------------------------------------------------- 1 | # Eleven module module for tests 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/README.rst: -------------------------------------------------------------------------------- 1 | # Eleven module module for tests 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/tests/__init__.py: -------------------------------------------------------------------------------- 1 | 2 | from . import test_model1 3 | -------------------------------------------------------------------------------- /testing/resources/test_repo_odoo_namespace/odoo/addons/test_namespace_package_module/__init__.py: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /testing/resources/test_repo/app_module/static/description/index.html: -------------------------------------------------------------------------------- 1 | 2 | Testing 3 | 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/no_odoo_module/__init__.py: -------------------------------------------------------------------------------- 1 | from . import myfile 2 | from . import eval_used 3 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | from . import utf8_models 3 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from . import tests 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/xml_syntax_error.XML: -------------------------------------------------------------------------------- 1 | 2 | <{xml-syntax-error}> -------------------------------------------------------------------------------- /src/pylint_odoo/checkers/__init__.py: -------------------------------------------------------------------------------- 1 | from . import odoo_addons 2 | from . import vim_comment 3 | from . import custom_logging 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/report/test_report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/womanifest_module/doc/index.rst: -------------------------------------------------------------------------------- 1 | Module broken 2 | =============== 3 | `````````` 4 | syntax error 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/app_module/README.rst: -------------------------------------------------------------------------------- 1 | app module 2 | ========== 3 | 4 | This module was written to check the test lint 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/__init__.py: -------------------------------------------------------------------------------- 1 | from . import models 2 | from . import utf8_models 3 | from .tests import test_model1 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/static/src/xml/widget.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/doc/index.rst: -------------------------------------------------------------------------------- 1 | Module broken 2 | ====================== 3 | 4 | 5 | `````````` 6 | syntax error 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/rst_syntax.rst: -------------------------------------------------------------------------------- 1 | Module broken 2 | ====================== 3 | 4 | 5 | `````````` 6 | syntax error 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module3/README.rst: -------------------------------------------------------------------------------- 1 | Test module 3 2 | ============= 3 | 4 | This module was written to check the test lint 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/tests/xml_not_important_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/tests/xml_not_important_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/openerp/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from . import osv # pylint: disable=W0402 4 | -------------------------------------------------------------------------------- /pyproject.toml: -------------------------------------------------------------------------------- 1 | [tool.black] 2 | line-length=119 3 | 4 | [build-system] 5 | requires = ["setuptools >=42"] 6 | build-backend = "setuptools.build_meta" 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/tests/xml_not_important_4.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/wointerpreter_wx.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | "Module python without interpreter but with execute permission." 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/skip_file_not_used.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/tests/data/help_test_data.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/no_odoo_module/myfile.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | import other_package 3 | 4 | if __name__ == '__main__': 5 | var = other_package 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/interpreter_wx.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | # !/usr/bin/python 3 | 4 | "Module python with interpreter and execute permission." 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/models/__init__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from . import broken_model 4 | from . import model_inhe1 5 | from . import model_inhe2 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/xml_special_char.xml: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/OCA/pylint-odoo/HEAD/testing/resources/test_repo/broken_module/xml_special_char.xml -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | from . import models 4 | from .models import broken_model 5 | from .tests import test_model 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module3/__manifest__.py: -------------------------------------------------------------------------------- 1 | # Verify a dictionary parsed correctly as node but raising error as literal_eval 2 | { 3 | "key": "" or "", 4 | } 5 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module3/migrations/8.0.1.0.2/pre-migration.py: -------------------------------------------------------------------------------- 1 | # Should raise manifest-behind-migrations but since manifest version is not parseable, it won't 2 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/absolute_import.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | try: 3 | import uninstalled_module 4 | except ImportError: 5 | uninstalled_module = None 6 | -------------------------------------------------------------------------------- /.pre-commit-hooks.yaml: -------------------------------------------------------------------------------- 1 | - id: pylint_odoo 2 | name: Check for Odoo modules using pylint 3 | entry: pylint 4 | language: python 5 | types: [python] 6 | require_serial: true 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/lib/tab_no_check.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('.example').each(function () { 3 | var oe_website_sale = this; 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/tests/data/odoo_data_noupdate_0.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/utf8_models.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from odoo import models 4 | 5 | 6 | class EleveModel(models.Model): 7 | _name = 'eleve.model' 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/utf8_models.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from odoo import models 4 | 5 | 6 | class TwelveModel(models.Model): 7 | _name = 'twelve.model' 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/interpreter_wox.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python 2 | # -*- coding: utf-8 -*- 3 | 4 | 5 | "Module python with interpreter but without execute permission." 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/test_example.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('.example').each(function () { 3 | var oe_website_sale = this; 4 | }); 5 | }); 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/app_module/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | "price": 1, 3 | "support": "myemail@mydomain.com", 4 | "author": "Odoo Community Association (OCA)", 5 | "license": "OEEL-1", 6 | } 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/skip_xml_check_2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/tests/data/odoo_data_noupdate_1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/lib/broken_example.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('.example').each(function () { 3 | var oe_website_sale = this; 4 | }) /*missing semicolon*/ 5 | }) /*missing semicolon*/ 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/tests/xml_not_important_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /testing/resources/.pylintrc-odoo-deprecated-model-methods: -------------------------------------------------------------------------------- 1 | [ODOOLINT] 2 | deprecated-odoo-model-methods={ 3 | '15.0': {'custom_deprecated_method_just_because', 'another_deprecated_model_method'}, 4 | '16.0': {'fields_view_get'}, 5 | } 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/pylint_deprecated_modules/README.md: -------------------------------------------------------------------------------- 1 | Pylint has next issue: 2 | 3 | https://bitbucket.org/logilab/pylint/issues/362/bug-w0402-not-show-fails-if-module-not-is 4 | 5 | This folder add all packages deprecated to show the error. 6 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/broken_example2.js: -------------------------------------------------------------------------------- 1 | /*Use of "+function" instead of "Number(function" */ 2 | +function ($) { 3 | 'use strict'; 4 | var var_1 = "value1"; 5 | var var_2 = "value2"; 6 | }; 7 | /* Newline required at end of file but not found */ -------------------------------------------------------------------------------- /.prettierrc.yml: -------------------------------------------------------------------------------- 1 | # Defaults for all prettier-supported languages. 2 | # Prettier will complete this with settings from .editorconfig file. 3 | bracketSpacing: false 4 | printWidth: 119 5 | proseWrap: always 6 | semi: true 7 | trailingComma: "es5" 8 | xmlWhitespaceSensitivity: "strict" 9 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/migrations/11.0.1.0.0/not_used_from_manifest.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 6 | 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/broken_example.js: -------------------------------------------------------------------------------- 1 | $(document).ready(function () { 2 | $('.example').each(function () { 3 | var oe_website_sale = this; 4 | }) /*missing semicolon*/ 5 | /*Use of console log*/ 6 | console.log("This is similar to a print"); 7 | }) /*missing semicolon*/ 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/res_partner_unlink.py: -------------------------------------------------------------------------------- 1 | from odoo import models 2 | 3 | 4 | class ResPartner(models.Model): 5 | _inherit = 'res.partner' 6 | 7 | def unlink(self): 8 | if self.name == 'explode': 9 | raise RuntimeError() 10 | 11 | return super().unlink() 12 | -------------------------------------------------------------------------------- /testing/resources/test_repo_odoo_namespace/odoo/__init__.py: -------------------------------------------------------------------------------- 1 | # See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages 2 | try: 3 | __import__("pkg_resources").declare_namespace(__name__) 4 | except ImportError: 5 | from pkgutil import extend_path 6 | 7 | __path__ = extend_path(__path__, __name__) 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/report.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 10 | 11 | -------------------------------------------------------------------------------- /testing/resources/test_repo_odoo_namespace/odoo/addons/__init__.py: -------------------------------------------------------------------------------- 1 | # See http://peak.telecommunity.com/DevCenter/setuptools#namespace-packages 2 | try: 3 | __import__("pkg_resources").declare_namespace(__name__) 4 | except ImportError: 5 | from pkgutil import extend_path 6 | 7 | __path__ = extend_path(__path__, __name__) 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo_odoo_namespace/odoo/addons/test_namespace_package_module/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | 'name': 'Namespace package module for tests', 3 | 'license': 'AGPL-3', 4 | 'author': u'Vauxoo,Odoo Community Association (OCA)', 5 | 'version': '12.0.1.0.0', 6 | 'depends': [ 7 | 'base', 8 | ], 9 | } 10 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/models.py: -------------------------------------------------------------------------------- 1 | from odoo import models 2 | 3 | 4 | class TwelveModel(models.Model): 5 | _name = "twelve.model" 6 | 7 | def name_get(self): 8 | # do staff 9 | return super().name_get() 10 | 11 | def name_get2(self): 12 | return super().name_get() # Should be super().name_get2() 13 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/models/model_inhe1.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from openerp import models 4 | from .no_exists import package 5 | 6 | 7 | class TestModel(models.Model): 8 | _inherit = 'res.company' 9 | 10 | def method(self): 11 | return package 12 | 13 | 14 | class TestModel2(models.Model): 15 | _inherit = 'model.no.duplicated' 16 | -------------------------------------------------------------------------------- /test-requirements.txt: -------------------------------------------------------------------------------- 1 | build 2 | bump2version 3 | coverage 4 | pbr 5 | pre-commit 6 | pytest ; python_version < '3.13' 7 | pytest<8.3.5 ; python_version >= '3.13' # Latest pytest==8.3.5 and py3.13 raises "ResourceWarning: unclosed database in sqlite3.Connection" and "pytest.PytestUnraisableExceptionWarning" 8 | pytest-cov 9 | pytest-xdist 10 | setuptools >=42 11 | tox 12 | twine 13 | wheel 14 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/README.rst: -------------------------------------------------------------------------------- 1 | .. image:: https://img.shields.io/badge/licence-AGPL--3-blue.svg 2 | :alt: License: AGPL-3 3 | 4 | Test module 5 | =========== 6 | 7 | This module was written to check the test of rst syntax. 8 | This is a rst file without syntax error. 9 | 10 | Pygments test 11 | 12 | .. code-block:: python 13 | 14 | if True: 15 | pass 16 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | 'name': 'Eleven module for tests', 3 | 'license': 'AGPL-3', 4 | 'author': u'Jesus, Odoo Community Association (OCA)', 5 | 'category': 'Category 01', 6 | 'version': '11.0.1.0.0', 7 | 'depends': [ 8 | 'base', 9 | ], 10 | 'data': [ 11 | 'security/ir.model.access.csv', 12 | ], 13 | } 14 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/sale_order_unlink.py: -------------------------------------------------------------------------------- 1 | import platform 2 | from odoo.models import Model 3 | 4 | if platform.system() == 'Windows': 5 | raise OSError 6 | 7 | 8 | class SaleOrder(Model): 9 | _name = 'sale.order' 10 | 11 | def unlink(self): 12 | if self.name == 'maybe': 13 | if self.status == 'explosive': 14 | raise Exception() 15 | 16 | return super().unlink() 17 | -------------------------------------------------------------------------------- /.isort.cfg: -------------------------------------------------------------------------------- 1 | [settings] 2 | ; see https://github.com/psf/black 3 | multi_line_output=3 4 | include_trailing_comma=True 5 | force_grid_wrap=0 6 | combine_as_imports=True 7 | use_parentheses=True 8 | line_length=119 9 | known_odoo=odoo 10 | known_odoo_addons=odoo.addons 11 | sections=FUTURE,STDLIB,THIRDPARTY,ODOO,ODOO_ADDONS,FIRSTPARTY,LOCALFOLDER 12 | default_section=THIRDPARTY 13 | ensure_newline_before_comments = True 14 | known_local_folder = pylint_odoo 15 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/migrations/10.0.1.0.0/pre-migration.py: -------------------------------------------------------------------------------- 1 | from odoo import SUPERUSER_ID, api 2 | from odoo.addons.test_module import random_stuff 3 | 4 | 5 | def method(cr, unused): 6 | # invalid-name cr and unused-argument unused 7 | return cr 8 | 9 | 10 | def migrate(cr, version): 11 | # suppressed invalid-name cr and unused-argument version 12 | with api.Environment.manage(): 13 | env = api.Environment(cr, SUPERUSER_ID, {}) 14 | env.ref('xmlid').unlink() 15 | -------------------------------------------------------------------------------- /.flake8: -------------------------------------------------------------------------------- 1 | [flake8] 2 | max-line-length = 119 3 | max-complexity = 16 4 | # B = bugbear 5 | # B9 = bugbear opinionated (incl line length) 6 | select = C,E,F,W,B,B9 7 | # E203: whitespace before ':' (black behaviour) 8 | # E501: flake8 line length (covered by bugbear B950) 9 | # W503: line break before binary operator (black behaviour) 10 | # W504: line break after binary operator (black behaviour) 11 | # C901: too complex is enabled from pylint 12 | ignore = E203,E501,W503,W504,C901 13 | per-file-ignores= 14 | __init__.py:F401 15 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module3/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | product.product.account.user,product.model_product_product,group_account_user,1,0,0,0 3 | account.payment.term,model_account_payment_term,account.group_account_user,1,0,0,0 4 | account.account.type,model_account_account_type,account.group_account_user,1,0,0,0 5 | account.tax internal user,model_account_tax,base.group_user,1,0,0,0 6 | account.account,model_account_account,account.group_account_user,1,0,0,0 7 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module3/__openerp__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | { 3 | 'name': 'Broken module 3 for tests', 4 | 'license': 'AGPL-3', 5 | 'author': ['Other', 'Odoo Community Association (OCA)'], # expected string 6 | 'maintainers': 'Others, Many people', # expected a list of strings 7 | 'website': 'htt://odoo-community.com', 8 | 'version': '8.0.1.0.0foo', 9 | 'depends': ['base'], 10 | 'data': [], 11 | 'test': [], 12 | 'installable': False, 13 | 'support': 'valid@email.com', 14 | } 15 | -------------------------------------------------------------------------------- /.coveragerc: -------------------------------------------------------------------------------- 1 | [paths] 2 | source = src 3 | 4 | [run] 5 | source = src 6 | parallel = true 7 | context = ${{COVERAGE_CONTEXT}} 8 | 9 | [report] 10 | show_missing = true 11 | precision = 2 12 | # fail_under = 98 13 | omit = 14 | *__init__.py 15 | */tests/* 16 | *__main__.py 17 | 18 | # Regexes for lines to exclude from consideration 19 | exclude_lines = 20 | # Have to re-enable the standard pragma 21 | pragma: no cover 22 | # tests import the package instead 23 | if __name__ == "__main__": 24 | 25 | [html] 26 | show_contexts=True 27 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/model_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | view.model.form 7 | test.model 8 | 9 |
10 | 11 | 12 |
13 |
14 | 15 |
16 |
17 | -------------------------------------------------------------------------------- /testing/resources/test_repo/no_odoo_module/eval_used.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | 4 | def eval_from_param(param): 5 | """eval used from param""" 6 | param("c = 2") 7 | 8 | 9 | def eval_from_other(): 10 | """eval used from many ways""" 11 | my_dict = { 12 | 'my_eval': eval, # [eval-used] 13 | } 14 | my_list = [eval] # [eval-used] 15 | 16 | my_var = eval # [eval-used] 17 | # inferred case 18 | my_var('d = 3') # [eval-used] 19 | eval_from_param(eval) # [eval-used] 20 | return my_dict, my_list 21 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/__openerp__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | { 3 | 'name': 'Broken module 2 for tests', 4 | 'license': 'unknow license', # unknow license 5 | 'author': 'Other,Odoo Community Association (OCA)', # Missing oca author 6 | 'development_status': 'InvalidDevStatus', 7 | 'website': 'https://odoo-community.org,https://odoo.com', 8 | 'version': '1.0', 9 | 'depends': ['base'], 10 | 'data': [], 11 | 'test': [], 12 | 'installable': False, 13 | 'support': 'invalidmail.com', # invalid email 14 | } 15 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/models.py: -------------------------------------------------------------------------------- 1 | from odoo import models 2 | 3 | # astroid is not set as an external Python dependency in the manifest, 4 | # so all of the following imports should fail 5 | import astroid 6 | from astroid import Const 7 | from astroid import BinOp as bo 8 | 9 | 10 | class EleveModel(models.Model): 11 | _name = 'eleve.model' 12 | 13 | def method1(self): 14 | self.const = isinstance(astroid.Const, Const) 15 | self.bo = isinstance(astroid.BinOp, bo) 16 | 17 | def fields_view_get(self): 18 | return self.bo 19 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/demo/duplicated_id_demo.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | view.model.form 7 | test.model 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/skip_xml_check.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | view.model.form80 7 | test.model 8 | 9 | 10 | view.model.form80 11 | test.model 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /.editorconfig: -------------------------------------------------------------------------------- 1 | # Configuration for known file extensions 2 | [*.{css,js,json,less,md,py,rst,sass,scss,xml,yaml,yml}] 3 | charset = utf-8 4 | end_of_line = lf 5 | indent_size = 4 6 | indent_style = space 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true 9 | 10 | [*.{json,yml,yaml,rst,md}] 11 | indent_size = 2 12 | 13 | # Do not configure editor for libs and autogenerated content 14 | [{*/static/{lib,src/lib}/**,*/static/description/index.html,*/readme/../README.rst}] 15 | charset = unset 16 | end_of_line = unset 17 | indent_size = unset 18 | indent_style = unset 19 | insert_final_newline = false 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/skip_xml_check_3.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | 6 | 7 | view.model.form80 8 | test.model 9 | 10 | 11 | view.model.form80 12 | test.model 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/__openerp__.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | { 3 | 'name': 'Empty module for tests', 4 | 'license': 'AGPL-3', 5 | 'author': u'Moisés, Odoo Community Association (OCA), author2', 6 | 'version': '10.0.1.0.0', 7 | 'depends': [ 8 | 'base', 9 | ], 10 | 'data': [ 11 | 'security/ir.model.access.csv', 12 | 'res_users.xml', 13 | 'model_view.xml', 14 | 'website_templates.xml', 15 | ], 16 | 'external_dependencies': { 17 | 'bin': [ 18 | 'sh', 19 | ], 20 | 'python': [ 21 | 'os', 22 | 'manifest_lib', 23 | ], 24 | }, 25 | } 26 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/README.rst: -------------------------------------------------------------------------------- 1 | Test module 2 2 | ============= 3 | 4 | This module was written to check the test lint 5 | 6 | 7 | ******* 8 | Project 9 | ******* 10 | 11 | .. toctree:: 12 | :maxdepth: 1 13 | 14 | project/contribute 15 | project/contributors 16 | project/license 17 | project/changes 18 | project/roadmap 19 | 20 | ***************** 21 | Developer's guide 22 | ***************** 23 | 24 | .. toctree:: 25 | :maxdepth: 2 26 | 27 | guides/concepts.rst 28 | guides/code_overview.rst 29 | 30 | ****************** 31 | Indices and tables 32 | ****************** 33 | 34 | * :ref:`genindex` 35 | * :ref:`modindex` 36 | * :ref:`search` 37 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/osv_expression.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from __future__ import absolute_import 4 | import expression 5 | import expression as expr4 6 | import manifest_lib 7 | import openerp.osv 8 | import openerp.osv.expression 9 | 10 | from openerp.osv import expression as expr2 11 | from openerp.osv import osv as osv2 12 | from openerp.osv import osv, expression # noqa 13 | from openerp.osv import osv, expression as expr3 # noqa 14 | from openerp.osv.expression import is_operator # noqa 15 | 16 | 17 | def dummy(): 18 | return (expression, osv, osv2, expr2, openerp.osv.expression, openerp.osv, 19 | expr4, expr3, absolute_import, manifest_lib) 20 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/res_users.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Moy6 7 | moylop260 8 | 9 | 10 | 11 | Admin 2 12 | admin_2 13 | 14 | 15 | 16 | 17 | 18 | 19 | change_password 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/i18n/broken_module.pot: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: Odoo Server\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 1985-04-14 17:12+0000\n" 6 | "PO-Revision-Date: 1985-04-14 02:03+0000\n" 7 | "Last-Translator: Moisés López \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: \n" 12 | "Plural-Forms: \n" 13 | 14 | # Missing module: comment 15 | #: model:ir.model.fields,field_description:broken_module.field_description 16 | #: model:ir.model.fields,field_description:broken_module.field_wizard_description 17 | #, python-format 18 | msgid "Branch" 19 | msgstr "" 20 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/tests/test_model1.py: -------------------------------------------------------------------------------- 1 | 2 | from odoo.tests.common import TransactionCase 3 | from odoo.addons.eleven_module.models import EleveModel 4 | from .no_exists import package 5 | 6 | # Even though astroid is not set as an external dependency, it should not fail, 7 | # because this is a test file 8 | import astroid 9 | from astroid import Const 10 | from astroid import BinOp as bo 11 | 12 | 13 | class TestModel(TransactionCase): 14 | def setUp(self): 15 | super(TestModel, self).setUp() 16 | self.const = isinstance(astroid.Const, Const) 17 | self.bo = isinstance(astroid.BinOp, bo) 18 | 19 | def method(self): 20 | return package 21 | 22 | def methodModel(self): 23 | return EleveModel 24 | -------------------------------------------------------------------------------- /testing/resources/test_repo_odoo_namespace/odoo/addons/test_namespace_package_module/i18n/fr.po: -------------------------------------------------------------------------------- 1 | msgid "" 2 | msgstr "" 3 | "Project-Id-Version: Odoo Server\n" 4 | "Report-Msgid-Bugs-To: \n" 5 | "POT-Creation-Date: 1985-04-14 17:12+0000\n" 6 | "PO-Revision-Date: 1985-04-14 02:03+0000\n" 7 | "Last-Translator: Moisés López \n" 8 | "Language-Team: \n" 9 | "MIME-Version: 1.0\n" 10 | "Content-Type: text/plain; charset=UTF-8\n" 11 | "Content-Transfer-Encoding: \n" 12 | "Plural-Forms: \n" 13 | 14 | #. module: test_module 15 | #: model:ir.model.fields,field_description2:test_module.field_description2 16 | #: model:ir.model.fields,field_description2:test_module.field_description2 17 | #, python-format 18 | msgid "Correct variables %s" 19 | msgstr "Correct variables" 20 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_product_product_account_user,product.product.account.user,product.model_product_product,group_account_user,1,0,0,0 3 | access_account_payment_term,account.payment.term,model_account_payment_term,account.group_account_user,1,0,0,0 4 | access_account_payment_term_line,account.payment.term.line,model_account_payment_term_line,account.group_account_user,1,0,0,0 5 | access_account_account_type,account.account.type,model_account_account_type,account.group_account_user,1,0,0,0 6 | access_account_account_type,account.tax internal user,model_account_tax,base.group_user,1,0,0,0 7 | access_account_account,account.account,model_account_account,account.group_account_user,1,0,0,0 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module2/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_product_product_account_user,product.product.account.user,product.model_product_product,group_account_user,1,0,0,0 3 | access_account_payment_term,account.payment.term,model_account_payment_term,account.group_account_user,1,0,0,0 4 | access_account_payment_term_line,account.payment.term.line,model_account_payment_term_line,account.group_account_user,1,0,0,0 5 | access_account_account_tax,account.account.type,model_account_account_type,account.group_account_user,1,0,0,0 6 | access_account_account_tax,account.tax internal user,model_account_tax,base.group_user,1,0,0,0 7 | access_account_account,account.account,model_account_account,account.group_account_user,1,0,0,0 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/eleven_module/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_product_product_account_user,product.product.account.user,product.model_product_product,group_account_user,1,0,0,0 3 | access_account_payment_term,account.payment.term,model_account_payment_term,account.group_account_user,1,0,0,0 4 | access_account_payment_term_line,account.payment.term.line,model_account_payment_term_line,account.group_account_user,1,0,0,0 5 | access_account_account_type,account.account.type,model_account_account_type,account.group_account_user,1,0,0,0 6 | access_account_account_tax,account.tax internal user,model_account_tax,base.group_user,1,0,0,0 7 | access_account_account,account.account,model_account_account,account.group_account_user,1,0,0,0 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_product_product_account_user,product.product.account.user,product.model_product_product,group_account_user,1,0,0,0 3 | access_account_payment_term,account.payment.term,model_account_payment_term,account.group_account_user,1,0,0,0 4 | access_account_payment_term_line,account.payment.term.line,model_account_payment_term_line,account.group_account_user,1,0,0,0 5 | access_account_account_type,account.account.type,model_account_account_type,account.group_account_user,1,0,0,0 6 | access_account_account_tax,account.tax internal user,model_account_tax,base.group_user,1,0,0,0 7 | access_account_account,account.account,model_account_account,account.group_account_user,1,0,0,0 8 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/security/ir.model.access.csv: -------------------------------------------------------------------------------- 1 | id,name,model_id:id,group_id:id,perm_read,perm_write,perm_create,perm_unlink 2 | access_product_product_account_user,product.product.account.user,product.model_product_product,group_account_user,1,0,0,0 3 | access_account_payment_term,account.payment.term,model_account_payment_term,account.group_account_user,1,0,0,0 4 | access_account_payment_term_line,account.payment.term.line,model_account_payment_term_line,account.group_account_user,1,0,0,0 5 | access_account_account_type,account.account.type,model_account_account_type,account.group_account_user,1,0,0,0 6 | access_account_account_tax,account.tax internal user,model_account_tax,base.group_user,1,0,0,0 7 | access_account_account,account.account,model_account_account,account.group_account_user,1,0,0,0 8 | -------------------------------------------------------------------------------- /.bumpversion.cfg: -------------------------------------------------------------------------------- 1 | [bumpversion] 2 | current_version = 9.3.22 3 | commit = True 4 | tag = True 5 | sign_tags = True 6 | 7 | [bumpversion:file:setup.cfg] 8 | search = version = {current_version} 9 | replace = version = {new_version} 10 | 11 | [bumpversion:file (badge):README.md] 12 | search = /v{current_version}.svg 13 | replace = /v{new_version}.svg 14 | 15 | [bumpversion:file (link):README.md] 16 | search = /v{current_version}...main 17 | replace = /v{new_version}...main 18 | 19 | [bumpversion:file (github link):README.md] 20 | search = /blob/v{current_version}/ 21 | replace = /blob/v{new_version}/ 22 | 23 | [bumpversion:file:README.md] 24 | search = rev: v{current_version} 25 | replace = rev: v{new_version} 26 | 27 | [bumpversion:file:src/pylint_odoo/__init__.py] 28 | search = __version__ = "{current_version}" 29 | replace = __version__ = "{new_version}" 30 | -------------------------------------------------------------------------------- /testing/resources/test_repo/twelve_module/__manifest__.py: -------------------------------------------------------------------------------- 1 | { 2 | 'name': 'Twelve module for tests', 3 | 'license': 'AGPL-3', 4 | 'author': u'Jesus, Odoo Community Association (OCA)', 5 | 'version': '12.0.1.0.0', 6 | 'depends': [ 7 | 'base', 8 | ], 9 | 'data': [ 10 | 'security/ir.model.access.csv', 11 | ], 12 | "assets": { 13 | "web.assets_common": [ 14 | "twelve_module/static/nonexistent.js", 15 | "https://shady.cdn.com/somefile.js" 16 | ], 17 | "web.assets_frontend": [ 18 | "/twelve_module/hypothetically/good/file.css", 19 | ("before", "/web/static/src/css/random.css", "https://bad.idea.com/cool.css"), 20 | ["prepend", "/web/static/src/js/hello.js", "http://insecure.and.bad.idea.com/kiwi.js"] 21 | ] 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/model_view.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | view.model.form 7 | test.model 8 | 9 |
10 | 11 | 12 |
13 |
14 | 15 | 16 | 17 | By name 18 | test.model 19 | {'group_by': ['name']} 20 | 21 | 22 | 23 |
24 |
25 | -------------------------------------------------------------------------------- /src/pylint_odoo/checkers/vim_comment.py: -------------------------------------------------------------------------------- 1 | import tokenize 2 | 3 | from pylint.checkers import BaseTokenChecker 4 | 5 | from .odoo_base_checker import OdooBaseChecker 6 | 7 | ODOO_MSGS = { 8 | # C->convention R->refactor W->warning E->error F->fatal 9 | "W8202": ("Use of vim comment", "use-vim-comment", "Better using local vim configuration file"), 10 | } 11 | 12 | 13 | class VimComment(OdooBaseChecker, BaseTokenChecker): 14 | name = "odoolint" 15 | msgs = ODOO_MSGS 16 | 17 | def is_vim_comment(self, comment): 18 | return comment.strip("# ").lower().startswith("vim:") 19 | 20 | def process_tokens(self, tokens): 21 | for tok_type, token_content, start_line_col, _end_line_col, _line_content in tokens: 22 | if tokenize.COMMENT == tok_type: 23 | line_num = start_line_col[0] 24 | if self.is_vim_comment(token_content): 25 | self.add_message("use-vim-comment", line=line_num) 26 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/template1.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 16 | 17 | 20 | 21 | 24 | 25 | 28 | 29 | -------------------------------------------------------------------------------- /src/pylint_odoo/plugin.py: -------------------------------------------------------------------------------- 1 | from . import checkers 2 | from .augmentations.main import apply_augmentations 3 | 4 | 5 | def register(linter): 6 | """Required method to auto register this checker""" 7 | linter.register_checker(checkers.odoo_addons.OdooAddons(linter)) 8 | linter.register_checker(checkers.vim_comment.VimComment(linter)) 9 | linter.register_checker(checkers.custom_logging.CustomLoggingChecker(linter)) 10 | 11 | # register any checking fiddlers 12 | apply_augmentations(linter) 13 | 14 | 15 | def get_all_messages(): 16 | """Get all messages of this plugin""" 17 | all_msgs = {} 18 | all_msgs.update(checkers.odoo_addons.ODOO_MSGS) 19 | all_msgs.update(checkers.vim_comment.ODOO_MSGS) 20 | all_msgs.update(checkers.custom_logging.ODOO_MSGS) 21 | return all_msgs 22 | 23 | 24 | def messages2md(): 25 | all_msgs = get_all_messages() 26 | md_msgs = "Short Name | Description | Code\n--- | --- | ---" 27 | for msg_code, (title, name_key, _description) in sorted(all_msgs.items(), key=lambda v: v[1][1]): 28 | md_msgs += f"\n{name_key} | {title} | {msg_code}" 29 | md_msgs += "\n" 30 | return md_msgs 31 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/__openerp__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | { 3 | 'name': 'Broken module for tests', 4 | # missing license 5 | 'author': 'Vauxoo, Many People', # Missing oca author 6 | 'category': 'No valid for odoo.com/apps', # raised category-allowed 7 | 'development_status': 'Alpha', 8 | 'description': 'Should be a README.rst file', 9 | 'version': '8_0.1.0.0', 10 | 'website': 'https://odoo-community.org', 11 | 'depends': ['base'], 12 | 'data': [ 13 | 'model_view.xml', 'model_view2.xml', 'model_view_odoo.xml', 14 | 'model_view_odoo2.xml', 15 | 'file_no_exist.xml', 16 | 'skip_xml_check.xml', 17 | 'skip_xml_check_2.xml', 18 | 'skip_xml_check_3.xml', 19 | 'duplicated.xml', 20 | 'duplicated.xml', 21 | 'report.xml', 22 | 'template1.xml', 23 | ], 24 | 'demo': ['demo/duplicated_id_demo.xml', 'file_no_exist.xml'], 25 | 'test': ['file_no_exist.yml'], 26 | 'installable': True, 27 | 'name': 'Duplicated value', 28 | 'active': True, # Deprecated active key 29 | 'auto_install': False, 30 | 'price': 800, 31 | } 32 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Byte-compiled / optimized / DLL files 2 | __pycache__/ 3 | *.py[cod] 4 | /.venv 5 | /.pytest_cache 6 | 7 | # C extensions 8 | *.so 9 | 10 | # Distribution / packaging 11 | .Python 12 | env/ 13 | bin/ 14 | build/ 15 | develop-eggs/ 16 | dist/ 17 | dist_wo_pbr/ 18 | eggs/ 19 | lib64/ 20 | parts/ 21 | sdist/ 22 | var/ 23 | *.egg-info/ 24 | .installed.cfg 25 | *.egg 26 | *.eggs 27 | 28 | # Installer logs 29 | pip-log.txt 30 | pip-delete-this-directory.txt 31 | 32 | # Unit test / coverage reports 33 | htmlcov/ 34 | .tox/ 35 | .coverage 36 | .coverage\.* 37 | .coverage\_* 38 | .cache 39 | nosetests.xml 40 | coverage.xml 41 | 42 | # Translations 43 | *.mo 44 | 45 | # Pycharm 46 | .idea 47 | 48 | # Eclipse 49 | .settings 50 | 51 | # Visual Studio cache/options directory 52 | .vs/ 53 | .vscode 54 | 55 | # OSX Files 56 | .DS_Store 57 | 58 | # Django stuff: 59 | *.log 60 | 61 | # Mr Developer 62 | .mr.developer.cfg 63 | .project 64 | .pydevproject 65 | 66 | # Rope 67 | .ropeproject 68 | 69 | # Sphinx documentation 70 | docs/_build/ 71 | 72 | # Backup files 73 | *~ 74 | *.swp 75 | 76 | # OCA rules 77 | !static/lib/ 78 | 79 | # Auto-generated 80 | ChangeLog 81 | .pre-commit-config-local.yaml 82 | -------------------------------------------------------------------------------- /setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = pylint-odoo 3 | version = 9.3.22 4 | author = Odoo Community Association (OCA) 5 | author_email = support@odoo-community.org 6 | summary = Pylint plugin for Odoo 7 | long_description_content_type = text/markdown 8 | license = APGL3 9 | home_page = https://github.com/OCA/pylint-odoo 10 | requires_python = >=3.10 11 | classifier = 12 | Development Status :: 6 - Mature 13 | Environment :: Console 14 | Intended Audience :: Developers 15 | Intended Audience :: Information Technology 16 | License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+) 17 | Operating System :: OS Independent 18 | Programming Language :: Python 19 | Programming Language :: Python :: 3 20 | Programming Language :: Python :: 3 :: Only 21 | Programming Language :: Python :: 3.10 22 | Programming Language :: Python :: 3.11 23 | Programming Language :: Python :: 3.12 24 | Programming Language :: Python :: 3.13 25 | Programming Language :: Python :: 3.14 26 | Topic :: Software Development :: Debuggers 27 | Topic :: Software Development :: Quality Assurance 28 | Topic :: Software Development :: Testing 29 | 30 | [options] 31 | package_dir = 32 | =src 33 | packages = find: 34 | 35 | [options.packages.find] 36 | where = src 37 | -------------------------------------------------------------------------------- /testing/resources/test_repo/broken_module/models/model_inhe2.py: -------------------------------------------------------------------------------- 1 | # coding: utf-8 2 | 3 | from openerp import models 4 | 5 | 6 | class TestModel(models.Model): 7 | _inherit = 'res.company' 8 | 9 | 10 | class TestModel2(models.Model): 11 | _inherit = 'res.company' 12 | 13 | 14 | class TestModel3(models.Model): 15 | _inherit = 'res.partner' 16 | 17 | 18 | class TestModel4(models.Model): 19 | _inherit = 'res.partner' 20 | 21 | 22 | class TestModel41(models.Model): 23 | _name = 'res.partner' 24 | _inherit = 'res.partner' 25 | 26 | 27 | class TestModel5(models.Model): 28 | _inherit = 'valid.duplicated' # pylint: disable=consider-merging-classes-inherited 29 | 30 | 31 | class TestModel6(models.Model): 32 | _inherit = 'valid.duplicated' 33 | 34 | 35 | class TestModel7(models.Model): 36 | _name = 'valid.duplicated.2' 37 | _inherit = 'valid.duplicated' 38 | 39 | class TestModel75(models.Model): 40 | _inherit = 'valid.duplicated' 41 | _name = 'valid.duplicated.2' 42 | 43 | class TestModel8(models.Model): 44 | _inherit = ['valid.duplicated', 'valid.duplicated2'] 45 | 46 | def method_1(self): 47 | _inherit = 'not-class-attribute' 48 | return _inherit 49 | 50 | def method_2(self): 51 | _inherit = 'not-class-attribute' 52 | return _inherit 53 | -------------------------------------------------------------------------------- /setup.py: -------------------------------------------------------------------------------- 1 | import re 2 | from os.path import dirname, join 3 | 4 | from setuptools import setup 5 | 6 | try: 7 | from pbr import git 8 | except ImportError: 9 | git = None 10 | 11 | 12 | def generate_changelog(): 13 | fname = "ChangeLog" 14 | if not git: 15 | changelog_str = '# ChangeLog was not generated. You need to install "pbr"' 16 | with open(fname, "w", encoding="UTF-8") as fchg: 17 | fchg.write(changelog_str) 18 | return changelog_str 19 | changelog = git._iter_log_oneline() 20 | changelog = git._iter_changelog(changelog) 21 | git.write_git_changelog(changelog=filter(lambda log: not log[1].startswith("* Bump version"), changelog)) 22 | return read(fname) 23 | 24 | 25 | def generate_dependencies(): 26 | return read("requirements.txt").splitlines() 27 | 28 | 29 | def read(*names, **kwargs): 30 | with open(join(dirname(__file__), *names), encoding=kwargs.get("encoding", "utf8")) as file_obj: 31 | return file_obj.read() 32 | 33 | 34 | def generage_long_description(): 35 | long_description = "{}\n{}".format( 36 | # re.compile(".*\(start-badges\).*^.*\(end-badges\)", re.M | re.S).sub("", read("README.md")), 37 | read("README.md"), 38 | re.sub(":[a-z]+:`~?(.*?)`", r"``\1``", generate_changelog()), 39 | ) 40 | return long_description 41 | 42 | 43 | setup( 44 | long_description=generage_long_description(), 45 | install_requires=generate_dependencies(), 46 | ) 47 | -------------------------------------------------------------------------------- /testing/resources/test_repo/test_module/website_templates.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 10 | 11 | 12 | 17 | 18 |