Support free-threaded Python 3.13 (#925)
* Support free-threaded Python 3.13 * fix issues with tox.ini * add multithreading test * fix pep8 * fix ruff format * name linux CI run based on python VERSION * clarify use of pytest-run-parallel marks * refactor test_multithreading * simplify test_multithreading * remove pytest-run-parallel use
This commit is contained in:
parent
1de1cad7f2
commit
df983f9c98
11
.github/workflows/ci.yml
vendored
11
.github/workflows/ci.yml
vendored
@ -16,6 +16,7 @@ jobs:
|
||||
PYTHON:
|
||||
- {VERSION: "3.8", TOXENV: "py38"}
|
||||
- {VERSION: "3.13", TOXENV: "py313"}
|
||||
- {VERSION: "3.13t", TOXENV: "py313"}
|
||||
MACOS:
|
||||
- macos-13
|
||||
- macos-latest
|
||||
@ -24,7 +25,7 @@ jobs:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Setup python
|
||||
id: setup-python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: quansight-labs/setup-python@v5.3.1
|
||||
with:
|
||||
python-version: ${{ matrix.PYTHON.VERSION }}
|
||||
- uses: actions/cache@v4.2.0
|
||||
@ -53,12 +54,13 @@ jobs:
|
||||
PYTHON:
|
||||
- {VERSION: "3.8", TOXENV: "py38"}
|
||||
- {VERSION: "3.13", TOXENV: "py313"}
|
||||
- {VERSION: "3.13t", TOXENV: "py313"}
|
||||
name: "Python ${{ matrix.PYTHON.VERSION }} on ${{ matrix.WINDOWS.WINDOWS }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Setup python
|
||||
id: setup-python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: quansight-labs/setup-python@v5.3.1
|
||||
with:
|
||||
python-version: ${{ matrix.PYTHON.VERSION }}
|
||||
architecture: ${{ matrix.WINDOWS.ARCH }}
|
||||
@ -92,6 +94,7 @@ jobs:
|
||||
- {VERSION: "3.11", TOXENV: "py311"}
|
||||
- {VERSION: "3.12", TOXENV: "py312"}
|
||||
- {VERSION: "3.13", TOXENV: "py313"}
|
||||
- {VERSION: "3.13t", TOXENV: "py313"}
|
||||
- {VERSION: "pypy-3.9", TOXENV: "pypy3"}
|
||||
- {VERSION: "pypy-3.10", TOXENV: "pypy3"}
|
||||
|
||||
@ -99,12 +102,12 @@ jobs:
|
||||
- {VERSION: "3.13", TOXENV: "py313", RUST_VERSION: "1.64.0"}
|
||||
- {VERSION: "3.13", TOXENV: "py313", RUST_VERSION: "beta"}
|
||||
- {VERSION: "3.13", TOXENV: "py313", RUST_VERSION: "nightly"}
|
||||
name: "${{ matrix.PYTHON.TOXENV }} on linux, Rust ${{ matrix.PYTHON.RUST_VERSION || 'stable' }}"
|
||||
name: "${{ matrix.PYTHON.VERSION }} on linux, Rust ${{ matrix.PYTHON.RUST_VERSION || 'stable' }}"
|
||||
steps:
|
||||
- uses: actions/checkout@v4.2.2
|
||||
- name: Setup python
|
||||
id: setup-python
|
||||
uses: actions/setup-python@v5.3.0
|
||||
uses: quansight-labs/setup-python@v5.3.1
|
||||
with:
|
||||
python-version: ${{ matrix.PYTHON.VERSION }}
|
||||
- uses: actions/cache@v4.2.0
|
||||
|
||||
@ -285,7 +285,7 @@ Compatibility
|
||||
-------------
|
||||
|
||||
This library should be compatible with py-bcrypt and it will run on Python
|
||||
3.6+, and PyPy 3.
|
||||
3.8+ (including free-threaded builds), and PyPy 3.
|
||||
|
||||
Security
|
||||
--------
|
||||
|
||||
@ -182,7 +182,7 @@ fn kdf<'p>(
|
||||
})
|
||||
}
|
||||
|
||||
#[pyo3::pymodule]
|
||||
#[pyo3::pymodule(gil_used = false)]
|
||||
mod _bcrypt {
|
||||
use pyo3::types::PyModuleMethods;
|
||||
|
||||
|
||||
@ -1,3 +1,6 @@
|
||||
import uuid
|
||||
from concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
import pytest
|
||||
|
||||
import bcrypt
|
||||
@ -171,7 +174,7 @@ _2y_test_vectors = [
|
||||
]
|
||||
|
||||
|
||||
def test_gensalt_basic(monkeypatch):
|
||||
def test_gensalt_basic():
|
||||
salt = bcrypt.gensalt()
|
||||
assert salt.startswith(b"$2b$12$")
|
||||
|
||||
@ -219,7 +222,7 @@ def test_gensalt_bad_prefix():
|
||||
bcrypt.gensalt(prefix=b"bad")
|
||||
|
||||
|
||||
def test_gensalt_2a_prefix(monkeypatch):
|
||||
def test_gensalt_2a_prefix():
|
||||
salt = bcrypt.gensalt(prefix=b"2a")
|
||||
assert salt.startswith(b"$2a$12$")
|
||||
|
||||
@ -494,3 +497,24 @@ def test_2a_wraparound_bug():
|
||||
)
|
||||
== b"$2a$04$R1lJ2gkNaoPGdafE.H.16.1MKHPvmKwryeulRe225LKProWYwt9Oi"
|
||||
)
|
||||
|
||||
|
||||
def test_multithreading():
|
||||
def create_user(pw):
|
||||
salt = bcrypt.gensalt(4)
|
||||
hash_ = bcrypt.hashpw(pw, salt)
|
||||
key = bcrypt.kdf(pw, salt, 32, 50)
|
||||
assert bcrypt.checkpw(pw, hash_)
|
||||
return (salt, hash_, key)
|
||||
|
||||
user_creator = ThreadPoolExecutor(max_workers=4)
|
||||
pws = [uuid.uuid4().bytes for _ in range(50)]
|
||||
|
||||
futures = [user_creator.submit(create_user, pw) for pw in pws]
|
||||
|
||||
users = [future.result() for future in futures]
|
||||
|
||||
for pw, (salt, hash_, key) in zip(pws, users):
|
||||
assert bcrypt.hashpw(pw, salt) == hash_
|
||||
assert bcrypt.checkpw(pw, hash_)
|
||||
assert bcrypt.kdf(pw, salt, 32, 50) == key
|
||||
|
||||
Loading…
Reference in New Issue
Block a user