diff --git a/.github/workflows/lint-python.yml b/.github/workflows/lint-python.yml index 548038f1..bef1e6d0 100644 --- a/.github/workflows/lint-python.yml +++ b/.github/workflows/lint-python.yml @@ -1,21 +1,41 @@ name: lint_python on: [pull_request, push] jobs: - lint_python: + lint-python: runs-on: ubuntu-latest + strategy: + matrix: + python-version: [3.7, 3.8, 3.9, "3.10", "3.11"] + steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 - - run: pip install bandit black codespell flake8 isort mypy pytest pyupgrade safety - - run: bandit --recursive --skip B101,B105,B106,B110,B303,B404,B603 . - - run: black --check . || true - - run: codespell || true # --ignore-words-list="" --skip="" - - run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics - - run: flake8 . --count --exit-zero --max-complexity=29 --max-line-length=167 --show-source --statistics - - run: isort --check-only --profile black . - - run: pip install -e . - - run: mypy --ignore-missing-imports . || true - - run: mv setup.cfg setup.cfg.disabled - - run: pytest . - - run: shopt -s globstar && pyupgrade --py36-plus **/*.py || true - - run: safety check + - uses: actions/checkout@v3 + - name: Set up Python ${{ matrix.python-version }} + uses: actions/setup-python@v4 + with: + python-version: ${{ matrix.python-version }} + - name: Install deploy dependencies + run: pip install .[deploy] + - name: Install test dependencies + run: pip install .[test] + - name: Install code dependencies + run: pip install . + - name: Security vulnerability analysis with bandit + run: bandit -c pyproject.toml -r . + - name: Format with black + run: black --check . || true + - name: Check spelling + run: codespell || true + - name: Lint with flake8 + run: flake8 . --count --select=E9,F63,F7,F82 --show-source --statistics + - name: Lint again with flake8 + run: flake8 . --count --exit-zero --max-complexity=29 --max-line-length=167 --show-source --statistics + - name: Sort imports + run: isort --check-only . + - name: Lint again with mypy + run: mypy . || true + - name: Test with pytest + run: pytest . + - name: Shopt + run: shopt -s globstar && pyupgrade --py37-plus **/*.py || true + - name: Security check with safety + run: safety check diff --git a/.github/workflows/tox.yml b/.github/workflows/tox.yml index 37186bf5..2d35155a 100644 --- a/.github/workflows/tox.yml +++ b/.github/workflows/tox.yml @@ -6,16 +6,14 @@ jobs: fail-fast: false max-parallel: 4 matrix: - python: [3.6, 3.7, 3.8, 3.9] + python: [3.7, 3.8, 3.9] runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - uses: actions/setup-python@v2 + - uses: actions/checkout@v3 + - uses: actions/setup-python@v4 with: python-version: ${{ matrix.python }} - run: pip install tox - - if: matrix.python == '3.6' - run: TOXENV=py36 tox - if: matrix.python == '3.7' run: TOXENV=py37 tox - if: matrix.python == '3.8' diff --git a/.gitignore b/.gitignore index 84665a27..ddfcd10b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,6 @@ +# Dropbox marker +.DS_Store + # Byte-compiled / optimized / DLL files __pycache__/ *.py[cod] diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 00000000..b5df5fb0 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,10 @@ +{ + "python.testing.pytestEnabled": true, + "python.testing.unittestEnabled": false, + "python.formatting.provider": "black", + "python.defaultInterpreterPath": "python3", + "editor.formatOnSave": false, + "modulename": "paho_mqtt", + "distname": "${workspaceFolderBasename}", + "moduleversion": "1.6.1" +} diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 00000000..7c4f3e00 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,199 @@ +{ + // See https://go.microsoft.com/fwlink/?LinkId=733558 + // for the documentation about the tasks.json format + // Use the Install Build/Test Dependencies tasks to install the Python toolchain. + "version": "2.0.0", + "tasks": [ + { + "label": "Install Deploy Dependencies", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pip", + "install", + "--upgrade", + ".[deploy]" + ], + "problemMatcher": [] + }, + { + "label": "Install Test Dependencies", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pip", + "install", + "--upgrade", + ".[test]" + ], + "problemMatcher": [] + }, + { + "label": "Install Code Dependencies", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pip", + "install", + "--upgrade", + "." + ], + "problemMatcher": [] + }, + { + "label": "Clean", + "type": "shell", + "command": "rm", + "args": [ + "-rfvd", + "build", + "dist", + "htmlcov", + "docs/_build", + "src/${config:modulename}.egg-info", + ], + "windows": { + "command": "Get-ChildItem", + "args": [ + "-Path", + "build\\,", + "dist\\,", + "htmlcov\\,", + "docs\\_build,", + "src\\${config:modulename}.egg-info", + "-Recurse", + "|", + "Remove-Item", + "-Recurse", + "-Confirm:$false", + "-Force", + ], + }, + "options": { + "cwd": "${workspaceFolder}" + }, + "problemMatcher": [] + }, + { + "label": "Bandit", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "bandit", + "-c", + "pyproject.toml", + "-r", + "." + ], + "problemMatcher": [] + }, + { + "label": "iSort", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "isort", + "." + ], + "problemMatcher": [] + }, + { + "label": "Codespell", + "type": "process", + "command": "codespell", + "args": [ + "--toml", + "pyproject.toml", + "src" + ], + "problemMatcher": [] + }, + { + "label": "Pylint", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pylint", + "--reports=y", + "src" + ], + "problemMatcher": [] + }, + { + "label": "Pyflakes", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pyflakes", + "src" + ], + "problemMatcher": [] + }, + { + "label": "Pylama", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pylama", + "src", + ], + "problemMatcher": [] + }, + { + "label": "Build", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "build", + ".", + "--wheel", + "--sdist", + ], + "problemMatcher": [] + }, + { + "label": "Test", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pytest" + ], + "problemMatcher": [] + }, + { + "label": "Install Locally", + "type": "process", + "command": "${config:python.defaultInterpreterPath}", + "args": [ + "-m", + "pip", + "install", + "${workspaceFolder}/dist/paho-mqtt-${config:moduleversion}.tar.gz", + "--force-reinstall" + ], + "dependsOrder": "sequence", + "dependsOn": [ + "Clean", + "Install Deploy Dependencies", + "Install Test Dependencies", + "Install Code Dependencies", + "iSort", + "Pylint", + "Bandit", + //"Test", + "Build", + ], + "problemMatcher": [] + }, + ] +} diff --git a/MANIFEST.in b/MANIFEST.in index 2e8e0978..709ef093 100644 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,10 +1,12 @@ -include edl-v10 epl-v10 +include edl-v10 +include epl-v20 include README.rst include CONTRIBUTING.md -include setup.py include notice.html include LICENSE.txt include about.html recursive-include src *.py recursive-include examples *.py +global-exclude __pycache__ +global-exclude *.pyc diff --git a/README.rst b/README.rst index e66ffbb2..92ec9a17 100644 --- a/README.rst +++ b/README.rst @@ -5,7 +5,7 @@ This document describes the source code for the `Eclipse Paho `_ broker to publish messages, and to subscribe to topics and receive published messages. It also provides some helper functions to make publishing one off messages to an MQTT server very straightforward. -It supports Python 2.7.9+ or 3.6+. +It supports Python 3.7+. The MQTT protocol is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. Designed as an extremely lightweight publish/subscribe messaging transport, it is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium. diff --git a/Vagrantfile b/Vagrantfile index ab8124e6..a4e616cc 100644 --- a/Vagrantfile +++ b/Vagrantfile @@ -1,17 +1,11 @@ Vagrant.configure("2") do |config| # The base OS - config.vm.box = "ubuntu/trusty64" + config.vm.box = "ubuntu/bionic64" config.vm.provision :shell, :inline => "sudo apt-get update" # Install make config.vm.provision :shell, :inline => "apt-get install -y make" - # Provision Python 2 - config.vm.provision :shell, :inline => "apt-get upgrade -y python" - config.vm.provision :shell, :inline => "apt-get install -y python-pip" - config.vm.provision :shell, :inline => "python -m pip install --upgrade pip" - config.vm.provision :shell, :inline => "python -m pip install virtualenv" - # Provision Python 3 config.vm.provision :shell, :inline => "apt-get install -y python3" config.vm.provision :shell, :inline => "apt-get install -y python3-pip" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..6320122c --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,126 @@ +[build-system] +requires = ["setuptools>=66.0", "wheel"] +build-backend = "setuptools.build_meta:__legacy__" + +[project] +name = "paho-mqtt" +authors = [ + {name = "Roger Light", email = "roger@atchoo.org"}, +] +maintainers = [ + {name = "Roger Light", email = "roger@atchoo.org"} +] +description = "MQTT version 5.0/3.1.1 client class" +version = "1.6.1" +readme = "README.rst" +license = {file = "LICENSE.txt"} +requires-python = ">=3.7" +classifiers = [ + 'Development Status :: 4 - Beta', + 'Intended Audience :: Developers', + 'License :: OSI Approved :: Eclipse Public License 2.0 (EPL-2.0)', + 'Operating System :: MacOS :: MacOS X', + 'Operating System :: Microsoft :: Windows', + 'Operating System :: POSIX', + 'Natural Language :: English', + 'Programming Language :: Python', + 'Programming Language :: Python :: 3', + 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.8', + 'Programming Language :: Python :: 3.9', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Topic :: Communications', + 'Topic :: Internet', +] + +dependencies = [ +] + +[project.urls] +homepage = "http://eclipse.org/paho" +documentation = "https://www.eclipse.org/paho/index.php?page=documentation.php" +repository = "https://github.com/eclipse/paho.mqtt.python" +changelog = "https://github.com/eclipse/paho.mqtt.python/blob/master/ChangeLog.txt" + +[project.optional-dependencies] +proxy = [ + "PySocks>=1.7", +] +deploy = [ + "build >= 0.10", + "pip >= 23.0", + "setuptools >= 66.0", + "wheel >= 0.40", +] +test = [ + 'bandit', + 'black', + 'codespell', + 'flake8', + 'isort', + 'mock', + 'mypy', + 'ptr', + 'pylama', + 'pytest', + 'safety', + 'six', + 'tox', +] + +[tool.codespell] +count = '' +quiet-level = 3 + +[tool.isort] +py_version=37 +profile = "black" +src_paths = ["src"] + +[tool.black] +line-length = 167 +target-version = ['py37'] + +[tool.bandit] +exclude_dirs = ["docs", "examples", "tests"] +skips = ["B101","B105","B106","B110","B303","B324","B404","B603"] + +[tool.mypy] +ignore-missing-imports = "" + +[tool.pylama] +format = "pylint" +skip = "*/.tox/*,*/.env/*" +linters = "pylint,mccabe" +ignore = "C0103" + +[tool.pylama.linter.pyflakes] +builtins = "_" + +[tool.pylama.linter.pylint] +max_line_length = 167 +disable = "R" +exit-zero = "" + +[tool.pylint] +exit-zero = "" +py-version = "3.7" +disable = """ + raw-checker-failed, + bad-inline-option, + locally-disabled, + file-ignored, + suppressed-message, + useless-suppression, + deprecated-pragma, + use-symbolic-message-instead, +""" + +[tool.pytest.ini_options] +minversion = "7.0" +pythonpath = ["src"] +testpaths = [ + "test", + "tests", +] diff --git a/setup.cfg b/redundant/setup.cfg similarity index 100% rename from setup.cfg rename to redundant/setup.cfg diff --git a/setup.py b/redundant/setup.py similarity index 100% rename from setup.py rename to redundant/setup.py diff --git a/tox.ini b/redundant/tox.ini similarity index 94% rename from tox.ini rename to redundant/tox.ini index f5e39787..49f0a606 100644 --- a/tox.ini +++ b/redundant/tox.ini @@ -1,5 +1,5 @@ [tox] -envlist = py{27,35,36,37,38,39} +envlist = py{37,38,39,310,311} [testenv:py27] setenv = EXCLUDE = --exclude=./.*,./examples/loop_asyncio.py,*/MQTTV5.py,*/MQTTV311.py diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index bd0dd2ba..00000000 --- a/requirements.txt +++ /dev/null @@ -1,6 +0,0 @@ -mock==3.0.5 -pylama==7.7.1 -pytest==4.6.6; python_version < '3.0' -pytest==5.2.2; python_version >= '3.0' -pytest-runner==5.2 -tox==3.14.0