diff --git a/.pylintrc b/.pylintrc new file mode 100644 index 0000000..7eb5e2c --- /dev/null +++ b/.pylintrc @@ -0,0 +1,4 @@ +# -*- mode: conf; -*- + +[MESSAGES CONTROL] +disable=fixme diff --git a/docs/index.rst b/docs/index.rst index c51685e..0effd08 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -19,6 +19,9 @@ It provides the following: .. _pyCOREPOS: https://pypi.org/project/pyCOREPOS/ +.. image:: https://img.shields.io/badge/linting-pylint-yellowgreen + :target: https://github.com/pylint-dev/pylint + .. image:: https://img.shields.io/badge/code%20style-black-000000.svg :target: https://github.com/psf/black diff --git a/pyproject.toml b/pyproject.toml index ba60abb..c252e30 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -36,7 +36,7 @@ dependencies = [ [project.optional-dependencies] web = ["WuttaWeb"] docs = ["Sphinx", "furo"] -tests = ["pytest-cov", "tox"] +tests = ["pylint", "pytest", "pytest-cov", "tox"] [project.entry-points."wutta.app.providers"] diff --git a/src/wutta_corepos/_version.py b/src/wutta_corepos/_version.py index dfdbb08..c78b835 100644 --- a/src/wutta_corepos/_version.py +++ b/src/wutta_corepos/_version.py @@ -1,4 +1,7 @@ # -*- coding: utf-8; -*- +""" +Package Version +""" from importlib.metadata import version diff --git a/src/wutta_corepos/app.py b/src/wutta_corepos/app.py index fdc310f..a937686 100644 --- a/src/wutta_corepos/app.py +++ b/src/wutta_corepos/app.py @@ -41,11 +41,11 @@ class WuttaCoreposAppProvider(AppProvider): :rtype: :class:`~wutta_corepos.handler.CoreposHandler` """ - if not hasattr(self, "corepos_handler"): + if "corepos" not in self.app.handlers: spec = self.config.get( f"{self.appname}.corepos_handler", default="wutta_corepos.handler:CoreposHandler", ) factory = self.app.load_object(spec) - self.corepos_handler = factory(self.config, **kwargs) - return self.corepos_handler + self.app.handlers["corepos"] = factory(self.config, **kwargs) + return self.app.handlers["corepos"] diff --git a/src/wutta_corepos/conf.py b/src/wutta_corepos/conf.py index 70add3c..2c2a309 100644 --- a/src/wutta_corepos/conf.py +++ b/src/wutta_corepos/conf.py @@ -106,53 +106,65 @@ class WuttaCoreposConfigExtension(WuttaConfigExtension): key = "wutta_corepos" - def configure(self, config): + def configure(self, config): # pylint: disable=empty-docstring """ """ # office_op - from corepos.db.office_op import Session + from corepos.db.office_op import ( # pylint: disable=import-outside-toplevel + Session as OfficeOpSession, + ) engines = get_engines(config, "corepos.db.office_op") config.core_office_op_engines = engines config.core_office_op_engine = engines.get("default") - Session.configure(bind=config.core_office_op_engine) + OfficeOpSession.configure(bind=config.core_office_op_engine) # office_trans - from corepos.db.office_trans import Session + from corepos.db.office_trans import ( # pylint: disable=import-outside-toplevel + Session as OfficeTransSession, + ) engines = get_engines(config, "corepos.db.office_trans") config.core_office_trans_engines = engines config.core_office_trans_engine = engines.get("default") - Session.configure(bind=config.core_office_trans_engine) + OfficeTransSession.configure(bind=config.core_office_trans_engine) # office_arch - from corepos.db.office_arch import Session + from corepos.db.office_arch import ( # pylint: disable=import-outside-toplevel + Session as OfficeArchSession, + ) engines = get_engines(config, "corepos.db.office_arch") config.core_office_arch_engines = engines config.core_office_arch_engine = engines.get("default") - Session.configure(bind=config.core_office_arch_engine) + OfficeArchSession.configure(bind=config.core_office_arch_engine) # lane_op - from corepos.db.lane_op import Session + from corepos.db.lane_op import ( # pylint: disable=import-outside-toplevel + Session as LaneOpSession, + ) engines = get_engines(config, "corepos.db.lane_op") config.core_lane_op_engines = engines config.core_lane_op_engine = engines.get("default") - Session.configure(bind=config.core_lane_op_engine) + LaneOpSession.configure(bind=config.core_lane_op_engine) # lane_trans - from corepos.db.lane_trans import Session + from corepos.db.lane_trans import ( # pylint: disable=import-outside-toplevel + Session as LaneTransSession, + ) engines = get_engines(config, "corepos.db.lane_trans") config.core_lane_trans_engines = engines config.core_lane_trans_engine = engines.get("default") - Session.configure(bind=config.core_lane_trans_engine) + LaneTransSession.configure(bind=config.core_lane_trans_engine) # define some schema columns "late" unless not supported if config.get_bool( "corepos.db.office_op.use_latest_columns", default=True, usedb=False ): - from corepos.db.office_op.model import use_latest_columns + from corepos.db.office_op.model import ( # pylint: disable=import-outside-toplevel + use_latest_columns, + ) use_latest_columns() diff --git a/src/wutta_corepos/db/model.py b/src/wutta_corepos/db/model.py index 6b1781b..9dba587 100644 --- a/src/wutta_corepos/db/model.py +++ b/src/wutta_corepos/db/model.py @@ -30,7 +30,7 @@ from sqlalchemy import orm from wuttjamaican.db import model -class CoreUser(model.Base): +class CoreUser(model.Base): # pylint: disable=too-few-public-methods """ CORE-POS extension for :class:`~wuttjamaican:wuttjamaican.db.model.auth.User`. diff --git a/src/wutta_corepos/handler.py b/src/wutta_corepos/handler.py index cfbae46..76f0ddc 100644 --- a/src/wutta_corepos/handler.py +++ b/src/wutta_corepos/handler.py @@ -38,7 +38,9 @@ class CoreposHandler(GenericHandler): Returns the :term:`data model` module for CORE Office 'op' DB, i.e. :mod:`pycorepos:corepos.db.office_op.model`. """ - from corepos.db.office_op import model + from corepos.db.office_op import ( # pylint: disable=import-outside-toplevel + model, + ) return model @@ -47,7 +49,9 @@ class CoreposHandler(GenericHandler): Returns the :term:`data model` module for CORE Office 'trans' DB, i.e. :mod:`pycorepos:corepos.db.office_trans.model`. """ - from corepos.db.office_trans import model + from corepos.db.office_trans import ( # pylint: disable=import-outside-toplevel + model, + ) return model @@ -56,7 +60,9 @@ class CoreposHandler(GenericHandler): Returns the :term:`data model` module for CORE Office 'arch' DB, i.e. :mod:`pycorepos:corepos.db.office_arch.model`. """ - from corepos.db.office_arch import model + from corepos.db.office_arch import ( # pylint: disable=import-outside-toplevel + model, + ) return model @@ -65,7 +71,7 @@ class CoreposHandler(GenericHandler): Returns the :term:`data model` module for CORE Lane 'op' DB, i.e. :mod:`pycorepos:corepos.db.lane_op.model`. """ - from corepos.db.lane_op import model + from corepos.db.lane_op import model # pylint: disable=import-outside-toplevel return model @@ -74,7 +80,9 @@ class CoreposHandler(GenericHandler): Returns the :term:`data model` module for CORE Lane 'trans' DB, i.e. :mod:`pycorepos:corepos.db.lane_trans.model`. """ - from corepos.db.lane_trans import model + from corepos.db.lane_trans import ( # pylint: disable=import-outside-toplevel + model, + ) return model @@ -85,7 +93,9 @@ class CoreposHandler(GenericHandler): :returns: Instance of :class:`pycorepos:corepos.db.office_op.Session`. """ - from corepos.db.office_op import Session + from corepos.db.office_op import ( # pylint: disable=import-outside-toplevel + Session, + ) if "bind" not in kwargs: kwargs["bind"] = self.config.core_office_op_engines[dbkey] @@ -98,7 +108,9 @@ class CoreposHandler(GenericHandler): :returns: Instance of :class:`pycorepos:corepos.db.office_trans.Session`. """ - from corepos.db.office_trans import Session + from corepos.db.office_trans import ( # pylint: disable=import-outside-toplevel + Session, + ) if "bind" not in kwargs: kwargs["bind"] = self.config.core_office_trans_engines[dbkey] @@ -111,7 +123,9 @@ class CoreposHandler(GenericHandler): :returns: Instance of :class:`pycorepos:corepos.db.office_arch.Session`. """ - from corepos.db.office_arch import Session + from corepos.db.office_arch import ( # pylint: disable=import-outside-toplevel + Session, + ) if "bind" not in kwargs: kwargs["bind"] = self.config.core_office_arch_engines[dbkey] @@ -124,7 +138,9 @@ class CoreposHandler(GenericHandler): :returns: Instance of :class:`pycorepos:corepos.db.lane_op.Session`. """ - from corepos.db.lane_op import Session + from corepos.db.lane_op import ( # pylint: disable=import-outside-toplevel + Session, + ) if "bind" not in kwargs: kwargs["bind"] = self.config.core_lane_op_engines[dbkey] @@ -137,7 +153,9 @@ class CoreposHandler(GenericHandler): :returns: Instance of :class:`pycorepos:corepos.db.lane_trans.Session`. """ - from corepos.db.lane_trans import Session + from corepos.db.lane_trans import ( # pylint: disable=import-outside-toplevel + Session, + ) if "bind" not in kwargs: kwargs["bind"] = self.config.core_lane_trans_engines[dbkey] @@ -157,6 +175,7 @@ class CoreposHandler(GenericHandler): url = self.config.get("corepos.office.url", require=require) if url: return url.rstrip("/") + return None def get_office_department_url(self, dept_id, office_url=None, require=False): """ @@ -175,6 +194,7 @@ class CoreposHandler(GenericHandler): office_url = self.get_office_url(require=require) if office_url: return f"{office_url}/item/departments/DepartmentEditor.php?did={dept_id}" + return None def get_office_employee_url(self, employee_id, office_url=None, require=False): """ @@ -193,6 +213,7 @@ class CoreposHandler(GenericHandler): office_url = self.get_office_url(require=require) if office_url: return f"{office_url}/admin/Cashiers/CashierEditor.php?emp_no={employee_id}" + return None def get_office_likecode_url(self, likecode_id, office_url=None, require=False): """ @@ -211,6 +232,7 @@ class CoreposHandler(GenericHandler): office_url = self.get_office_url(require=require) if office_url: return f"{office_url}/item/likecodes/LikeCodeEditor.php?start={likecode_id}" + return None def get_office_product_url(self, upc, office_url=None, require=False): """ @@ -229,6 +251,7 @@ class CoreposHandler(GenericHandler): office_url = self.get_office_url(require=require) if office_url: return f"{office_url}/item/ItemEditorPage.php?searchupc={upc}" + return None def get_office_vendor_url(self, vend_id, office_url=None, require=False): """ @@ -247,3 +270,4 @@ class CoreposHandler(GenericHandler): office_url = self.get_office_url(require=require) if office_url: return f"{office_url}/item/vendors/VendorIndexPage.php?vid={vend_id}" + return None diff --git a/src/wutta_corepos/web/__init__.py b/src/wutta_corepos/web/__init__.py index 27a88a5..d3a2ac9 100644 --- a/src/wutta_corepos/web/__init__.py +++ b/src/wutta_corepos/web/__init__.py @@ -25,5 +25,5 @@ Wutta-COREPOS -- wuttaweb features """ -def includeme(config): +def includeme(config): # pylint: disable=missing-function-docstring config.include("wutta_corepos.web.views") diff --git a/src/wutta_corepos/web/views/__init__.py b/src/wutta_corepos/web/views/__init__.py index 78797ab..c36452d 100644 --- a/src/wutta_corepos/web/views/__init__.py +++ b/src/wutta_corepos/web/views/__init__.py @@ -25,5 +25,5 @@ Wutta-COREPOS -- wuttaweb views """ -def includeme(config): +def includeme(config): # pylint: disable=missing-function-docstring config.include("wutta_corepos.web.views.corepos") diff --git a/src/wutta_corepos/web/views/corepos/__init__.py b/src/wutta_corepos/web/views/corepos/__init__.py index 436e8d5..fff81f8 100644 --- a/src/wutta_corepos/web/views/corepos/__init__.py +++ b/src/wutta_corepos/web/views/corepos/__init__.py @@ -27,6 +27,6 @@ Views for CORE-POS from .master import CoreOpMasterView -def includeme(config): +def includeme(config): # pylint: disable=missing-function-docstring config.include("wutta_corepos.web.views.corepos.members") config.include("wutta_corepos.web.views.corepos.products") diff --git a/src/wutta_corepos/web/views/corepos/master.py b/src/wutta_corepos/web/views/corepos/master.py index 92c7f9a..b0d9ab2 100644 --- a/src/wutta_corepos/web/views/corepos/master.py +++ b/src/wutta_corepos/web/views/corepos/master.py @@ -29,7 +29,7 @@ from wuttaweb.views import MasterView from wutta_corepos.web.db import CoreOpSession -class CoreOpMasterView(MasterView): +class CoreOpMasterView(MasterView): # pylint: disable=abstract-method """ Base class for master views which use the CORE Office 'op' DB. """ diff --git a/src/wutta_corepos/web/views/corepos/members.py b/src/wutta_corepos/web/views/corepos/members.py index ffa106c..ffaffd3 100644 --- a/src/wutta_corepos/web/views/corepos/members.py +++ b/src/wutta_corepos/web/views/corepos/members.py @@ -32,7 +32,7 @@ from corepos.db.office_op.model import MemberInfo from wutta_corepos.web.views.corepos import CoreOpMasterView -class MemberView(CoreOpMasterView): +class MemberView(CoreOpMasterView): # pylint: disable=abstract-method """ Master view for :class:`~pycorepos:corepos.db.office_op.model.MemberInfo`; route @@ -74,7 +74,7 @@ class MemberView(CoreOpMasterView): sort_defaults = "card_number" - def get_query(self, session=None): + def get_query(self, session=None): # pylint: disable=empty-docstring """ """ query = super().get_query(session=session) @@ -89,8 +89,9 @@ class MemberView(CoreOpMasterView): return query - def configure_grid(self, g): + def configure_grid(self, grid): # pylint: disable=empty-docstring """ """ + g = grid super().configure_grid(g) op_model = self.corepos_handler.get_model_office_op() @@ -108,18 +109,22 @@ class MemberView(CoreOpMasterView): g.set_link("first_name") g.set_link("last_name") - def render_customer_attr(self, member, key, value): + def render_customer_attr( # pylint: disable=unused-argument,empty-docstring + self, member, key, value + ): """ """ customer = member.customers[0] return getattr(customer, key) -def defaults(config, **kwargs): +def defaults(config, **kwargs): # pylint: disable=missing-function-docstring base = globals() - MemberView = kwargs.get("MemberView", base["MemberView"]) + MemberView = kwargs.get( # pylint: disable=invalid-name,redefined-outer-name + "MemberView", base["MemberView"] + ) MemberView.defaults(config) -def includeme(config): +def includeme(config): # pylint: disable=missing-function-docstring defaults(config) diff --git a/src/wutta_corepos/web/views/corepos/products.py b/src/wutta_corepos/web/views/corepos/products.py index 24e94af..19b016d 100644 --- a/src/wutta_corepos/web/views/corepos/products.py +++ b/src/wutta_corepos/web/views/corepos/products.py @@ -29,7 +29,7 @@ from corepos.db.office_op.model import Product from wutta_corepos.web.views.corepos import CoreOpMasterView -class ProductView(CoreOpMasterView): +class ProductView(CoreOpMasterView): # pylint: disable=abstract-method """ Master view for :class:`~pycorepos:corepos.db.office_op.model.Product`; route @@ -73,8 +73,9 @@ class ProductView(CoreOpMasterView): sort_defaults = "upc" - def configure_grid(self, g): + def configure_grid(self, grid): # pylint: disable=empty-docstring """ """ + g = grid super().configure_grid(g) # normal_price @@ -87,12 +88,14 @@ class ProductView(CoreOpMasterView): g.set_link("size") -def defaults(config, **kwargs): +def defaults(config, **kwargs): # pylint: disable=missing-function-docstring base = globals() - ProductView = kwargs.get("ProductView", base["ProductView"]) + ProductView = kwargs.get( # pylint: disable=invalid-name,redefined-outer-name + "ProductView", base["ProductView"] + ) ProductView.defaults(config) -def includeme(config): +def includeme(config): # pylint: disable=missing-function-docstring defaults(config) diff --git a/tox.ini b/tox.ini index 49b89cb..20021b1 100644 --- a/tox.ini +++ b/tox.ini @@ -6,6 +6,10 @@ envlist = py38, py39, py310, py311 extras = web,tests commands = pytest {posargs} +[testenv:pylint] +basepython = python3.11 +commands = pylint wutta_corepos + [testenv:coverage] basepython = python3.11 commands = pytest --cov=wutta_corepos --cov-report=html --cov-fail-under=100