uncommitted - siphashc

Ready changes

Summary

Import uploads missing from VCS:

Diff

diff --git a/.github/.kodiak.toml b/.github/.kodiak.toml
new file mode 100644
index 0000000..a964fb2
--- /dev/null
+++ b/.github/.kodiak.toml
@@ -0,0 +1,9 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+# Configuration for https://kodiakhq.com/
+version = 1
+
+[merge]
+method = "rebase"
+
+[update]
+ignored_usernames = ["dependabot", "weblate"]
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000..daf8beb
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1,4 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+github: [nijel]
+custom: https://weblate.org/donate/
+liberapay: Weblate
diff --git a/.github/dependabot.yml b/.github/dependabot.yml
new file mode 100644
index 0000000..6cdf350
--- /dev/null
+++ b/.github/dependabot.yml
@@ -0,0 +1,17 @@
+# This file is generated in https://github.com/WeblateOrg/meta/
+version: 2
+updates:
+  - package-ecosystem: github-actions
+    directory: /
+    schedule:
+      interval: daily
+    labels:
+      - dependencies
+      - automerge
+  - package-ecosystem: pip
+    directory: /
+    schedule:
+      interval: daily
+    labels:
+      - dependencies
+      - automerge
diff --git a/.github/labels.yml b/.github/labels.yml
new file mode 100644
index 0000000..2fbc5d7
--- /dev/null
+++ b/.github/labels.yml
@@ -0,0 +1,68 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+
+# Default GitHub labels
+- color: d73a4a
+  name: bug
+  description: Something isn't working
+- color: cfd3d7
+  name: duplicate
+  description: This issue or pull request already exists
+- color: a2eeef
+  name: enhancement
+  description: New feature or request
+- color: 7057ff
+  name: good first issue
+  description: Good for newcomers
+- color: 008672
+  name: help wanted
+  description: Extra attention is needed
+- color: e4e669
+  name: invalid
+  description: This doesn't seem right
+- color: d876e3
+  name: question
+  description: Support question
+- color: ffffff
+  name: wontfix
+  description: This will not be worked on
+# Bountysource
+- color: 129e5e
+  name: bounty
+  description: There is a bounty on the issue
+# Dependabot
+- color: 0025ff
+  name: dependencies
+  description: Pull requests that update a dependency file
+# Kodiaq
+- color: 000000
+  name: automerge
+  description: Automatically merge pull request once tests pass
+# Hacktoberfest
+- color: 129e5e
+  name: hacktoberfest
+  description: This is good for Hacktoberfest
+# Weblate specific
+- color: 87a2f2
+  name: backlog
+  description: This is currently not on the roadmap
+- color: 0075ca
+  name: documentation
+  description: Improvements or additions to documentation
+- color: d4c5f9
+  name: hosted
+  description: Issues affecting Hosted Weblate service
+- color: e3f49c
+  name: naming
+  description: Discussions about naming certain features
+- color: fef2c0
+  name: translate-toolkit
+  description: Issues which need to be fixed in the translate-toolkit
+- color: 02d7e1
+  name: undecided
+  description: These features might not be implemented at all
+- color: e3f49c
+  name: ux
+  description: User experience issues
+- color: b38ddd
+  name: needinfo
+  description: This needs additional information from the reporter
diff --git a/.github/matchers/flake8.json b/.github/matchers/flake8.json
new file mode 100644
index 0000000..ba849ac
--- /dev/null
+++ b/.github/matchers/flake8.json
@@ -0,0 +1,17 @@
+{
+  "problemMatcher": [
+    {
+      "owner": "flake8",
+      "pattern": [
+        {
+          "code": 4,
+          "column": 3,
+          "file": 1,
+          "line": 2,
+          "message": 5,
+          "regexp": "^([^:]*):(\\d+):(\\d+): (\\w+\\d\\d\\d) (.*)$"
+        }
+      ]
+    }
+  ]
+}
diff --git a/.github/stale.yml b/.github/stale.yml
index 5e5c048..f004417 100644
--- a/.github/stale.yml
+++ b/.github/stale.yml
@@ -1,7 +1,9 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+#
 # Configuration for probot-stale - https://github.com/probot/stale
 
 # Number of days of inactivity before an Issue or Pull Request becomes stale
-daysUntilStale: 60
+daysUntilStale: 30
 # Number of days of inactivity before a stale Issue or Pull Request is closed
 daysUntilClose: 14
 # Issues or Pull Requests with these labels will never be considered stale. Set to `[]` to disable
@@ -29,8 +31,8 @@ pulls:
     recent activity. It will be closed if no further activity occurs. Thank you
     for your contributions.
 issues:
-  daysUntilStale: 14
-  daysUntilClose: 7
+  daysUntilStale: 10
+  daysUntilClose: 4
   exemptLabels:
     - bug
     - enhancement
diff --git a/.github/workflows/closing.yml b/.github/workflows/closing.yml
new file mode 100644
index 0000000..7cdb75e
--- /dev/null
+++ b/.github/workflows/closing.yml
@@ -0,0 +1,34 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+name: Issue closed
+
+on:
+  issues:
+    types: [closed]
+
+jobs:
+  issueClosed:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Add closed question comment
+        uses: peter-evans/create-or-update-comment@v1
+        if: (contains(github.event.issue.labels.*.name, 'question') && ! contains(github.event.issue.labels.*.name, 'wontfix')) || join(github.event.issue.labels.*.name) == ''
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          issue-number: ${{ github.event.issue.number }}
+          body: |
+            The issue you have reported seems to be resolved now.
+
+            * In case you see a similar problem, please open a separate issue.
+            * If you are happy with the outcome, consider supporting Weblate by [donating](https://weblate.org/donate/).
+      - name: Add closed issue comment
+        uses: peter-evans/create-or-update-comment@v1
+        if: "! contains(github.event.issue.labels.*.name, 'invalid') && ! contains(github.event.issue.labels.*.name, 'question') && ! contains(github.event.issue.labels.*.name, 'wontfix') && ! contains(github.event.issue.labels.*.name, 'duplicate') && ! contains(github.event.issue.labels.*.name, 'undecided') && ! contains(github.event.issue.labels.*.name, 'needinfo') && join(github.event.issue.labels.*.name) != ''"
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          issue-number: ${{ github.event.issue.number }}
+          body: |
+            Thank you for your report, the issue you have reported has just been fixed.
+
+            * In case you see a problem with the fix, please comment on this issue.
+            * In case you see a similar problem, please open a separate issue.
+            * If you are happy with the outcome, consider supporting Weblate by [donating](https://weblate.org/donate/).
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
new file mode 100644
index 0000000..1bf153a
--- /dev/null
+++ b/.github/workflows/codeql-analysis.yml
@@ -0,0 +1,53 @@
+name: "CodeQL"
+
+on:
+  push:
+    branches: [master]
+  pull_request:
+    # The branches below must be a subset of the branches above
+    branches: [master]
+  schedule:
+    - cron: "0 19 * * 0"
+
+jobs:
+  analyze:
+    name: Analyze
+    runs-on: ubuntu-latest
+
+    strategy:
+      fail-fast: false
+      matrix:
+        # Override automatic language detection by changing the below list
+        # Supported options are ['csharp', 'cpp', 'go', 'java', 'javascript', 'python']
+        language: ["cpp", "python"]
+        # Learn more...
+        # https://docs.github.com/en/github/finding-security-vulnerabilities-and-errors-in-your-code/configuring-code-scanning#overriding-automatic-language-detection
+
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v2
+        with:
+          # We must fetch at least the immediate parents so that if this is
+          # a pull request then we can checkout the head.
+          fetch-depth: 2
+
+      # If this run was triggered by a pull request event, then checkout
+      # the head of the pull request instead of the merge commit.
+      - run: git checkout HEAD^2
+        if: ${{ github.event_name == 'pull_request' }}
+
+      # Initializes the CodeQL tools for scanning.
+      - name: Initialize CodeQL
+        uses: github/codeql-action/init@v1
+        with:
+          languages: ${{ matrix.language }}
+
+      - name: Set up Python
+        uses: actions/setup-python@v2.1.2
+        with:
+          python-version: 3.8
+
+      - run: python setup.py build
+
+      - name: Perform CodeQL Analysis
+        uses: github/codeql-action/analyze@v1
diff --git a/.github/workflows/flake8.yml b/.github/workflows/flake8.yml
new file mode 100644
index 0000000..c78af6b
--- /dev/null
+++ b/.github/workflows/flake8.yml
@@ -0,0 +1,34 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+name: Flake8
+
+on:
+  push:
+    branches-ignore:
+      - "dependabot/**"
+  pull_request:
+
+jobs:
+  flake8:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/cache@v2.1.1
+        with:
+          path: |
+            ~/.cache/pip
+            ~/.cache/pre-commit
+          key: ${{ runner.os }}-pip-lint-${{ hashFiles('**/requirements*.txt') }}-${{ hashFiles('.pre-commit-config.yaml') }}
+      - name: Setup Python
+        uses: actions/setup-python@v2.1.2
+        with:
+          python-version: 3.8
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip wheel
+          pip install -r requirements-lint.txt
+      - name: Run flake8
+        run: |
+          echo "::add-matcher::.github/matchers/flake8.json"
+          pre-commit run flake8 --all
+          echo "::remove-matcher owner=flake8::"
diff --git a/.github/workflows/label-sync.yml b/.github/workflows/label-sync.yml
new file mode 100644
index 0000000..3e929f4
--- /dev/null
+++ b/.github/workflows/label-sync.yml
@@ -0,0 +1,21 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+name: Sync labels
+on:
+  push:
+    branches:
+      - master
+    paths:
+      - .github/labels.yml
+      - .github/workflows/label-sync.yml
+jobs:
+  build:
+    name: Sync labels
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2.3.1
+      - uses: micnncim/action-label-syncer@v1
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+          GITHUB_REPOSITORY: ${{ github.repository }}
+        with:
+          manifest: .github/labels.yml
diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml
new file mode 100644
index 0000000..ad3da5c
--- /dev/null
+++ b/.github/workflows/labels.yml
@@ -0,0 +1,43 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+name: Issue labeled
+
+on:
+  issues:
+    types: [labeled]
+
+jobs:
+  issueLabeled:
+    runs-on: ubuntu-latest
+    steps:
+      - name: Add backlog comment
+        uses: peter-evans/create-or-update-comment@v1
+        if: github.event.label.name == 'backlog'
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          issue-number: ${{ github.event.issue.number }}
+          body: |
+            This issue has been added to the backlog. It is not scheduled on our roadmap, but it eventually might be implemented. In case you desperately need this feature, please consider helping or [funding the development](https://weblate.org/support/).
+      - name: Add undecided comment
+        uses: peter-evans/create-or-update-comment@v1
+        if: github.event.label.name == 'undecided'
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          issue-number: ${{ github.event.issue.number }}
+          body: |
+            This issue has been put aside. Currently, it is unclear whether it will ever be implemented as it seems to cover too narrow of a use case or doesn't seem to fit into Weblate. Please try to clarify the use case or consider proposing something more generic to make it useful to more users.
+      - name: Add question comment
+        uses: peter-evans/create-or-update-comment@v1
+        if: github.event.label.name == 'question'
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          issue-number: ${{ github.event.issue.number }}
+          body: |
+            This issue looks like a support question. We try to answer these reasonably fast, but in case you are looking for faster resolution, please consider [purchasing support subscription](https://weblate.org/support/) and make Weblate stronger.
+      - name: Add translate-toolkit comment
+        uses: peter-evans/create-or-update-comment@v1
+        if: github.event.label.name == 'translate-toolkit'
+        with:
+          token: ${{ secrets.GITHUB_TOKEN }}
+          issue-number: ${{ github.event.issue.number }}
+          body: |
+            The issue you've reported needs to be addressed in the [translate-toolkit](https://github.com/translate/translate/). Please file the issue there and do not forget to include links to any relevant specifications about the formats (if applicable).
diff --git a/.github/workflows/pre-commit.yml b/.github/workflows/pre-commit.yml
new file mode 100644
index 0000000..a6c4205
--- /dev/null
+++ b/.github/workflows/pre-commit.yml
@@ -0,0 +1,31 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+name: Pre-commit check
+
+on:
+  push:
+    branches-ignore:
+      - "dependabot/**"
+  pull_request:
+
+jobs:
+  pre-commit:
+    runs-on: ubuntu-latest
+
+    steps:
+      - uses: actions/checkout@v2.3.1
+      - uses: actions/cache@v2.1.1
+        with:
+          path: |
+            ~/.cache/pip
+            ~/.cache/pre-commit
+          key: ${{ runner.os }}-pre-commit-${{ hashFiles('**/requirements*.txt') }}-${{ hashFiles('.pre-commit-config.yaml') }}
+      - name: Setup Python
+        uses: actions/setup-python@v2.1.2
+        with:
+          python-version: 3.8
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip wheel
+          pip install -r requirements-lint.txt
+      - name: pre-commit
+        run: pre-commit run --all
diff --git a/.github/workflows/pull_requests.yaml b/.github/workflows/pull_requests.yaml
new file mode 100644
index 0000000..2935edd
--- /dev/null
+++ b/.github/workflows/pull_requests.yaml
@@ -0,0 +1,18 @@
+# This file is maintained in https://github.com/WeblateOrg/meta/
+
+name: Pull request automation
+
+on:
+  pull_request:
+    types: opened
+
+jobs:
+  weblate_automerge:
+    runs-on: ubuntu-latest
+    name: Weblate automerge
+    if: github.actor == 'weblate'
+    steps:
+      - uses: actions-ecosystem/action-add-labels@v1
+        with:
+          github_token: ${{ secrets.GITHUB_TOKEN }}
+          labels: automerge
diff --git a/.github/workflows/pythonpackage.yml b/.github/workflows/pythonpackage.yml
new file mode 100644
index 0000000..d7d6436
--- /dev/null
+++ b/.github/workflows/pythonpackage.yml
@@ -0,0 +1,30 @@
+name: Python package
+
+on:
+  push:
+    branches-ignore:
+      - "dependabot/**"
+  pull_request:
+
+jobs:
+  build:
+    runs-on: ubuntu-latest
+    strategy:
+      matrix:
+        python-version: [3.5, 3.6, 3.7, 3.8]
+
+    steps:
+      - uses: actions/checkout@v2.3.1
+      - name: Set up Python ${{ matrix.python-version }}
+        uses: actions/setup-python@v2.1.2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Compile
+        run: |
+          CFLAGS="-Wall -Wextra -Wno-unused-parameter" python setup.py build
+      - name: Test
+        run: |
+          python -W default setup.py test
+      - name: Benchmark
+        run: |
+          python benchmark.py
diff --git a/.github/workflows/setup.yml b/.github/workflows/setup.yml
new file mode 100644
index 0000000..002a2f0
--- /dev/null
+++ b/.github/workflows/setup.yml
@@ -0,0 +1,70 @@
+name: Distribution
+
+on: [push, pull_request]
+
+jobs:
+  manylinux:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/cache@v2.1.1
+        with:
+          path: ~/.cache/pip
+          key: ${{ runner.os }}-pip-setup-${{ hashFiles('**/requirements*.txt') }}
+      - name: Set up Python
+        uses: actions/setup-python@v2.1.2
+        with:
+          python-version: 3.8
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip wheel
+          pip install twine
+      - uses: RalfG/python-wheels-manylinux-build@v0.3.1
+        with:
+          python-versions: "cp35-cp35m cp36-cp36m cp37-cp37m cp38-cp38"
+      - name: twine
+        run: twine check dist/*
+      - name: Publish package
+        if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags')
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.pypi_password }}
+        run: twine upload --skip-existing dist/*-manylinux*.whl
+
+  native:
+    runs-on: ${{ matrix.os }}
+    strategy:
+      matrix:
+        os: [macos-latest, windows-latest, ubuntu-latest]
+        python-version: [3.5, 3.6, 3.7, 3.8]
+
+    steps:
+      - uses: actions/checkout@v2
+      - uses: actions/cache@v2.1.1
+        with:
+          path: ~/.cache/pip
+          key: ${{ runner.os }}-pip-setup-${{ hashFiles('**/requirements*.txt') }}
+      - name: Set up Python ${{ matrix.python-version }}
+        uses: actions/setup-python@v2.1.2
+        with:
+          python-version: ${{ matrix.python-version }}
+      - name: Install dependencies
+        run: |
+          python -m pip install --upgrade pip wheel
+          pip install twine
+      - name: build
+        run: python ./setup.py sdist bdist_wheel
+      - name: twine
+        run: twine check dist/*
+      - name: Publish wheel
+        if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') && matrix.os != 'ubuntu-latest'
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.pypi_password }}
+        run: twine upload --skip-existing dist/*.whl
+      - name: Publish source
+        if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags') && matrix.os == 'ubuntu-latest'
+        env:
+          TWINE_USERNAME: __token__
+          TWINE_PASSWORD: ${{ secrets.pypi_password }}
+        run: twine upload --skip-existing dist/*.tar.gz
diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml
new file mode 100644
index 0000000..0a5587e
--- /dev/null
+++ b/.pre-commit-config.yaml
@@ -0,0 +1,55 @@
+# See https://pre-commit.com for more information
+# See https://pre-commit.com/hooks.html for more hooks
+repos:
+  - repo: https://github.com/pre-commit/mirrors-isort
+    rev: v5.4.2
+    hooks:
+      - id: isort
+  - repo: https://github.com/ambv/black
+    rev: 20.8b1
+    hooks:
+      - id: black
+  - repo: https://gitlab.com/pycqa/flake8
+    rev: 3.8.3
+    hooks:
+      - id: flake8
+        additional_dependencies:
+          - flake8-breakpoint
+          - flake8-black
+          - flake8-bugbear
+          - flake8-builtins
+          - flake8-comprehensions
+          - flake8-docstrings
+          - flake8-eradicate
+          - flake8-executable
+          - flake8-isort
+          - flake8-logging-format
+          - flake8-mutable
+          - flake8-no-u-prefixed-strings
+          - flake8-print
+          - flake8-return
+          - flake8-self
+          - flake8-string-format
+          - pep8-naming
+  - repo: https://github.com/pre-commit/pre-commit-hooks
+    rev: v3.2.0
+    hooks:
+      - id: trailing-whitespace
+      - id: end-of-file-fixer
+      - id: check-yaml
+      - id: requirements-txt-fixer
+      - id: check-merge-conflict
+      - id: mixed-line-ending
+        args: [--fix=lf]
+  - repo: https://github.com/adrienverge/yamllint
+    rev: v1.24.2
+    hooks:
+      - id: yamllint
+  - repo: meta
+    hooks:
+      - id: check-hooks-apply
+      - id: check-useless-excludes
+  - repo: https://github.com/prettier/prettier
+    rev: 2.1.1
+    hooks:
+      - id: prettier
diff --git a/.travis.yml b/.travis.yml
deleted file mode 100644
index 1c23b68..0000000
--- a/.travis.yml
+++ /dev/null
@@ -1,20 +0,0 @@
-dist: trusty
-sudo: false
-language: python
-python:
-    - "2.7"
-    - "3.3"
-    - "3.4"
-    - "3.5"
-    - "3.6"
-matrix:
-  include:
-    - os: osx
-      language: generic
-    - python: 3.7
-      dist: xenial
-      sudo: true
-script:
-    - CFLAGS="-Wall -Wextra -Wno-unused-parameter" python setup.py build
-    - python setup.py test
-    - python benchmark.py
diff --git a/.yamllint.yml b/.yamllint.yml
new file mode 100644
index 0000000..beb48ac
--- /dev/null
+++ b/.yamllint.yml
@@ -0,0 +1,7 @@
+extends: default
+
+rules:
+  line-length:
+    max: 500
+    level: error
+  document-start: disable
diff --git a/CHANGES.rst b/CHANGES.rst
index 600ff40..1c07122 100644
--- a/CHANGES.rst
+++ b/CHANGES.rst
@@ -1,6 +1,22 @@
 Changes
 =======
 
+2.1
+---
+
+* Fixed publishing wheels in pypi.org.
+
+2.0
+---
+
+* Dropped support for Python 2.
+
+1.3
+---
+
+* Changed license to ISC.
+* Fixed depreciation warning on Python 3.8.
+
 1.2
 ---
 
diff --git a/LICENSE.md b/LICENSE.md
index 5135285..670022b 100644
--- a/LICENSE.md
+++ b/LICENSE.md
@@ -2,22 +2,16 @@ Copyright (c) 2013 Eli Janssen
 
 Copyright (c) 2014 Carlo Pires (python3 support)
 
-Copyright (c) 2017 Michal Čihař (additional cleanups)
+Copyright (c) 2017 - 2019 Michal Čihař (additional cleanups)
 
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
-of the Software, and to permit persons to whom the Software is furnished to do
-so, subject to the following conditions:
+Permission to use, copy, modify, and/or distribute this software for any
+purpose with or without fee is hereby granted, provided that the above
+copyright notice and this permission notice appear in all copies.
 
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
-AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
-OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
-SOFTWARE.
+THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/README.rst b/README.rst
index 41529bf..5b36935 100644
--- a/README.rst
+++ b/README.rst
@@ -1,14 +1,12 @@
-siphashc
-========
+.. image:: https://s.weblate.org/cdn/Logo-Darktext-borders.png
+   :alt: Weblate
+   :target: https://weblate.org/
+   :height: 80px
 
-.. image:: https://travis-ci.org/WeblateOrg/siphashc.svg?branch=master
-    :target: https://travis-ci.org/WeblateOrg/siphashc
+**Weblate is a copylefted libre software web-based continuous localization system,
+used by over 1150 libre projects and companies in more than 115 countries.**
 
-.. image:: https://ci.appveyor.com/api/projects/status/kgeohtb6as3xd9b7/branch/master?svg=true
-    :target: https://ci.appveyor.com/project/nijel/siphashc-merge/branch/master
-
-.. image:: https://api.codacy.com/project/badge/Grade/33758f86fbf44e929d85f47390093771    
-    :target: https://www.codacy.com/app/Weblate/siphashc
+siphashc is a Python module (in c) for siphash-2-4
 
 .. image:: https://img.shields.io/pypi/v/siphashc.svg
     :target: https://pypi.python.org/pypi/siphashc
@@ -40,18 +38,6 @@ It was merged from two versions of the module:
 Usage
 ~~~~~
 
-Python 2
-^^^^^^^^
-
-.. code:: python
-
-    >>> from siphashc import siphash
-    >>> siphash('sixteencharstrng', 'i need a hash of this')
-    10796923698683394048L
-
-Python 3
-^^^^^^^^
-
 .. code:: python
 
     >>> from siphashc import siphash
@@ -61,6 +47,6 @@ Python 3
 License
 ~~~~~~~
 
-Released under the `MIT
-license <http://www.opensource.org/licenses/mit-license.php>`__. See
+Released under the `ISC
+license <https://choosealicense.com/licenses/isc/>`__. See
 ``LICENSE.md`` file for details.
diff --git a/appveyor.yml b/appveyor.yml
deleted file mode 100644
index 545ec70..0000000
--- a/appveyor.yml
+++ /dev/null
@@ -1,33 +0,0 @@
-version: "{build}"
-
-clone_depth: 100
-
-environment:
-  matrix:
-    - PYTHON: "C:\\Python27"
-    - PYTHON: "C:\\Python33"
-    - PYTHON: "C:\\Python34"
-    - PYTHON: "C:\\Python35"
-    - PYTHON: "C:\\Python36"
-    - PYTHON: "C:\\Python36-x64"
-
-install:
-  - "SET PATH=%PYTHON%;%PYTHON%\\Scripts;%PATH%"
-  # We need wheel installed to build wheels
-  - "python.exe -m pip install wheel"
-
-build_script:
-  # Build the compiled extension
-  - "python setup.py build"
-
-test_script:
-  # Run the project tests
-- "python setup.py test"
-- "python benchmark.py"
-
-after_test:
-  - "python.exe setup.py bdist_wheel"
-
-artifacts:
-  # bdist_wheel puts your built wheel in the dist directory
-  - path: dist\*
diff --git a/benchmark.py b/benchmark.py
index 8b30218..7d4ad77 100755
--- a/benchmark.py
+++ b/benchmark.py
@@ -1,17 +1,17 @@
 #!/usr/bin/env python
-"""Simple timing benchmark.
+"""
+Simple timing benchmark.
+
+Used for testing possible regressions when changing code.
+"""
 
-Used for testing possible regressions when changing code."""
-from __future__ import print_function
 import timeit
 
-print('Benchmark (short):')
-print(timeit.timeit(
-    "siphash('0123456789ABCDEF', 'a')",
-    "from siphashc import siphash"
-))
-print('Benchmark (long):')
-print(timeit.timeit(
-    "siphash('0123456789ABCDEF', 'a' * 1000)",
-    "from siphashc import siphash"
-))
+print("Benchmark (short):")
+print(timeit.timeit("siphash('0123456789ABCDEF', 'a')", "from siphashc import siphash"))
+print("Benchmark (long):")
+print(
+    timeit.timeit(
+        "siphash('0123456789ABCDEF', 'a' * 1000)", "from siphashc import siphash"
+    )
+)
diff --git a/debian/changelog b/debian/changelog
index d43248d..c68399e 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,13 @@
+siphashc (2.1-0.1) unstable; urgency=medium
+
+  * Non-maintainer upload.
+  * New upstream release.
+    - Supports Python 3.10. (Closes: #999397)
+  * Add watch file.
+  * Update copyright years.
+
+ -- Stefano Rivera <stefanor@debian.org>  Sat, 20 Nov 2021 09:17:18 -0400
+
 siphashc (1.2-1) unstable; urgency=medium
 
   * Initial release (Closes: #892182)
diff --git a/debian/copyright b/debian/copyright
index 223870b..2f79ddc 100644
--- a/debian/copyright
+++ b/debian/copyright
@@ -5,7 +5,7 @@ Source: https://github.com/WeblateOrg/siphashc
 Files: *
 Copyright: 2013 Eli Janssen
 	   2014 Carlo Pires (python3 support)
-	   2017 Michal Čihař (additional cleanups)
+	   2017-2020 Michal Čihař (additional cleanups)
 License: MIT
 
 Files: debian/*
@@ -32,4 +32,4 @@ License: MIT
  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
  CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
  TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
- SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
\ No newline at end of file
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
diff --git a/debian/watch b/debian/watch
new file mode 100644
index 0000000..c807b65
--- /dev/null
+++ b/debian/watch
@@ -0,0 +1,4 @@
+version=4
+opts="filenamemangle=s%(?:.*?)?v?(\d[\d.]*)\.tar\.gz%@PACKAGE@-$1.tar.gz%" \
+ https://github.com/WeblateOrg/siphashc/tags \
+ (?:.*?/)?v?(\d[\d.]*)\.tar\.gz
diff --git a/requirements-lint.txt b/requirements-lint.txt
new file mode 100644
index 0000000..d835492
--- /dev/null
+++ b/requirements-lint.txt
@@ -0,0 +1,2 @@
+pre-commit==2.7.1
+twine
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..b1cddb4
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,4 @@
+[flake8]
+per-file-ignores =
+   benchmark.py:T001
+max-line-length = 88
diff --git a/setup.py b/setup.py
index bd188c7..e1590ea 100755
--- a/setup.py
+++ b/setup.py
@@ -1,41 +1,51 @@
 #!/usr/bin/env python
-# -*- coding: utf-8 -*-
+"""Setup for the siphashc module."""
 
 import io
 import os.path
-from setuptools import setup, Extension
 
-with io.open(os.path.join(os.path.dirname(__file__), 'README.rst'), encoding='utf-8') as readme:
+from setuptools import Extension, setup
+
+with io.open(
+    os.path.join(os.path.dirname(__file__), "README.rst"), encoding="utf-8"
+) as readme:
     LONG_DESCRIPTION = readme.read()
 
 setup(
-    name='siphashc',
-    version='1.2',
-    author='Michal Čihař',
-    author_email='michal@cihar.com',
-    description='Python module (in c) for siphash-2-4',
+    name="siphashc",
+    version="2.1",
+    author="Michal Čihař",
+    author_email="michal@cihar.com",
+    description="Python module (in c) for siphash-2-4",
     long_description=LONG_DESCRIPTION,
-    keywords='siphash siphash-2-4',
-    url='https://github.com/WeblateOrg/siphashc',
-    bugtrack_url='https://github.com/WeblateOrg/siphashc/issues',
-    license="MIT",
+    long_description_content_type="text/x-rst",
+    keywords="siphash siphash-2-4",
+    url="https://github.com/WeblateOrg/siphashc",
+    project_urls={
+        "Issue Tracker": "https://github.com/WeblateOrg/siphashc/issues",
+        "Source Code": "https://github.com/WeblateOrg/siphashc",
+        "Twitter": "https://twitter.com/WeblateOrg",
+    },
+    license="ISC",
+    python_requires=">=3.5",
     ext_modules=[
         Extension(
-            name="siphashc",
-            sources=["siphashc.c", "siphash/siphash.c"],
-            language="c"
-        ),
+            name="siphashc", sources=["siphashc.c", "siphash/siphash.c"], language="c"
+        )
     ],
     classifiers=[
-        'Development Status :: 5 - Production/Stable',
-        'Intended Audience :: Developers',
-        'Operating System :: OS Independent',
-        'Programming Language :: Python',
-        'Programming Language :: Python :: 2.7',
-        'Programming Language :: Python :: 3',
-        'Topic :: Software Development :: Libraries :: Python Modules',
-        'License :: OSI Approved :: MIT License',
+        "Development Status :: 5 - Production/Stable",
+        "Intended Audience :: Developers",
+        "Operating System :: OS Independent",
+        "Programming Language :: Python",
+        "Programming Language :: Python :: 3",
+        "Programming Language :: Python :: 3.5",
+        "Programming Language :: Python :: 3.6",
+        "Programming Language :: Python :: 3.7",
+        "Programming Language :: Python :: 3.8",
+        "Topic :: Software Development :: Libraries :: Python Modules",
+        "License :: OSI Approved :: ISC License (ISCL)",
     ],
-    test_suite='test_siphashc',
+    test_suite="test_siphashc",
     zip_safe=True,
 )
diff --git a/siphash/README.md b/siphash/README.md
index 474cf3c..bdcc6ab 100644
--- a/siphash/README.md
+++ b/siphash/README.md
@@ -1,2 +1 @@
 siphash from https://github.com/floodyberry/siphash
-
diff --git a/siphash/siphash.h b/siphash/siphash.h
index b9b7eb8..7bd9f55 100644
--- a/siphash/siphash.h
+++ b/siphash/siphash.h
@@ -12,9 +12,9 @@
 #ifdef __cplusplus /* If this is a C++ compiler, use C linkage */
 extern "C" {
 #endif
- 
+
 uint64_t siphash(const unsigned char key[16], const unsigned char *m, size_t len);
- 
+
 #ifdef __cplusplus /* If this is a C++ compiler, end C linkage */
 }
 #endif
diff --git a/siphashc.c b/siphashc.c
index 8c56d28..8b9ac76 100644
--- a/siphashc.c
+++ b/siphashc.c
@@ -1,7 +1,7 @@
 /*
  * Copyright (c) 2013 Eli Janssen
  * Copyright (c) 2014 Carlo Pires
- * Copyright (c) 2017 Michal Čihař
+ * Copyright (c) 2017 - 2020 Michal Čihař
  *
  * Permission is hereby granted, free of charge, to any person obtaining a copy
  * of this software and associated documentation files (the "Software"), to deal
@@ -22,6 +22,8 @@
  * THE SOFTWARE.
 **/
 
+#define PY_SSIZE_T_CLEAN
+
 #include <stdlib.h>
 #include <string.h>
 #include <Python.h>
@@ -29,9 +31,9 @@
 
 static PyObject *pysiphash(PyObject *self, PyObject *args) {
     const char *key = NULL;
-    int key_sz;
+    Py_ssize_t key_sz;
     const char *plaintext = NULL;
-    int plain_sz;
+    Py_ssize_t plain_sz;
     uint64_t hash;
 
     if (!PyArg_ParseTuple(
@@ -67,42 +69,20 @@ static PyMethodDef siphashc_methods[] = {
     {NULL, NULL, 0, NULL} /* sentinel */
 };
 
-#if PY_MAJOR_VERSION >= 3
-	static struct PyModuleDef moduledef = {
-		    PyModuleDef_HEAD_INIT,
-		    "siphashc",
-		    NULL,
-            -1,
-		    siphashc_methods,
-		    NULL,
-		    NULL,
-		    NULL,
-		    NULL
-	};
-
-	#define INITERROR return NULL
-
-	PyObject *
-	PyInit_siphashc(void)
-#else
-	#define INITERROR return
+static struct PyModuleDef moduledef = {
+    PyModuleDef_HEAD_INIT,
+    "siphashc",
+    NULL,
+    -1,
+    siphashc_methods,
+    NULL,
+    NULL,
+    NULL,
+    NULL
+};
 
-	void
-	initsiphashc(void)
-#endif
+PyObject *
+PyInit_siphashc(void)
 {
-    PyObject *module;
-#if PY_MAJOR_VERSION >= 3
-    module = PyModule_Create(&moduledef);
-#else
-    module = Py_InitModule("siphashc", siphashc_methods);
-#endif
-
-    if (module == NULL)
-        INITERROR;
-
-#if PY_MAJOR_VERSION >= 3
-    return module;
-#endif
+    return PyModule_Create(&moduledef);
 }
-
diff --git a/test_siphashc.py b/test_siphashc.py
index 8fe3a91..e553f43 100644
--- a/test_siphashc.py
+++ b/test_siphashc.py
@@ -1,5 +1,6 @@
 """Test for siphashc module."""
 import unittest
+
 from siphashc import siphash
 
 
@@ -8,49 +9,91 @@ class TestSiphashC(unittest.TestCase):
 
     def test_hash(self):
         """Test simple hashing."""
-        result = siphash('sixteencharstrng', 'i need a hash of this')
+        result = siphash("sixteencharstrng", "i need a hash of this")
         self.assertEqual(10796923698683394048, result)
 
-        result = siphash('0123456789ABCDEF', 'a')
+        result = siphash("0123456789ABCDEF", "a")
         self.assertEqual(12398370950267227270, result)
 
     def test_errors(self):
         """Test error handling."""
         with self.assertRaises(ValueError):
-            siphash('not long enough', 'a')
+            siphash("not long enough", "a")
         with self.assertRaises(ValueError):
-            siphash('toooooooooooooooooooooooo long', 'a')
+            siphash("toooooooooooooooooooooooo long", "a")
         with self.assertRaises(ValueError):
-            siphash('', 'a')
+            siphash("", "a")
 
     def test_reference_vectors(self):
         """Test reference vectors."""
         vectors = [
-            0x726fdb47dd0e0e31, 0x74f839c593dc67fd, 0x0d6c8009d9a94f5a,
-            0x85676696d7fb7e2d, 0xcf2794e0277187b7, 0x18765564cd99a68d,
-            0xcbc9466e58fee3ce, 0xab0200f58b01d137, 0x93f5f5799a932462,
-            0x9e0082df0ba9e4b0, 0x7a5dbbc594ddb9f3, 0xf4b32f46226bada7,
-            0x751e8fbc860ee5fb, 0x14ea5627c0843d90, 0xf723ca908e7af2ee,
-            0xa129ca6149be45e5, 0x3f2acc7f57c29bdb, 0x699ae9f52cbe4794,
-            0x4bc1b3f0968dd39c, 0xbb6dc91da77961bd, 0xbed65cf21aa2ee98,
-            0xd0f2cbb02e3b67c7, 0x93536795e3a33e88, 0xa80c038ccd5ccec8,
-            0xb8ad50c6f649af94, 0xbce192de8a85b8ea, 0x17d835b85bbb15f3,
-            0x2f2e6163076bcfad, 0xde4daaaca71dc9a5, 0xa6a2506687956571,
-            0xad87a3535c49ef28, 0x32d892fad841c342, 0x7127512f72f27cce,
-            0xa7f32346f95978e3, 0x12e0b01abb051238, 0x15e034d40fa197ae,
-            0x314dffbe0815a3b4, 0x027990f029623981, 0xcadcd4e59ef40c4d,
-            0x9abfd8766a33735c, 0x0e3ea96b5304a7d0, 0xad0c42d6fc585992,
-            0x187306c89bc215a9, 0xd4a60abcf3792b95, 0xf935451de4f21df2,
-            0xa9538f0419755787, 0xdb9acddff56ca510, 0xd06c98cd5c0975eb,
-            0xe612a3cb9ecba951, 0xc766e62cfcadaf96, 0xee64435a9752fe72,
-            0xa192d576b245165a, 0x0a8787bf8ecb74b2, 0x81b3e73d20b49b6f,
-            0x7fa8220ba3b2ecea, 0x245731c13ca42499, 0xb78dbfaf3a8d83bd,
-            0xea1ad565322a1a0b, 0x60e61c23a3795013, 0x6606d7e446282b93,
-            0x6ca4ecb15c5f91e1, 0x9f626da15c9625f3, 0xe51b38608ef25f57,
-            0x958a324ceb064572
+            0x726FDB47DD0E0E31,
+            0x74F839C593DC67FD,
+            0x0D6C8009D9A94F5A,
+            0x85676696D7FB7E2D,
+            0xCF2794E0277187B7,
+            0x18765564CD99A68D,
+            0xCBC9466E58FEE3CE,
+            0xAB0200F58B01D137,
+            0x93F5F5799A932462,
+            0x9E0082DF0BA9E4B0,
+            0x7A5DBBC594DDB9F3,
+            0xF4B32F46226BADA7,
+            0x751E8FBC860EE5FB,
+            0x14EA5627C0843D90,
+            0xF723CA908E7AF2EE,
+            0xA129CA6149BE45E5,
+            0x3F2ACC7F57C29BDB,
+            0x699AE9F52CBE4794,
+            0x4BC1B3F0968DD39C,
+            0xBB6DC91DA77961BD,
+            0xBED65CF21AA2EE98,
+            0xD0F2CBB02E3B67C7,
+            0x93536795E3A33E88,
+            0xA80C038CCD5CCEC8,
+            0xB8AD50C6F649AF94,
+            0xBCE192DE8A85B8EA,
+            0x17D835B85BBB15F3,
+            0x2F2E6163076BCFAD,
+            0xDE4DAAACA71DC9A5,
+            0xA6A2506687956571,
+            0xAD87A3535C49EF28,
+            0x32D892FAD841C342,
+            0x7127512F72F27CCE,
+            0xA7F32346F95978E3,
+            0x12E0B01ABB051238,
+            0x15E034D40FA197AE,
+            0x314DFFBE0815A3B4,
+            0x027990F029623981,
+            0xCADCD4E59EF40C4D,
+            0x9ABFD8766A33735C,
+            0x0E3EA96B5304A7D0,
+            0xAD0C42D6FC585992,
+            0x187306C89BC215A9,
+            0xD4A60ABCF3792B95,
+            0xF935451DE4F21DF2,
+            0xA9538F0419755787,
+            0xDB9ACDDFF56CA510,
+            0xD06C98CD5C0975EB,
+            0xE612A3CB9ECBA951,
+            0xC766E62CFCADAF96,
+            0xEE64435A9752FE72,
+            0xA192D576B245165A,
+            0x0A8787BF8ECB74B2,
+            0x81B3E73D20B49B6F,
+            0x7FA8220BA3B2ECEA,
+            0x245731C13CA42499,
+            0xB78DBFAF3A8D83BD,
+            0xEA1AD565322A1A0B,
+            0x60E61C23A3795013,
+            0x6606D7E446282B93,
+            0x6CA4ECB15C5F91E1,
+            0x9F626DA15C9625F3,
+            0xE51B38608EF25F57,
+            0x958A324CEB064572,
         ]
-        k = '\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f'
-        message = ''
+        k = "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
+        message = ""
         for i in range(64):
             self.assertEqual(siphash(k, message), vectors[i])
             message += chr(i)

Run locally

More details

Full run details