Import Upstream version 1.7.1
This commit is contained in:
commit
b5d35b32b7
|
@ -0,0 +1,24 @@
|
||||||
|
[bumpversion]
|
||||||
|
current_version = 1.7.1
|
||||||
|
commit = True
|
||||||
|
tag = True
|
||||||
|
|
||||||
|
[bumpversion:file:setup.py]
|
||||||
|
search = 'fallback_version': '{current_version}'
|
||||||
|
replace = 'fallback_version': '{new_version}'
|
||||||
|
|
||||||
|
[bumpversion:file (badge):README.rst]
|
||||||
|
search = /v{current_version}.svg
|
||||||
|
replace = /v{new_version}.svg
|
||||||
|
|
||||||
|
[bumpversion:file (link):README.rst]
|
||||||
|
search = /v{current_version}...master
|
||||||
|
replace = /v{new_version}...master
|
||||||
|
|
||||||
|
[bumpversion:file:docs/conf.py]
|
||||||
|
search = version = release = '{current_version}'
|
||||||
|
replace = version = release = '{new_version}'
|
||||||
|
|
||||||
|
[bumpversion:file:src/lazy_object_proxy/__init__.py]
|
||||||
|
search = __version__ = '{current_version}'
|
||||||
|
replace = __version__ = '{new_version}'
|
|
@ -0,0 +1,55 @@
|
||||||
|
# Generated by cookiepatcher, a small shim around cookiecutter (pip install cookiepatcher)
|
||||||
|
|
||||||
|
default_context:
|
||||||
|
allow_tests_inside_package: no
|
||||||
|
appveyor: no
|
||||||
|
c_extension_function: '-'
|
||||||
|
c_extension_module: '-'
|
||||||
|
c_extension_optional: yes
|
||||||
|
c_extension_support: yes
|
||||||
|
c_extension_test_pypi: yes
|
||||||
|
c_extension_test_pypi_username: ionel
|
||||||
|
codacy: no
|
||||||
|
codacy_projectid: 862e7946eabb4112be6503a667381b71
|
||||||
|
codeclimate: no
|
||||||
|
codecov: yes
|
||||||
|
command_line_interface: no
|
||||||
|
command_line_interface_bin_name: '-'
|
||||||
|
coveralls: yes
|
||||||
|
distribution_name: lazy-object-proxy
|
||||||
|
email: contact@ionelmc.ro
|
||||||
|
full_name: Ionel Cristian Mărieș
|
||||||
|
github_actions: yes
|
||||||
|
legacy_python: no
|
||||||
|
license: BSD 2-Clause License
|
||||||
|
linter: flake8
|
||||||
|
package_name: lazy_object_proxy
|
||||||
|
pre_commit: yes
|
||||||
|
project_name: lazy-object-proxy
|
||||||
|
project_short_description: A fast and thorough lazy object proxy.
|
||||||
|
pypi_badge: yes
|
||||||
|
pypi_disable_upload: no
|
||||||
|
release_date: '2021-03-22'
|
||||||
|
repo_hosting: github.com
|
||||||
|
repo_hosting_domain: github.com
|
||||||
|
repo_main_branch: master
|
||||||
|
repo_name: python-lazy-object-proxy
|
||||||
|
repo_username: ionelmc
|
||||||
|
requiresio: yes
|
||||||
|
scrutinizer: no
|
||||||
|
setup_py_uses_setuptools_scm: yes
|
||||||
|
setup_py_uses_test_runner: no
|
||||||
|
sphinx_docs: yes
|
||||||
|
sphinx_docs_hosting: https://python-lazy-object-proxy.readthedocs.io/
|
||||||
|
sphinx_doctest: no
|
||||||
|
sphinx_theme: sphinx-py3doc-enhanced-theme
|
||||||
|
test_matrix_configurator: no
|
||||||
|
test_matrix_separate_coverage: yes
|
||||||
|
test_runner: pytest
|
||||||
|
travis: no
|
||||||
|
travis_osx: no
|
||||||
|
version: 1.6.0
|
||||||
|
version_manager: bump2version
|
||||||
|
website: https://blog.ionelmc.ro
|
||||||
|
year_from: '2014'
|
||||||
|
year_to: '2021'
|
|
@ -0,0 +1,14 @@
|
||||||
|
[paths]
|
||||||
|
source = src
|
||||||
|
|
||||||
|
[run]
|
||||||
|
branch = true
|
||||||
|
source =
|
||||||
|
src
|
||||||
|
tests
|
||||||
|
parallel = true
|
||||||
|
|
||||||
|
[report]
|
||||||
|
show_missing = true
|
||||||
|
precision = 2
|
||||||
|
omit = *migrations*
|
|
@ -0,0 +1,20 @@
|
||||||
|
# see https://editorconfig.org/
|
||||||
|
root = true
|
||||||
|
|
||||||
|
[*]
|
||||||
|
# Use Unix-style newlines for most files (except Windows files, see below).
|
||||||
|
end_of_line = lf
|
||||||
|
trim_trailing_whitespace = true
|
||||||
|
indent_style = space
|
||||||
|
insert_final_newline = true
|
||||||
|
indent_size = 4
|
||||||
|
charset = utf-8
|
||||||
|
|
||||||
|
[*.{bat,cmd,ps1}]
|
||||||
|
end_of_line = crlf
|
||||||
|
|
||||||
|
[*.{yml,yaml}]
|
||||||
|
indent_size = 2
|
||||||
|
|
||||||
|
[*.tsv]
|
||||||
|
indent_style = tab
|
|
@ -0,0 +1 @@
|
||||||
|
tidelift: "pypi/lazy-object-proxy"
|
|
@ -0,0 +1,573 @@
|
||||||
|
name: build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: ${{ matrix.name }}
|
||||||
|
runs-on: ${{ matrix.os }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: 'check'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
tox_env: 'check'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'docs'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
tox_env: 'docs'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py36-cover (ubuntu/x86_64)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py36-cover (windows/AMD64)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py36-cover (macos/x86_64)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py36-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp36-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py36-nocov (ubuntu/x86_64/musllinux)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp36-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py36-nocov (ubuntu/aarch64/manylinux)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp36-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py36-nocov (ubuntu/aarch64/musllinux)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp36-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py36-nocov (windows/AMD64)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: 'cp36-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py36-nocov (windows/x86)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x86'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'x86'
|
||||||
|
cibw_build: 'cp36-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py36-nocov (macos/x86_64)'
|
||||||
|
python: '3.6'
|
||||||
|
toxpython: 'python3.6'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py36-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp36-*'
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py37-cover (ubuntu/x86_64)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py37-cover (windows/AMD64)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py37-cover (macos/x86_64)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py37-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp37-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py37-nocov (ubuntu/x86_64/musllinux)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp37-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py37-nocov (ubuntu/aarch64/manylinux)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp37-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py37-nocov (ubuntu/aarch64/musllinux)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp37-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py37-nocov (windows/AMD64)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: 'cp37-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py37-nocov (windows/x86)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x86'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'x86'
|
||||||
|
cibw_build: 'cp37-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py37-nocov (macos/x86_64)'
|
||||||
|
python: '3.7'
|
||||||
|
toxpython: 'python3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py37-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp37-*'
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py38-cover (ubuntu/x86_64)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py38-cover (windows/AMD64)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py38-cover (macos/x86_64)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py38-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp38-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py38-nocov (ubuntu/x86_64/musllinux)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp38-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py38-nocov (ubuntu/aarch64/manylinux)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp38-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py38-nocov (ubuntu/aarch64/musllinux)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp38-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py38-nocov (windows/AMD64)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: 'cp38-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py38-nocov (windows/x86)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x86'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'x86'
|
||||||
|
cibw_build: 'cp38-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py38-nocov (macos/x86_64)'
|
||||||
|
python: '3.8'
|
||||||
|
toxpython: 'python3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py38-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp38-*'
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py39-cover (ubuntu/x86_64)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py39-cover (windows/AMD64)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py39-cover (macos/x86_64)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py39-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp39-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py39-nocov (ubuntu/x86_64/musllinux)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp39-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py39-nocov (ubuntu/aarch64/manylinux)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp39-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py39-nocov (ubuntu/aarch64/musllinux)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp39-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py39-nocov (windows/AMD64)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: 'cp39-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py39-nocov (windows/x86)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x86'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'x86'
|
||||||
|
cibw_build: 'cp39-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py39-nocov (macos/x86_64)'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py39-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp39-*'
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py310-cover (ubuntu/x86_64)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py310-cover (windows/AMD64)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py310-cover (macos/x86_64)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'py310-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp310-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py310-nocov (ubuntu/x86_64/musllinux)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp310-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py310-nocov (ubuntu/aarch64/manylinux)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp310-*manylinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py310-nocov (ubuntu/aarch64/musllinux)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'aarch64'
|
||||||
|
cibw_build: 'cp310-*musllinux*'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'py310-nocov (windows/AMD64)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: 'cp310-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py310-nocov (windows/x86)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x86'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'x86'
|
||||||
|
cibw_build: 'cp310-*'
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'py310-nocov (macos/x86_64)'
|
||||||
|
python: '3.10'
|
||||||
|
toxpython: 'python3.10'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'py310-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: 'cp310-*'
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'pypy37-cover (ubuntu/x86_64)'
|
||||||
|
python: 'pypy-3.7'
|
||||||
|
toxpython: 'pypy3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy37-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'pypy37-cover (windows/AMD64)'
|
||||||
|
python: 'pypy-3.7'
|
||||||
|
toxpython: 'pypy3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy37-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'pypy37-cover (macos/x86_64)'
|
||||||
|
python: 'pypy-3.7'
|
||||||
|
toxpython: 'pypy3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy37-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'pypy37-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: 'pypy-3.7'
|
||||||
|
toxpython: 'pypy3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy37-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'pypy37-nocov (windows/AMD64)'
|
||||||
|
python: 'pypy-3.7'
|
||||||
|
toxpython: 'pypy3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy37-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'pypy37-nocov (macos/x86_64)'
|
||||||
|
python: 'pypy-3.7'
|
||||||
|
toxpython: 'pypy3.7'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy37-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'pypy38-cover (ubuntu/x86_64)'
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
toxpython: 'pypy3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy38-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'pypy38-cover (windows/AMD64)'
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
toxpython: 'pypy3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy38-cover,codecov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'pypy38-cover (macos/x86_64)'
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
toxpython: 'pypy3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy38-cover,codecov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
- name: 'pypy38-nocov (ubuntu/x86_64/manylinux)'
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
toxpython: 'pypy3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy38-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'pypy38-nocov (windows/AMD64)'
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
toxpython: 'pypy3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy38-nocov'
|
||||||
|
cibw_arch: 'AMD64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'windows-latest'
|
||||||
|
- name: 'pypy38-nocov (macos/x86_64)'
|
||||||
|
python: 'pypy-3.8'
|
||||||
|
toxpython: 'pypy3.8'
|
||||||
|
python_arch: 'x64'
|
||||||
|
tox_env: 'pypy38-nocov'
|
||||||
|
cibw_arch: 'x86_64'
|
||||||
|
cibw_build: false
|
||||||
|
os: 'macos-latest'
|
||||||
|
steps:
|
||||||
|
- uses: docker/setup-qemu-action@v1
|
||||||
|
if: matrix.cibw_arch == 'aarch64'
|
||||||
|
with:
|
||||||
|
platforms: arm64
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: ${{ matrix.python }}
|
||||||
|
architecture: ${{ matrix.python_arch }}
|
||||||
|
- name: install dependencies
|
||||||
|
run: |
|
||||||
|
python -mpip install --progress-bar=off twine tox cibuildwheel -r ci/requirements.txt
|
||||||
|
virtualenv --version
|
||||||
|
pip --version
|
||||||
|
tox --version
|
||||||
|
pip list --format=freeze
|
||||||
|
- name: install dependencies (gdb)
|
||||||
|
if: >
|
||||||
|
!matrix.cibw_build && matrix.os == 'ubuntu'
|
||||||
|
run: >
|
||||||
|
sudo apt-get install gdb
|
||||||
|
- name: cibw build and test
|
||||||
|
if: matrix.cibw_build
|
||||||
|
run: cibuildwheel
|
||||||
|
env:
|
||||||
|
TOXPYTHON: '${{ matrix.toxpython }}'
|
||||||
|
CIBW_ARCHS: '${{ matrix.cibw_arch }}'
|
||||||
|
CIBW_BUILD: '${{ matrix.cibw_build }}'
|
||||||
|
CIBW_BUILD_VERBOSITY: '3'
|
||||||
|
CIBW_TEST_REQUIRES: >
|
||||||
|
tox
|
||||||
|
tox-direct
|
||||||
|
CIBW_TEST_COMMAND: >
|
||||||
|
cd {project} &&
|
||||||
|
tox --skip-pkg-install --direct-yolo -e ${{ matrix.tox_env }} -v
|
||||||
|
CIBW_TEST_COMMAND_WINDOWS: >
|
||||||
|
cd /d {project} &&
|
||||||
|
tox --skip-pkg-install --direct-yolo -e ${{ matrix.tox_env }} -v
|
||||||
|
- name: regular build and test
|
||||||
|
env:
|
||||||
|
TOXPYTHON: '${{ matrix.toxpython }}'
|
||||||
|
if: >
|
||||||
|
!matrix.cibw_build
|
||||||
|
run: >
|
||||||
|
tox -e ${{ matrix.tox_env }} -v
|
||||||
|
- name: check wheel
|
||||||
|
if: matrix.cibw_build
|
||||||
|
run: twine check wheelhouse/*.whl
|
||||||
|
- name: upload wheel
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: matrix.cibw_build
|
||||||
|
with:
|
||||||
|
path: wheelhouse/*.whl
|
|
@ -0,0 +1,77 @@
|
||||||
|
*.py[cod]
|
||||||
|
__pycache__
|
||||||
|
|
||||||
|
# C extensions
|
||||||
|
*.so
|
||||||
|
|
||||||
|
# Packages
|
||||||
|
*.egg
|
||||||
|
*.egg-info
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
eggs
|
||||||
|
.eggs
|
||||||
|
parts
|
||||||
|
bin
|
||||||
|
var
|
||||||
|
sdist
|
||||||
|
wheelhouse
|
||||||
|
develop-eggs
|
||||||
|
.installed.cfg
|
||||||
|
lib
|
||||||
|
lib64
|
||||||
|
venv*/
|
||||||
|
pyvenv*/
|
||||||
|
pip-wheel-metadata/
|
||||||
|
|
||||||
|
# Installer logs
|
||||||
|
pip-log.txt
|
||||||
|
|
||||||
|
# Unit test / coverage reports
|
||||||
|
.coverage
|
||||||
|
.tox
|
||||||
|
.coverage.*
|
||||||
|
.pytest_cache/
|
||||||
|
nosetests.xml
|
||||||
|
coverage.xml
|
||||||
|
htmlcov
|
||||||
|
|
||||||
|
# Translations
|
||||||
|
*.mo
|
||||||
|
|
||||||
|
# Buildout
|
||||||
|
.mr.developer.cfg
|
||||||
|
|
||||||
|
# IDE project files
|
||||||
|
.project
|
||||||
|
.pydevproject
|
||||||
|
.idea
|
||||||
|
.vscode
|
||||||
|
*.iml
|
||||||
|
*.komodoproject
|
||||||
|
|
||||||
|
# Complexity
|
||||||
|
output/*.html
|
||||||
|
output/*/index.html
|
||||||
|
|
||||||
|
# Sphinx
|
||||||
|
docs/_build
|
||||||
|
|
||||||
|
.DS_Store
|
||||||
|
*~
|
||||||
|
.*.sw[po]
|
||||||
|
.build
|
||||||
|
.ve
|
||||||
|
.env
|
||||||
|
.cache
|
||||||
|
.pytest
|
||||||
|
.benchmarks
|
||||||
|
.bootstrap
|
||||||
|
.appveyor.token
|
||||||
|
*.bak
|
||||||
|
|
||||||
|
# Mypy Cache
|
||||||
|
.mypy_cache/
|
||||||
|
|
||||||
|
# Generated by setuptools-scm
|
||||||
|
src/*/_version.py
|
|
@ -0,0 +1,20 @@
|
||||||
|
# To install the git pre-commit hook run:
|
||||||
|
# pre-commit install
|
||||||
|
# To update the pre-commit hooks run:
|
||||||
|
# pre-commit install-hooks
|
||||||
|
exclude: '^(\.tox|ci/templates|\.bumpversion\.cfg)(/|$)'
|
||||||
|
repos:
|
||||||
|
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||||
|
rev: v4.0.1
|
||||||
|
hooks:
|
||||||
|
- id: trailing-whitespace
|
||||||
|
- id: end-of-file-fixer
|
||||||
|
- id: debug-statements
|
||||||
|
- repo: https://github.com/timothycrosley/isort
|
||||||
|
rev: 5.9.3
|
||||||
|
hooks:
|
||||||
|
- id: isort
|
||||||
|
- repo: https://gitlab.com/pycqa/flake8
|
||||||
|
rev: 3.9.2
|
||||||
|
hooks:
|
||||||
|
- id: flake8
|
|
@ -0,0 +1,10 @@
|
||||||
|
# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details
|
||||||
|
version: 2
|
||||||
|
sphinx:
|
||||||
|
configuration: docs/conf.py
|
||||||
|
formats: all
|
||||||
|
python:
|
||||||
|
install:
|
||||||
|
- requirements: docs/requirements.txt
|
||||||
|
- method: pip
|
||||||
|
path: .
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
Authors
|
||||||
|
=======
|
||||||
|
|
||||||
|
* Ionel Cristian Mărieș - https://blog.ionelmc.ro
|
||||||
|
* Alvin Chow - https://github.com/alvinchow86
|
||||||
|
* Astrum Kuo - https://github.com/xowenx
|
||||||
|
* Erik M. Bray - http://iguananaut.net
|
||||||
|
* Ran Benita - https://github.com/bluetech
|
||||||
|
* "hugovk" - https://github.com/hugovk
|
|
@ -0,0 +1,124 @@
|
||||||
|
|
||||||
|
Changelog
|
||||||
|
=========
|
||||||
|
|
||||||
|
1.7.1 (2021-12-15)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
|
||||||
|
* Removed most of the Python 2 support code and fixed ``python_requires`` to require at least Python 3.6.
|
||||||
|
|
||||||
|
Note that 1.7.0 has been yanked because it could not install on Python 2.7.
|
||||||
|
Installing lazy-object-proxy on Python 2.7 should automatically fall back to the 1.6.0 release now.
|
||||||
|
|
||||||
|
1.7.0 (2021-12-15)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Switched CI to GitHub Actions, this has a couple consequences:
|
||||||
|
|
||||||
|
* Support for Python 2.7 is dropped. You can still install it there but it's not tested anymore and
|
||||||
|
Python 2 specific handling will be removed at some point.
|
||||||
|
* Linux wheels are now provided in `musllinux` and `manylinux2014` variants.
|
||||||
|
|
||||||
|
* Fixed ``__index__`` to fallback to ``int`` if the wrapped object doesn't have an ``__index__`` method.
|
||||||
|
This prevents situations where code using a proxy would otherwise likely just call ``int`` had the object
|
||||||
|
not have an ``__index__`` method.
|
||||||
|
|
||||||
|
1.6.0 (2021-03-22)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added support for async special methods (``__aiter__``, ``__anext__``,
|
||||||
|
``__await__``, ``__aenter__``, ``__aexit__``).
|
||||||
|
These are used in the ``async for``, ``await` and ``async with`` statements.
|
||||||
|
|
||||||
|
Note that ``__await__`` returns a wrapper that tries to emulate the crazy
|
||||||
|
stuff going on in the ceval loop, so there will be a small performance overhead.
|
||||||
|
* Added the ``__resolved__`` property. You can use it to check if the factory has
|
||||||
|
been called.
|
||||||
|
|
||||||
|
1.5.2 (2020-11-26)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added Python 3.9 wheels.
|
||||||
|
* Removed Python 2.7 Windows wheels
|
||||||
|
(not supported on newest image with Python 3.9).
|
||||||
|
|
||||||
|
1.5.1 (2020-07-22)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added ARM64 wheels (manylinux2014).
|
||||||
|
|
||||||
|
1.5.0 (2020-06-05)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added support for ``__fspath__``.
|
||||||
|
* Dropped support for Python 3.4.
|
||||||
|
|
||||||
|
1.4.3 (2019-10-26)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added binary wheels for Python 3.8.
|
||||||
|
* Fixed license metadata.
|
||||||
|
|
||||||
|
1.4.2 (2019-08-22)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Included a ``pyproject.toml`` to allow users install the sdist with old python/setuptools, as the
|
||||||
|
setuptools-scm dep will be fetched by pip instead of setuptools.
|
||||||
|
Fixes `#30 <https://github.com/ionelmc/python-lazy-object-proxy/issues/30>`_.
|
||||||
|
|
||||||
|
1.4.1 (2019-05-10)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Fixed wheels being built with ``-coverage`` cflags. No more issues about bogus ``cext.gcda`` files.
|
||||||
|
* Removed useless C file from wheels.
|
||||||
|
* Changed ``setup.py`` to use setuptools-scm.
|
||||||
|
|
||||||
|
1.4.0 (2019-05-05)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Fixed ``__mod__`` for the slots backend. Contributed by Ran Benita in
|
||||||
|
`#28 <https://github.com/ionelmc/python-lazy-object-proxy/pull/28>`_.
|
||||||
|
* Dropped support for Python 2.6 and 3.3. Contributed by "hugovk" in
|
||||||
|
`#24 <https://github.com/ionelmc/python-lazy-object-proxy/pull/24>`_.
|
||||||
|
|
||||||
|
1.3.1 (2017-05-05)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Fix broken release (``sdist`` had a broken ``MANIFEST.in``).
|
||||||
|
|
||||||
|
1.3.0 (2017-05-02)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Speed up arithmetic operations involving ``cext.Proxy`` subclasses.
|
||||||
|
|
||||||
|
1.2.2 (2016-04-14)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added `manylinux <https://www.python.org/dev/peps/pep-0513/>`_ wheels.
|
||||||
|
* Minor cleanup in readme.
|
||||||
|
|
||||||
|
1.2.1 (2015-08-18)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Fix a memory leak (the wrapped object would get bogus references). Contributed by Astrum Kuo in
|
||||||
|
`#10 <https://github.com/ionelmc/python-lazy-object-proxy/pull/10>`_.
|
||||||
|
|
||||||
|
1.2.0 (2015-07-06)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Don't instantiate the object when __repr__ is called. This aids with debugging (allows one to see exactly in
|
||||||
|
what state the proxy is).
|
||||||
|
|
||||||
|
1.1.0 (2015-07-05)
|
||||||
|
------------------
|
||||||
|
|
||||||
|
* Added support for pickling. The pickled value is going to be the wrapped object *without* any Proxy container.
|
||||||
|
* Fixed a memory management issue in the C extension (reference cycles weren't garbage collected due to improper
|
||||||
|
handling in the C extension). Contributed by Alvin Chow in
|
||||||
|
`#8 <https://github.com/ionelmc/python-lazy-object-proxy/pull/8>`_.
|
||||||
|
|
||||||
|
1.0.2 (2015-04-11)
|
||||||
|
-----------------------------------------
|
||||||
|
|
||||||
|
* First release on PyPI.
|
|
@ -0,0 +1,87 @@
|
||||||
|
============
|
||||||
|
Contributing
|
||||||
|
============
|
||||||
|
|
||||||
|
Contributions are welcome, and they are greatly appreciated! Every
|
||||||
|
little bit helps, and credit will always be given.
|
||||||
|
|
||||||
|
Bug reports
|
||||||
|
===========
|
||||||
|
|
||||||
|
When `reporting a bug <https://github.com/ionelmc/python-lazy-object-proxy/issues>`_ please include:
|
||||||
|
|
||||||
|
* Your operating system name and version.
|
||||||
|
* Any details about your local setup that might be helpful in troubleshooting.
|
||||||
|
* Detailed steps to reproduce the bug.
|
||||||
|
|
||||||
|
Documentation improvements
|
||||||
|
==========================
|
||||||
|
|
||||||
|
lazy-object-proxy could always use more documentation, whether as part of the
|
||||||
|
official lazy-object-proxy docs, in docstrings, or even on the web in blog posts,
|
||||||
|
articles, and such.
|
||||||
|
|
||||||
|
Feature requests and feedback
|
||||||
|
=============================
|
||||||
|
|
||||||
|
The best way to send feedback is to file an issue at https://github.com/ionelmc/python-lazy-object-proxy/issues.
|
||||||
|
|
||||||
|
If you are proposing a feature:
|
||||||
|
|
||||||
|
* Explain in detail how it would work.
|
||||||
|
* Keep the scope as narrow as possible, to make it easier to implement.
|
||||||
|
* Remember that this is a volunteer-driven project, and that code contributions are welcome :)
|
||||||
|
|
||||||
|
Development
|
||||||
|
===========
|
||||||
|
|
||||||
|
To set up `python-lazy-object-proxy` for local development:
|
||||||
|
|
||||||
|
1. Fork `python-lazy-object-proxy <https://github.com/ionelmc/python-lazy-object-proxy>`_
|
||||||
|
(look for the "Fork" button).
|
||||||
|
2. Clone your fork locally::
|
||||||
|
|
||||||
|
git clone git@github.com:YOURGITHUBNAME/python-lazy-object-proxy.git
|
||||||
|
|
||||||
|
3. Create a branch for local development::
|
||||||
|
|
||||||
|
git checkout -b name-of-your-bugfix-or-feature
|
||||||
|
|
||||||
|
Now you can make your changes locally.
|
||||||
|
|
||||||
|
4. When you're done making changes run all the checks and docs builder with `tox <https://tox.readthedocs.io/en/latest/install.html>`_ one command::
|
||||||
|
|
||||||
|
tox
|
||||||
|
|
||||||
|
5. Commit your changes and push your branch to GitHub::
|
||||||
|
|
||||||
|
git add .
|
||||||
|
git commit -m "Your detailed description of your changes."
|
||||||
|
git push origin name-of-your-bugfix-or-feature
|
||||||
|
|
||||||
|
6. Submit a pull request through the GitHub website.
|
||||||
|
|
||||||
|
Pull Request Guidelines
|
||||||
|
-----------------------
|
||||||
|
|
||||||
|
If you need some code review or feedback while you're developing the code just make the pull request.
|
||||||
|
|
||||||
|
For merging, you should:
|
||||||
|
|
||||||
|
1. Include passing tests (run ``tox``).
|
||||||
|
2. Update documentation when there's new API, functionality etc.
|
||||||
|
3. Add a note to ``CHANGELOG.rst`` about the changes.
|
||||||
|
4. Add yourself to ``AUTHORS.rst``.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Tips
|
||||||
|
----
|
||||||
|
|
||||||
|
To run a subset of tests::
|
||||||
|
|
||||||
|
tox -e envname -- pytest -k test_myfeature
|
||||||
|
|
||||||
|
To run all the test environments in *parallel*::
|
||||||
|
|
||||||
|
tox -p auto
|
|
@ -0,0 +1,21 @@
|
||||||
|
BSD 2-Clause License
|
||||||
|
|
||||||
|
Copyright (c) 2014-2019, Ionel Cristian Mărieș
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the
|
||||||
|
following conditions are met:
|
||||||
|
|
||||||
|
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following
|
||||||
|
disclaimer.
|
||||||
|
|
||||||
|
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following
|
||||||
|
disclaimer in the documentation and/or other materials provided with the distribution.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||||
|
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
|
||||||
|
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|
@ -0,0 +1,115 @@
|
||||||
|
========
|
||||||
|
Overview
|
||||||
|
========
|
||||||
|
|
||||||
|
.. start-badges
|
||||||
|
|
||||||
|
.. list-table::
|
||||||
|
:stub-columns: 1
|
||||||
|
|
||||||
|
* - docs
|
||||||
|
- |docs|
|
||||||
|
* - tests
|
||||||
|
- | |github-actions| |requires|
|
||||||
|
| |coveralls| |codecov|
|
||||||
|
* - package
|
||||||
|
- | |version| |wheel| |supported-versions| |supported-implementations|
|
||||||
|
| |commits-since|
|
||||||
|
.. |docs| image:: https://readthedocs.org/projects/python-lazy-object-proxy/badge/?style=flat
|
||||||
|
:target: https://python-lazy-object-proxy.readthedocs.io/
|
||||||
|
:alt: Documentation Status
|
||||||
|
|
||||||
|
.. |github-actions| image:: https://github.com/ionelmc/python-lazy-object-proxy/actions/workflows/github-actions.yml/badge.svg
|
||||||
|
:alt: GitHub Actions Build Status
|
||||||
|
:target: https://github.com/ionelmc/python-lazy-object-proxy/actions
|
||||||
|
|
||||||
|
.. |requires| image:: https://requires.io/github/ionelmc/python-lazy-object-proxy/requirements.svg?branch=master
|
||||||
|
:alt: Requirements Status
|
||||||
|
:target: https://requires.io/github/ionelmc/python-lazy-object-proxy/requirements/?branch=master
|
||||||
|
|
||||||
|
.. |coveralls| image:: https://coveralls.io/repos/ionelmc/python-lazy-object-proxy/badge.svg?branch=master&service=github
|
||||||
|
:alt: Coverage Status
|
||||||
|
:target: https://coveralls.io/r/ionelmc/python-lazy-object-proxy
|
||||||
|
|
||||||
|
.. |codecov| image:: https://codecov.io/gh/ionelmc/python-lazy-object-proxy/branch/master/graphs/badge.svg?branch=master
|
||||||
|
:alt: Coverage Status
|
||||||
|
:target: https://codecov.io/github/ionelmc/python-lazy-object-proxy
|
||||||
|
|
||||||
|
.. |version| image:: https://img.shields.io/pypi/v/lazy-object-proxy.svg
|
||||||
|
:alt: PyPI Package latest release
|
||||||
|
:target: https://pypi.org/project/lazy-object-proxy
|
||||||
|
|
||||||
|
.. |wheel| image:: https://img.shields.io/pypi/wheel/lazy-object-proxy.svg
|
||||||
|
:alt: PyPI Wheel
|
||||||
|
:target: https://pypi.org/project/lazy-object-proxy
|
||||||
|
|
||||||
|
.. |supported-versions| image:: https://img.shields.io/pypi/pyversions/lazy-object-proxy.svg
|
||||||
|
:alt: Supported versions
|
||||||
|
:target: https://pypi.org/project/lazy-object-proxy
|
||||||
|
|
||||||
|
.. |supported-implementations| image:: https://img.shields.io/pypi/implementation/lazy-object-proxy.svg
|
||||||
|
:alt: Supported implementations
|
||||||
|
:target: https://pypi.org/project/lazy-object-proxy
|
||||||
|
|
||||||
|
.. |commits-since| image:: https://img.shields.io/github/commits-since/ionelmc/python-lazy-object-proxy/v1.7.1.svg
|
||||||
|
:alt: Commits since latest release
|
||||||
|
:target: https://github.com/ionelmc/python-lazy-object-proxy/compare/v1.7.1...master
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.. end-badges
|
||||||
|
|
||||||
|
A fast and thorough lazy object proxy.
|
||||||
|
|
||||||
|
* Free software: BSD 2-Clause License
|
||||||
|
|
||||||
|
Note that this is based on `wrapt`_'s ObjectProxy with one big change: it calls a function the first time the proxy object is
|
||||||
|
used, while `wrapt.ObjectProxy` just forwards the method calls to the target object.
|
||||||
|
|
||||||
|
In other words, you use `lazy-object-proxy` when you only have the object way later and you use `wrapt.ObjectProxy` when you
|
||||||
|
want to override few methods (by subclassing) and forward everything else to the target object.
|
||||||
|
|
||||||
|
Example::
|
||||||
|
|
||||||
|
import lazy_object_proxy
|
||||||
|
|
||||||
|
def expensive_func():
|
||||||
|
from time import sleep
|
||||||
|
print('starting calculation')
|
||||||
|
# just as example for a very slow computation
|
||||||
|
sleep(2)
|
||||||
|
print('finished calculation')
|
||||||
|
# return the result of the calculation
|
||||||
|
return 10
|
||||||
|
|
||||||
|
obj = lazy_object_proxy.Proxy(expensive_func)
|
||||||
|
# function is called only when object is actually used
|
||||||
|
print(obj) # now expensive_func is called
|
||||||
|
|
||||||
|
print(obj) # the result without calling the expensive_func
|
||||||
|
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
pip install lazy-object-proxy
|
||||||
|
|
||||||
|
Documentation
|
||||||
|
=============
|
||||||
|
|
||||||
|
https://python-lazy-object-proxy.readthedocs.io/
|
||||||
|
|
||||||
|
Development
|
||||||
|
===========
|
||||||
|
|
||||||
|
To run all the tests run::
|
||||||
|
|
||||||
|
tox
|
||||||
|
|
||||||
|
Acknowledgements
|
||||||
|
================
|
||||||
|
|
||||||
|
This project is based on some code from `wrapt`_ as you can see in the git history.
|
||||||
|
|
||||||
|
.. _wrapt: https://github.com/GrahamDumpleton/wrapt
|
|
@ -0,0 +1,93 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import print_function
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import os
|
||||||
|
import subprocess
|
||||||
|
import sys
|
||||||
|
from os.path import abspath
|
||||||
|
from os.path import dirname
|
||||||
|
from os.path import exists
|
||||||
|
from os.path import join
|
||||||
|
from os.path import relpath
|
||||||
|
|
||||||
|
base_path = dirname(dirname(abspath(__file__)))
|
||||||
|
templates_path = join(base_path, "ci", "templates")
|
||||||
|
|
||||||
|
|
||||||
|
def check_call(args):
|
||||||
|
print("+", *args)
|
||||||
|
subprocess.check_call(args)
|
||||||
|
|
||||||
|
|
||||||
|
def exec_in_env():
|
||||||
|
env_path = join(base_path, ".tox", "bootstrap")
|
||||||
|
if sys.platform == "win32":
|
||||||
|
bin_path = join(env_path, "Scripts")
|
||||||
|
else:
|
||||||
|
bin_path = join(env_path, "bin")
|
||||||
|
if not exists(env_path):
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
print("Making bootstrap env in: {0} ...".format(env_path))
|
||||||
|
try:
|
||||||
|
check_call([sys.executable, "-m", "venv", env_path])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
try:
|
||||||
|
check_call([sys.executable, "-m", "virtualenv", env_path])
|
||||||
|
except subprocess.CalledProcessError:
|
||||||
|
check_call(["virtualenv", env_path])
|
||||||
|
print("Installing `jinja2` into bootstrap environment...")
|
||||||
|
check_call([join(bin_path, "pip"), "install", "jinja2", "tox"])
|
||||||
|
python_executable = join(bin_path, "python")
|
||||||
|
if not os.path.exists(python_executable):
|
||||||
|
python_executable += '.exe'
|
||||||
|
|
||||||
|
print("Re-executing with: {0}".format(python_executable))
|
||||||
|
print("+ exec", python_executable, __file__, "--no-env")
|
||||||
|
os.execv(python_executable, [python_executable, __file__, "--no-env"])
|
||||||
|
|
||||||
|
|
||||||
|
def main():
|
||||||
|
import jinja2
|
||||||
|
|
||||||
|
print("Project path: {0}".format(base_path))
|
||||||
|
|
||||||
|
jinja = jinja2.Environment(
|
||||||
|
loader=jinja2.FileSystemLoader(templates_path),
|
||||||
|
trim_blocks=True,
|
||||||
|
lstrip_blocks=True,
|
||||||
|
keep_trailing_newline=True
|
||||||
|
)
|
||||||
|
|
||||||
|
tox_environments = [
|
||||||
|
line.strip()
|
||||||
|
# 'tox' need not be installed globally, but must be importable
|
||||||
|
# by the Python that is running this script.
|
||||||
|
# This uses sys.executable the same way that the call in
|
||||||
|
# cookiecutter-pylibrary/hooks/post_gen_project.py
|
||||||
|
# invokes this bootstrap.py itself.
|
||||||
|
for line in subprocess.check_output([sys.executable, '-m', 'tox', '--listenvs'], universal_newlines=True).splitlines()
|
||||||
|
]
|
||||||
|
tox_environments = [line for line in tox_environments if line.startswith('py')]
|
||||||
|
|
||||||
|
for root, _, files in os.walk(templates_path):
|
||||||
|
for name in files:
|
||||||
|
relative = relpath(root, templates_path)
|
||||||
|
with open(join(base_path, relative, name), "w") as fh:
|
||||||
|
fh.write(jinja.get_template(join(relative, name)).render(tox_environments=tox_environments))
|
||||||
|
print("Wrote {}".format(name))
|
||||||
|
print("DONE.")
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
args = sys.argv[1:]
|
||||||
|
if args == ["--no-env"]:
|
||||||
|
main()
|
||||||
|
elif not args:
|
||||||
|
exec_in_env()
|
||||||
|
else:
|
||||||
|
print("Unexpected arguments {0}".format(args), file=sys.stderr)
|
||||||
|
sys.exit(1)
|
|
@ -0,0 +1,4 @@
|
||||||
|
virtualenv>=20.4.7
|
||||||
|
pip>=19.1.1
|
||||||
|
setuptools>=18.0.1
|
||||||
|
six>=1.14.0
|
|
@ -0,0 +1,115 @@
|
||||||
|
name: build
|
||||||
|
on: [push, pull_request]
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: {{ '${{ matrix.name }}' }}
|
||||||
|
runs-on: {{ '${{ matrix.os }}' }}
|
||||||
|
timeout-minutes: 30
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
include:
|
||||||
|
- name: 'check'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
tox_env: 'check'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
- name: 'docs'
|
||||||
|
python: '3.9'
|
||||||
|
toxpython: 'python3.9'
|
||||||
|
tox_env: 'docs'
|
||||||
|
os: 'ubuntu-latest'
|
||||||
|
{% for env in tox_environments %}
|
||||||
|
{% set prefix = env.split('-')[0] -%}
|
||||||
|
{% if prefix.startswith('pypy') %}
|
||||||
|
{% set python %}pypy-{{ prefix[4] }}.{{ prefix[5] }}{% endset %}
|
||||||
|
{% set cpython %}pp{{ prefix[4:5] }}{% endset %}
|
||||||
|
{% set toxpython %}pypy{{ prefix[4] }}.{{ prefix[5] }}{% endset %}
|
||||||
|
{% else %}
|
||||||
|
{% set python %}{{ prefix[2] }}.{{ prefix[3:] }}{% endset %}
|
||||||
|
{% set cpython %}cp{{ prefix[2:] }}{% endset %}
|
||||||
|
{% set toxpython %}python{{ prefix[2] }}.{{ prefix[3:] }}{% endset %}
|
||||||
|
{% endif %}
|
||||||
|
{% for os, python_arch, cibw_arch, wheel_arch, include_cover in [
|
||||||
|
['ubuntu', 'x64', 'x86_64', '*manylinux*', True],
|
||||||
|
['ubuntu', 'x64', 'x86_64', '*musllinux*', False],
|
||||||
|
['ubuntu', 'x64', 'aarch64', '*manylinux*', False],
|
||||||
|
['ubuntu', 'x64', 'aarch64', '*musllinux*', False],
|
||||||
|
['windows', 'x64', 'AMD64', '*', True],
|
||||||
|
['windows', 'x86', 'x86', '*', False],
|
||||||
|
['macos', 'x64', 'x86_64', '*', True],
|
||||||
|
] %}
|
||||||
|
{% if include_cover or ('nocov' in env and not prefix.startswith('pypy')) %}
|
||||||
|
{% set wheel_suffix = 'nocov' in env and wheel_arch.strip('*') %}
|
||||||
|
{% set name_suffix = '/' + wheel_suffix if wheel_suffix else '' %}
|
||||||
|
- name: '{{ env }} ({{ os }}/{{ cibw_arch }}{{ name_suffix }})'
|
||||||
|
python: '{{ python }}'
|
||||||
|
toxpython: '{{ toxpython }}'
|
||||||
|
python_arch: '{{ python_arch }}'
|
||||||
|
tox_env: '{{ env }}{% if 'cover' in env %},codecov{% endif %}'
|
||||||
|
cibw_arch: '{{ cibw_arch }}'
|
||||||
|
{% if 'nocov' in env and not prefix.startswith('pypy') %}
|
||||||
|
cibw_build: '{{ cpython }}-{{ wheel_arch }}'
|
||||||
|
{% else %}
|
||||||
|
cibw_build: false
|
||||||
|
{% endif %}
|
||||||
|
os: '{{ os }}-latest'
|
||||||
|
{% endif %}
|
||||||
|
{% endfor %}
|
||||||
|
{% endfor %}
|
||||||
|
steps:
|
||||||
|
- uses: docker/setup-qemu-action@v1
|
||||||
|
if: matrix.cibw_arch == 'aarch64'
|
||||||
|
with:
|
||||||
|
platforms: arm64
|
||||||
|
- uses: actions/checkout@v2
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- uses: actions/setup-python@v2
|
||||||
|
with:
|
||||||
|
python-version: {{ '${{ matrix.python }}' }}
|
||||||
|
architecture: {{ '${{ matrix.python_arch }}' }}
|
||||||
|
- name: install dependencies
|
||||||
|
run: |
|
||||||
|
python -mpip install --progress-bar=off twine tox cibuildwheel -r ci/requirements.txt
|
||||||
|
virtualenv --version
|
||||||
|
pip --version
|
||||||
|
tox --version
|
||||||
|
pip list --format=freeze
|
||||||
|
- name: install dependencies (gdb)
|
||||||
|
if: >
|
||||||
|
!matrix.cibw_build && matrix.os == 'ubuntu'
|
||||||
|
run: >
|
||||||
|
sudo apt-get install gdb
|
||||||
|
- name: cibw build and test
|
||||||
|
if: matrix.cibw_build
|
||||||
|
run: cibuildwheel
|
||||||
|
env:
|
||||||
|
TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}'
|
||||||
|
CIBW_ARCHS: '{{ '${{ matrix.cibw_arch }}' }}'
|
||||||
|
CIBW_BUILD: '{{ '${{ matrix.cibw_build }}' }}'
|
||||||
|
CIBW_BUILD_VERBOSITY: '3'
|
||||||
|
CIBW_TEST_REQUIRES: >
|
||||||
|
tox
|
||||||
|
tox-direct
|
||||||
|
CIBW_TEST_COMMAND: >
|
||||||
|
cd {project} &&
|
||||||
|
tox --skip-pkg-install --direct-yolo -e {{ '${{ matrix.tox_env }}' }} -v
|
||||||
|
CIBW_TEST_COMMAND_WINDOWS: >
|
||||||
|
cd /d {project} &&
|
||||||
|
tox --skip-pkg-install --direct-yolo -e {{ '${{ matrix.tox_env }}' }} -v
|
||||||
|
- name: regular build and test
|
||||||
|
env:
|
||||||
|
TOXPYTHON: '{{ '${{ matrix.toxpython }}' }}'
|
||||||
|
if: >
|
||||||
|
!matrix.cibw_build
|
||||||
|
run: >
|
||||||
|
tox -e {{ '${{ matrix.tox_env }}' }} -v
|
||||||
|
- name: check wheel
|
||||||
|
if: matrix.cibw_build
|
||||||
|
run: twine check wheelhouse/*.whl
|
||||||
|
- name: upload wheel
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: matrix.cibw_build
|
||||||
|
with:
|
||||||
|
path: wheelhouse/*.whl
|
|
@ -0,0 +1,10 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
PY3 = sys.version_info[0] >= 3
|
||||||
|
|
||||||
|
|
||||||
|
def pytest_ignore_collect(path, config):
|
||||||
|
basename = path.basename
|
||||||
|
|
||||||
|
if not PY3 and "py3" in basename or PY3 and "py2" in basename:
|
||||||
|
return True
|
|
@ -0,0 +1 @@
|
||||||
|
.. include:: ../AUTHORS.rst
|
|
@ -0,0 +1 @@
|
||||||
|
.. include:: ../CHANGELOG.rst
|
|
@ -0,0 +1,54 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
from __future__ import unicode_literals
|
||||||
|
|
||||||
|
import traceback
|
||||||
|
|
||||||
|
import sphinx_py3doc_enhanced_theme
|
||||||
|
|
||||||
|
extensions = [
|
||||||
|
'sphinx.ext.autodoc',
|
||||||
|
'sphinx.ext.autosummary',
|
||||||
|
'sphinx.ext.coverage',
|
||||||
|
'sphinx.ext.doctest',
|
||||||
|
'sphinx.ext.extlinks',
|
||||||
|
'sphinx.ext.ifconfig',
|
||||||
|
'sphinx.ext.napoleon',
|
||||||
|
'sphinx.ext.todo',
|
||||||
|
'sphinx.ext.viewcode',
|
||||||
|
]
|
||||||
|
source_suffix = '.rst'
|
||||||
|
master_doc = 'index'
|
||||||
|
project = 'lazy-object-proxy'
|
||||||
|
year = '2014-2021'
|
||||||
|
author = 'Ionel Cristian Mărieș'
|
||||||
|
copyright = '{0}, {1}'.format(year, author)
|
||||||
|
try:
|
||||||
|
from pkg_resources import get_distribution
|
||||||
|
version = release = get_distribution('lazy_object_proxy').version
|
||||||
|
except Exception:
|
||||||
|
traceback.print_exc()
|
||||||
|
version = release = '1.7.1'
|
||||||
|
|
||||||
|
pygments_style = 'trac'
|
||||||
|
templates_path = ['.']
|
||||||
|
extlinks = {
|
||||||
|
'issue': ('https://github.com/ionelmc/python-lazy-object-proxy/issues/%s', '#'),
|
||||||
|
'pr': ('https://github.com/ionelmc/python-lazy-object-proxy/pull/%s', 'PR #'),
|
||||||
|
}
|
||||||
|
html_theme = "sphinx_py3doc_enhanced_theme"
|
||||||
|
html_theme_path = [sphinx_py3doc_enhanced_theme.get_html_theme_path()]
|
||||||
|
html_theme_options = {
|
||||||
|
'githuburl': 'https://github.com/ionelmc/python-lazy-object-proxy/'
|
||||||
|
}
|
||||||
|
|
||||||
|
html_use_smartypants = True
|
||||||
|
html_last_updated_fmt = '%b %d, %Y'
|
||||||
|
html_split_index = False
|
||||||
|
html_sidebars = {
|
||||||
|
'**': ['searchbox.html', 'globaltoc.html', 'sourcelink.html'],
|
||||||
|
}
|
||||||
|
html_short_title = '%s-%s' % (project, version)
|
||||||
|
|
||||||
|
napoleon_use_ivar = True
|
||||||
|
napoleon_use_rtype = False
|
||||||
|
napoleon_use_param = False
|
|
@ -0,0 +1 @@
|
||||||
|
.. include:: ../CONTRIBUTING.rst
|
|
@ -0,0 +1,21 @@
|
||||||
|
========
|
||||||
|
Contents
|
||||||
|
========
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
readme
|
||||||
|
installation
|
||||||
|
usage
|
||||||
|
contributing
|
||||||
|
authors
|
||||||
|
changelog
|
||||||
|
|
||||||
|
Indices and tables
|
||||||
|
==================
|
||||||
|
|
||||||
|
* :ref:`genindex`
|
||||||
|
* :ref:`modindex`
|
||||||
|
* :ref:`search`
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
============
|
||||||
|
Installation
|
||||||
|
============
|
||||||
|
|
||||||
|
At the command line::
|
||||||
|
|
||||||
|
pip install lazy-object-proxy
|
|
@ -0,0 +1 @@
|
||||||
|
.. include:: ../README.rst
|
|
@ -0,0 +1,2 @@
|
||||||
|
sphinx>=1.3
|
||||||
|
sphinx-py3doc-enhanced-theme
|
|
@ -0,0 +1,11 @@
|
||||||
|
builtin
|
||||||
|
builtins
|
||||||
|
classmethod
|
||||||
|
staticmethod
|
||||||
|
classmethods
|
||||||
|
staticmethods
|
||||||
|
args
|
||||||
|
kwargs
|
||||||
|
callstack
|
||||||
|
Changelog
|
||||||
|
Indices
|
|
@ -0,0 +1,7 @@
|
||||||
|
=====
|
||||||
|
Usage
|
||||||
|
=====
|
||||||
|
|
||||||
|
To use lazy-object-proxy in a project::
|
||||||
|
|
||||||
|
import lazy_object_proxy
|
|
@ -0,0 +1,6 @@
|
||||||
|
[build-system]
|
||||||
|
requires = [
|
||||||
|
"setuptools>=30.3.0",
|
||||||
|
"wheel",
|
||||||
|
"setuptools_scm>=3.3.1",
|
||||||
|
]
|
|
@ -0,0 +1,48 @@
|
||||||
|
[options]
|
||||||
|
setup_requires =
|
||||||
|
setuptools_scm>=3.3.1
|
||||||
|
|
||||||
|
[flake8]
|
||||||
|
max-line-length = 140
|
||||||
|
exclude = .tox,.eggs,ci/templates,build,dist
|
||||||
|
|
||||||
|
[tool:pytest]
|
||||||
|
# If a pytest section is found in one of the possible config files
|
||||||
|
# (pytest.ini, tox.ini or setup.cfg), then pytest will not look for any others,
|
||||||
|
# so if you add a pytest config section elsewhere,
|
||||||
|
# you will need to delete this section from setup.cfg.
|
||||||
|
norecursedirs =
|
||||||
|
.git
|
||||||
|
.tox
|
||||||
|
.env
|
||||||
|
dist
|
||||||
|
build
|
||||||
|
migrations
|
||||||
|
|
||||||
|
python_files =
|
||||||
|
test_*.py
|
||||||
|
*_test.py
|
||||||
|
tests.py
|
||||||
|
markers =
|
||||||
|
xfail_subclass: Expected test to fail with a subclass of Proxy.
|
||||||
|
xfail_simple: Expected test to fail on the `simple` implementation.
|
||||||
|
addopts =
|
||||||
|
-ra
|
||||||
|
--strict-markers
|
||||||
|
--ignore=docs/conf.py
|
||||||
|
--ignore=setup.py
|
||||||
|
--ignore=ci
|
||||||
|
--ignore=.eggs
|
||||||
|
--doctest-modules
|
||||||
|
--doctest-glob=\*.rst
|
||||||
|
--tb=short
|
||||||
|
testpaths =
|
||||||
|
tests
|
||||||
|
|
||||||
|
[tool:isort]
|
||||||
|
force_single_line = True
|
||||||
|
line_length = 120
|
||||||
|
known_first_party = lazy_object_proxy
|
||||||
|
default_section = THIRDPARTY
|
||||||
|
forced_separate = test_lazy_object_proxy
|
||||||
|
skip = .tox,.eggs,ci/templates,build,dist
|
|
@ -0,0 +1,147 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
|
# -*- encoding: utf-8 -*-
|
||||||
|
from __future__ import absolute_import
|
||||||
|
from __future__ import print_function
|
||||||
|
|
||||||
|
import io
|
||||||
|
import os
|
||||||
|
import platform
|
||||||
|
import re
|
||||||
|
import sys
|
||||||
|
from glob import glob
|
||||||
|
from os.path import basename
|
||||||
|
from os.path import dirname
|
||||||
|
from os.path import join
|
||||||
|
from os.path import relpath
|
||||||
|
from os.path import splitext
|
||||||
|
|
||||||
|
from setuptools import Extension
|
||||||
|
from setuptools import find_packages
|
||||||
|
from setuptools import setup
|
||||||
|
from setuptools.command.build_ext import build_ext
|
||||||
|
from setuptools.dist import Distribution
|
||||||
|
|
||||||
|
# Enable code coverage for C code: we can't use CFLAGS=-coverage in tox.ini, since that may mess with compiling
|
||||||
|
# dependencies (e.g. numpy). Therefore we set SETUPPY_CFLAGS=-coverage in tox.ini and copy it to CFLAGS here (after
|
||||||
|
# deps have been safely installed).
|
||||||
|
if 'TOX_ENV_NAME' in os.environ and os.environ.get('SETUPPY_EXT_COVERAGE') == 'yes' and platform.system() == 'Linux':
|
||||||
|
CFLAGS = os.environ['CFLAGS'] = '-fprofile-arcs -ftest-coverage'
|
||||||
|
LFLAGS = os.environ['LFLAGS'] = '-lgcov'
|
||||||
|
else:
|
||||||
|
CFLAGS = ''
|
||||||
|
LFLAGS = ''
|
||||||
|
|
||||||
|
|
||||||
|
class OptionalBuildExt(build_ext):
|
||||||
|
"""Allow the building of C extensions to fail."""
|
||||||
|
def run(self):
|
||||||
|
try:
|
||||||
|
super().run()
|
||||||
|
except Exception as e:
|
||||||
|
self._unavailable(e)
|
||||||
|
self.extensions = [] # avoid copying missing files (it would fail).
|
||||||
|
|
||||||
|
def _unavailable(self, e):
|
||||||
|
print('*' * 80)
|
||||||
|
print('''WARNING:
|
||||||
|
|
||||||
|
An optional code optimization (C extension) could not be compiled.
|
||||||
|
|
||||||
|
Optimizations for this package will not be available!
|
||||||
|
''')
|
||||||
|
|
||||||
|
print('CAUSE:')
|
||||||
|
print('')
|
||||||
|
print(' ' + repr(e))
|
||||||
|
print('*' * 80)
|
||||||
|
|
||||||
|
|
||||||
|
def read(*names, **kwargs):
|
||||||
|
with io.open(
|
||||||
|
join(dirname(__file__), *names),
|
||||||
|
encoding=kwargs.get('encoding', 'utf8')
|
||||||
|
) as fh:
|
||||||
|
return fh.read()
|
||||||
|
|
||||||
|
|
||||||
|
class BinaryDistribution(Distribution):
|
||||||
|
"""Distribution which almost always forces a binary package with platform name"""
|
||||||
|
def has_ext_modules(self):
|
||||||
|
return super().has_ext_modules() or not os.environ.get('SETUPPY_ALLOW_PURE')
|
||||||
|
|
||||||
|
|
||||||
|
setup(
|
||||||
|
name='lazy-object-proxy',
|
||||||
|
use_scm_version={
|
||||||
|
'local_scheme': 'dirty-tag',
|
||||||
|
'write_to': 'src/lazy_object_proxy/_version.py',
|
||||||
|
'fallback_version': '1.7.1',
|
||||||
|
},
|
||||||
|
license='BSD-2-Clause',
|
||||||
|
description='A fast and thorough lazy object proxy.',
|
||||||
|
long_description='%s\n%s' % (
|
||||||
|
re.compile('^.. start-badges.*^.. end-badges', re.M | re.S).sub('', read('README.rst')),
|
||||||
|
re.sub(':[a-z]+:`~?(.*?)`', r'``\1``', read('CHANGELOG.rst'))
|
||||||
|
),
|
||||||
|
author='Ionel Cristian Mărieș',
|
||||||
|
author_email='contact@ionelmc.ro',
|
||||||
|
url='https://github.com/ionelmc/python-lazy-object-proxy',
|
||||||
|
packages=find_packages('src'),
|
||||||
|
package_dir={'': 'src'},
|
||||||
|
py_modules=[splitext(basename(path))[0] for path in glob('src/*.py')],
|
||||||
|
include_package_data=False,
|
||||||
|
zip_safe=False,
|
||||||
|
classifiers=[
|
||||||
|
# complete classifier list: http://pypi.python.org/pypi?%3Aaction=list_classifiers
|
||||||
|
'Development Status :: 5 - Production/Stable',
|
||||||
|
'Intended Audience :: Developers',
|
||||||
|
'License :: OSI Approved :: BSD License',
|
||||||
|
'Operating System :: Unix',
|
||||||
|
'Operating System :: POSIX',
|
||||||
|
'Operating System :: Microsoft :: Windows',
|
||||||
|
'Programming Language :: Python',
|
||||||
|
'Programming Language :: Python :: 3 :: Only',
|
||||||
|
'Programming Language :: Python :: 3.6',
|
||||||
|
'Programming Language :: Python :: 3.7',
|
||||||
|
'Programming Language :: Python :: 3.8',
|
||||||
|
'Programming Language :: Python :: 3.9',
|
||||||
|
'Programming Language :: Python :: 3.10',
|
||||||
|
'Programming Language :: Python :: Implementation :: CPython',
|
||||||
|
'Programming Language :: Python :: Implementation :: PyPy',
|
||||||
|
# uncomment if you test on these interpreters:
|
||||||
|
# 'Programming Language :: Python :: Implementation :: IronPython',
|
||||||
|
# 'Programming Language :: Python :: Implementation :: Jython',
|
||||||
|
# 'Programming Language :: Python :: Implementation :: Stackless',
|
||||||
|
'Topic :: Utilities',
|
||||||
|
],
|
||||||
|
project_urls={
|
||||||
|
'Documentation': 'https://python-lazy-object-proxy.readthedocs.io/',
|
||||||
|
'Changelog': 'https://python-lazy-object-proxy.readthedocs.io/en/latest/changelog.html',
|
||||||
|
'Issue Tracker': 'https://github.com/ionelmc/python-lazy-object-proxy/issues',
|
||||||
|
},
|
||||||
|
keywords=[
|
||||||
|
# eg: 'keyword1', 'keyword2', 'keyword3',
|
||||||
|
],
|
||||||
|
python_requires='>=3.6',
|
||||||
|
install_requires=[
|
||||||
|
# eg: 'aspectlib==1.1.1', 'six>=1.7',
|
||||||
|
],
|
||||||
|
extras_require={
|
||||||
|
# eg:
|
||||||
|
# 'rst': ['docutils>=0.11'],
|
||||||
|
# ':python_version=="2.6"': ['argparse'],
|
||||||
|
},
|
||||||
|
cmdclass={'build_ext': OptionalBuildExt},
|
||||||
|
ext_modules=[] if hasattr(sys, 'pypy_version_info') else [
|
||||||
|
Extension(
|
||||||
|
splitext(relpath(path, 'src').replace(os.sep, '.'))[0],
|
||||||
|
sources=[path],
|
||||||
|
extra_compile_args=CFLAGS.split(),
|
||||||
|
extra_link_args=LFLAGS.split(),
|
||||||
|
include_dirs=[dirname(path)]
|
||||||
|
)
|
||||||
|
for root, _, _ in os.walk('src')
|
||||||
|
for path in glob(join(root, '*.c'))
|
||||||
|
],
|
||||||
|
distclass=BinaryDistribution,
|
||||||
|
)
|
|
@ -0,0 +1,23 @@
|
||||||
|
try:
|
||||||
|
import copy_reg as copyreg
|
||||||
|
except ImportError:
|
||||||
|
import copyreg
|
||||||
|
|
||||||
|
from .utils import identity
|
||||||
|
|
||||||
|
copyreg.constructor(identity)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from .cext import Proxy
|
||||||
|
from .cext import identity
|
||||||
|
except ImportError:
|
||||||
|
from .slots import Proxy
|
||||||
|
else:
|
||||||
|
copyreg.constructor(identity)
|
||||||
|
|
||||||
|
try:
|
||||||
|
from ._version import version as __version__
|
||||||
|
except ImportError:
|
||||||
|
__version__ = '1.7.1'
|
||||||
|
|
||||||
|
__all__ = "Proxy",
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,14 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
PY2 = sys.version_info[0] == 2
|
||||||
|
PY3 = sys.version_info[0] == 3
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
string_types = str, bytes
|
||||||
|
else:
|
||||||
|
string_types = basestring, # noqa: F821
|
||||||
|
|
||||||
|
|
||||||
|
def with_metaclass(meta, *bases):
|
||||||
|
"""Create a base class with a metaclass."""
|
||||||
|
return meta("NewBase", bases, {})
|
|
@ -0,0 +1,278 @@
|
||||||
|
import operator
|
||||||
|
|
||||||
|
from .compat import PY2
|
||||||
|
from .compat import PY3
|
||||||
|
from .compat import string_types
|
||||||
|
from .compat import with_metaclass
|
||||||
|
from .utils import await_
|
||||||
|
from .utils import cached_property
|
||||||
|
from .utils import identity
|
||||||
|
|
||||||
|
|
||||||
|
def make_proxy_method(code):
|
||||||
|
def proxy_wrapper(self, *args):
|
||||||
|
return code(self.__wrapped__, *args)
|
||||||
|
|
||||||
|
return proxy_wrapper
|
||||||
|
|
||||||
|
|
||||||
|
class _ProxyMethods(object):
|
||||||
|
# We use properties to override the values of __module__ and
|
||||||
|
# __doc__. If we add these in ObjectProxy, the derived class
|
||||||
|
# __dict__ will still be setup to have string variants of these
|
||||||
|
# attributes and the rules of descriptors means that they appear to
|
||||||
|
# take precedence over the properties in the base class. To avoid
|
||||||
|
# that, we copy the properties into the derived class type itself
|
||||||
|
# via a meta class. In that way the properties will always take
|
||||||
|
# precedence.
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __module__(self):
|
||||||
|
return self.__wrapped__.__module__
|
||||||
|
|
||||||
|
@__module__.setter
|
||||||
|
def __module__(self, value):
|
||||||
|
self.__wrapped__.__module__ = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __doc__(self):
|
||||||
|
return self.__wrapped__.__doc__
|
||||||
|
|
||||||
|
@__doc__.setter
|
||||||
|
def __doc__(self, value):
|
||||||
|
self.__wrapped__.__doc__ = value
|
||||||
|
|
||||||
|
# Need to also propagate the special __weakref__ attribute for case
|
||||||
|
# where decorating classes which will define this. If do not define
|
||||||
|
# it and use a function like inspect.getmembers() on a decorator
|
||||||
|
# class it will fail. This can't be in the derived classes.
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __weakref__(self):
|
||||||
|
return self.__wrapped__.__weakref__
|
||||||
|
|
||||||
|
|
||||||
|
class _ProxyMetaType(type):
|
||||||
|
def __new__(cls, name, bases, dictionary):
|
||||||
|
# Copy our special properties into the class so that they
|
||||||
|
# always take precedence over attributes of the same name added
|
||||||
|
# during construction of a derived class. This is to save
|
||||||
|
# duplicating the implementation for them in all derived classes.
|
||||||
|
|
||||||
|
dictionary.update(vars(_ProxyMethods))
|
||||||
|
dictionary.pop('__dict__')
|
||||||
|
|
||||||
|
return type.__new__(cls, name, bases, dictionary)
|
||||||
|
|
||||||
|
|
||||||
|
class Proxy(with_metaclass(_ProxyMetaType)):
|
||||||
|
__factory__ = None
|
||||||
|
|
||||||
|
def __init__(self, factory):
|
||||||
|
self.__dict__['__factory__'] = factory
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __resolved__(self):
|
||||||
|
return '__wrapped__' in self.__dict__
|
||||||
|
|
||||||
|
@cached_property
|
||||||
|
def __wrapped__(self):
|
||||||
|
self = self.__dict__
|
||||||
|
if '__factory__' in self:
|
||||||
|
factory = self['__factory__']
|
||||||
|
return factory()
|
||||||
|
else:
|
||||||
|
raise ValueError("Proxy hasn't been initiated: __factory__ is missing.")
|
||||||
|
|
||||||
|
__name__ = property(make_proxy_method(operator.attrgetter('__name__')))
|
||||||
|
__class__ = property(make_proxy_method(operator.attrgetter('__class__')))
|
||||||
|
__annotations__ = property(make_proxy_method(operator.attrgetter('__anotations__')))
|
||||||
|
__dir__ = make_proxy_method(dir)
|
||||||
|
__str__ = make_proxy_method(str)
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
__bytes__ = make_proxy_method(bytes)
|
||||||
|
|
||||||
|
def __repr__(self, __getattr__=object.__getattribute__):
|
||||||
|
if '__wrapped__' in self.__dict__:
|
||||||
|
return '<{} at 0x{:x} wrapping {!r} at 0x{:x} with factory {!r}>'.format(
|
||||||
|
type(self).__name__, id(self),
|
||||||
|
self.__wrapped__, id(self.__wrapped__),
|
||||||
|
self.__factory__
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return '<{} at 0x{:x} with factory {!r}>'.format(
|
||||||
|
type(self).__name__, id(self),
|
||||||
|
self.__factory__
|
||||||
|
)
|
||||||
|
|
||||||
|
def __fspath__(self):
|
||||||
|
wrapped = self.__wrapped__
|
||||||
|
if isinstance(wrapped, string_types):
|
||||||
|
return wrapped
|
||||||
|
else:
|
||||||
|
fspath = getattr(wrapped, '__fspath__', None)
|
||||||
|
if fspath is None:
|
||||||
|
return wrapped
|
||||||
|
else:
|
||||||
|
return fspath()
|
||||||
|
|
||||||
|
__reversed__ = make_proxy_method(reversed)
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
__round__ = make_proxy_method(round)
|
||||||
|
|
||||||
|
__lt__ = make_proxy_method(operator.lt)
|
||||||
|
__le__ = make_proxy_method(operator.le)
|
||||||
|
__eq__ = make_proxy_method(operator.eq)
|
||||||
|
__ne__ = make_proxy_method(operator.ne)
|
||||||
|
__gt__ = make_proxy_method(operator.gt)
|
||||||
|
__ge__ = make_proxy_method(operator.ge)
|
||||||
|
__hash__ = make_proxy_method(hash)
|
||||||
|
__nonzero__ = make_proxy_method(bool)
|
||||||
|
__bool__ = make_proxy_method(bool)
|
||||||
|
|
||||||
|
def __setattr__(self, name, value):
|
||||||
|
if hasattr(type(self), name):
|
||||||
|
self.__dict__[name] = value
|
||||||
|
else:
|
||||||
|
setattr(self.__wrapped__, name, value)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
if name in ('__wrapped__', '__factory__'):
|
||||||
|
raise AttributeError(name)
|
||||||
|
else:
|
||||||
|
return getattr(self.__wrapped__, name)
|
||||||
|
|
||||||
|
def __delattr__(self, name):
|
||||||
|
if hasattr(type(self), name):
|
||||||
|
del self.__dict__[name]
|
||||||
|
else:
|
||||||
|
delattr(self.__wrapped__, name)
|
||||||
|
|
||||||
|
__add__ = make_proxy_method(operator.add)
|
||||||
|
__sub__ = make_proxy_method(operator.sub)
|
||||||
|
__mul__ = make_proxy_method(operator.mul)
|
||||||
|
__div__ = make_proxy_method(operator.div if PY2 else operator.truediv)
|
||||||
|
__truediv__ = make_proxy_method(operator.truediv)
|
||||||
|
__floordiv__ = make_proxy_method(operator.floordiv)
|
||||||
|
__mod__ = make_proxy_method(operator.mod)
|
||||||
|
__divmod__ = make_proxy_method(divmod)
|
||||||
|
__pow__ = make_proxy_method(pow)
|
||||||
|
__lshift__ = make_proxy_method(operator.lshift)
|
||||||
|
__rshift__ = make_proxy_method(operator.rshift)
|
||||||
|
__and__ = make_proxy_method(operator.and_)
|
||||||
|
__xor__ = make_proxy_method(operator.xor)
|
||||||
|
__or__ = make_proxy_method(operator.or_)
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return other + self.__wrapped__
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return other - self.__wrapped__
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
return other * self.__wrapped__
|
||||||
|
|
||||||
|
def __rdiv__(self, other):
|
||||||
|
return operator.div(other, self.__wrapped__)
|
||||||
|
|
||||||
|
def __rtruediv__(self, other):
|
||||||
|
return operator.truediv(other, self.__wrapped__)
|
||||||
|
|
||||||
|
def __rfloordiv__(self, other):
|
||||||
|
return other // self.__wrapped__
|
||||||
|
|
||||||
|
def __rmod__(self, other):
|
||||||
|
return other % self.__wrapped__
|
||||||
|
|
||||||
|
def __rdivmod__(self, other):
|
||||||
|
return divmod(other, self.__wrapped__)
|
||||||
|
|
||||||
|
def __rpow__(self, other, *args):
|
||||||
|
return pow(other, self.__wrapped__, *args)
|
||||||
|
|
||||||
|
def __rlshift__(self, other):
|
||||||
|
return other << self.__wrapped__
|
||||||
|
|
||||||
|
def __rrshift__(self, other):
|
||||||
|
return other >> self.__wrapped__
|
||||||
|
|
||||||
|
def __rand__(self, other):
|
||||||
|
return other & self.__wrapped__
|
||||||
|
|
||||||
|
def __rxor__(self, other):
|
||||||
|
return other ^ self.__wrapped__
|
||||||
|
|
||||||
|
def __ror__(self, other):
|
||||||
|
return other | self.__wrapped__
|
||||||
|
|
||||||
|
__iadd__ = make_proxy_method(operator.iadd)
|
||||||
|
__isub__ = make_proxy_method(operator.isub)
|
||||||
|
__imul__ = make_proxy_method(operator.imul)
|
||||||
|
__idiv__ = make_proxy_method(operator.idiv if PY2 else operator.itruediv)
|
||||||
|
__itruediv__ = make_proxy_method(operator.itruediv)
|
||||||
|
__ifloordiv__ = make_proxy_method(operator.ifloordiv)
|
||||||
|
__imod__ = make_proxy_method(operator.imod)
|
||||||
|
__ipow__ = make_proxy_method(operator.ipow)
|
||||||
|
__ilshift__ = make_proxy_method(operator.ilshift)
|
||||||
|
__irshift__ = make_proxy_method(operator.irshift)
|
||||||
|
__iand__ = make_proxy_method(operator.iand)
|
||||||
|
__ixor__ = make_proxy_method(operator.ixor)
|
||||||
|
__ior__ = make_proxy_method(operator.ior)
|
||||||
|
__neg__ = make_proxy_method(operator.neg)
|
||||||
|
__pos__ = make_proxy_method(operator.pos)
|
||||||
|
__abs__ = make_proxy_method(operator.abs)
|
||||||
|
__invert__ = make_proxy_method(operator.invert)
|
||||||
|
|
||||||
|
__int__ = make_proxy_method(int)
|
||||||
|
|
||||||
|
if PY2:
|
||||||
|
__long__ = make_proxy_method(long) # noqa
|
||||||
|
|
||||||
|
__float__ = make_proxy_method(float)
|
||||||
|
__oct__ = make_proxy_method(oct)
|
||||||
|
__hex__ = make_proxy_method(hex)
|
||||||
|
|
||||||
|
def __index__(self):
|
||||||
|
if hasattr(self.__wrapped__, '__index__'):
|
||||||
|
return operator.index(self.__wrapped__)
|
||||||
|
else:
|
||||||
|
return int(self.__wrapped__)
|
||||||
|
|
||||||
|
__len__ = make_proxy_method(len)
|
||||||
|
__contains__ = make_proxy_method(operator.contains)
|
||||||
|
__getitem__ = make_proxy_method(operator.getitem)
|
||||||
|
__setitem__ = make_proxy_method(operator.setitem)
|
||||||
|
__delitem__ = make_proxy_method(operator.delitem)
|
||||||
|
|
||||||
|
if PY2:
|
||||||
|
__getslice__ = make_proxy_method(operator.getslice)
|
||||||
|
__setslice__ = make_proxy_method(operator.setslice)
|
||||||
|
__delslice__ = make_proxy_method(operator.delslice)
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self.__wrapped__.__enter__()
|
||||||
|
|
||||||
|
def __exit__(self, *args, **kwargs):
|
||||||
|
return self.__wrapped__.__exit__(*args, **kwargs)
|
||||||
|
|
||||||
|
__iter__ = make_proxy_method(iter)
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.__wrapped__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return identity, (self.__wrapped__,)
|
||||||
|
|
||||||
|
def __reduce_ex__(self, protocol):
|
||||||
|
return identity, (self.__wrapped__,)
|
||||||
|
|
||||||
|
if await_:
|
||||||
|
from .utils import __aenter__
|
||||||
|
from .utils import __aexit__
|
||||||
|
from .utils import __aiter__
|
||||||
|
from .utils import __anext__
|
||||||
|
from .utils import __await__
|
||||||
|
|
||||||
|
__aiter__, __anext__, __await__, __aenter__, __aexit__ # noqa
|
|
@ -0,0 +1,452 @@
|
||||||
|
import operator
|
||||||
|
|
||||||
|
from .compat import PY2
|
||||||
|
from .compat import PY3
|
||||||
|
from .compat import string_types
|
||||||
|
from .compat import with_metaclass
|
||||||
|
from .utils import await_
|
||||||
|
from .utils import identity
|
||||||
|
|
||||||
|
|
||||||
|
class _ProxyMethods(object):
|
||||||
|
# We use properties to override the values of __module__ and
|
||||||
|
# __doc__. If we add these in ObjectProxy, the derived class
|
||||||
|
# __dict__ will still be setup to have string variants of these
|
||||||
|
# attributes and the rules of descriptors means that they appear to
|
||||||
|
# take precedence over the properties in the base class. To avoid
|
||||||
|
# that, we copy the properties into the derived class type itself
|
||||||
|
# via a meta class. In that way the properties will always take
|
||||||
|
# precedence.
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __module__(self):
|
||||||
|
return self.__wrapped__.__module__
|
||||||
|
|
||||||
|
@__module__.setter
|
||||||
|
def __module__(self, value):
|
||||||
|
self.__wrapped__.__module__ = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __doc__(self):
|
||||||
|
return self.__wrapped__.__doc__
|
||||||
|
|
||||||
|
@__doc__.setter
|
||||||
|
def __doc__(self, value):
|
||||||
|
self.__wrapped__.__doc__ = value
|
||||||
|
|
||||||
|
# We similar use a property for __dict__. We need __dict__ to be
|
||||||
|
# explicit to ensure that vars() works as expected.
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __dict__(self):
|
||||||
|
return self.__wrapped__.__dict__
|
||||||
|
|
||||||
|
# Need to also propagate the special __weakref__ attribute for case
|
||||||
|
# where decorating classes which will define this. If do not define
|
||||||
|
# it and use a function like inspect.getmembers() on a decorator
|
||||||
|
# class it will fail. This can't be in the derived classes.
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __weakref__(self):
|
||||||
|
return self.__wrapped__.__weakref__
|
||||||
|
|
||||||
|
|
||||||
|
class _ProxyMetaType(type):
|
||||||
|
def __new__(cls, name, bases, dictionary):
|
||||||
|
# Copy our special properties into the class so that they
|
||||||
|
# always take precedence over attributes of the same name added
|
||||||
|
# during construction of a derived class. This is to save
|
||||||
|
# duplicating the implementation for them in all derived classes.
|
||||||
|
|
||||||
|
dictionary.update(vars(_ProxyMethods))
|
||||||
|
|
||||||
|
return type.__new__(cls, name, bases, dictionary)
|
||||||
|
|
||||||
|
|
||||||
|
class Proxy(with_metaclass(_ProxyMetaType)):
|
||||||
|
"""
|
||||||
|
A proxy implementation in pure Python, using slots. You can subclass this to add
|
||||||
|
local methods or attributes, or enable __dict__.
|
||||||
|
|
||||||
|
The most important internals:
|
||||||
|
|
||||||
|
* ``__factory__`` is the callback that "materializes" the object we proxy to.
|
||||||
|
* ``__target__`` will contain the object we proxy to, once it's "materialized".
|
||||||
|
* ``__resolved__`` is a boolean, `True` if factory was called.
|
||||||
|
* ``__wrapped__`` is a property that does either:
|
||||||
|
|
||||||
|
* return ``__target__`` if it's set.
|
||||||
|
* calls ``__factory__``, saves result to ``__target__`` and returns said result.
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = '__target__', '__factory__'
|
||||||
|
|
||||||
|
def __init__(self, factory):
|
||||||
|
object.__setattr__(self, '__factory__', factory)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __resolved__(self, __getattr__=object.__getattribute__):
|
||||||
|
try:
|
||||||
|
__getattr__(self, '__target__')
|
||||||
|
except AttributeError:
|
||||||
|
return False
|
||||||
|
else:
|
||||||
|
return True
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __wrapped__(self, __getattr__=object.__getattribute__, __setattr__=object.__setattr__,
|
||||||
|
__delattr__=object.__delattr__):
|
||||||
|
try:
|
||||||
|
return __getattr__(self, '__target__')
|
||||||
|
except AttributeError:
|
||||||
|
try:
|
||||||
|
factory = __getattr__(self, '__factory__')
|
||||||
|
except AttributeError:
|
||||||
|
raise ValueError("Proxy hasn't been initiated: __factory__ is missing.")
|
||||||
|
target = factory()
|
||||||
|
__setattr__(self, '__target__', target)
|
||||||
|
return target
|
||||||
|
|
||||||
|
@__wrapped__.deleter
|
||||||
|
def __wrapped__(self, __delattr__=object.__delattr__):
|
||||||
|
__delattr__(self, '__target__')
|
||||||
|
|
||||||
|
@__wrapped__.setter
|
||||||
|
def __wrapped__(self, target, __setattr__=object.__setattr__):
|
||||||
|
__setattr__(self, '__target__', target)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __name__(self):
|
||||||
|
return self.__wrapped__.__name__
|
||||||
|
|
||||||
|
@__name__.setter
|
||||||
|
def __name__(self, value):
|
||||||
|
self.__wrapped__.__name__ = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __class__(self):
|
||||||
|
return self.__wrapped__.__class__
|
||||||
|
|
||||||
|
@__class__.setter # noqa: F811
|
||||||
|
def __class__(self, value): # noqa: F811
|
||||||
|
self.__wrapped__.__class__ = value
|
||||||
|
|
||||||
|
@property
|
||||||
|
def __annotations__(self):
|
||||||
|
return self.__wrapped__.__anotations__
|
||||||
|
|
||||||
|
@__annotations__.setter
|
||||||
|
def __annotations__(self, value):
|
||||||
|
self.__wrapped__.__annotations__ = value
|
||||||
|
|
||||||
|
def __dir__(self):
|
||||||
|
return dir(self.__wrapped__)
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return str(self.__wrapped__)
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
def __bytes__(self):
|
||||||
|
return bytes(self.__wrapped__)
|
||||||
|
|
||||||
|
def __repr__(self, __getattr__=object.__getattribute__):
|
||||||
|
try:
|
||||||
|
target = __getattr__(self, '__target__')
|
||||||
|
except AttributeError:
|
||||||
|
return '<{} at 0x{:x} with factory {!r}>'.format(
|
||||||
|
type(self).__name__, id(self),
|
||||||
|
self.__factory__
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return '<{} at 0x{:x} wrapping {!r} at 0x{:x} with factory {!r}>'.format(
|
||||||
|
type(self).__name__, id(self),
|
||||||
|
target, id(target),
|
||||||
|
self.__factory__
|
||||||
|
)
|
||||||
|
|
||||||
|
def __fspath__(self):
|
||||||
|
wrapped = self.__wrapped__
|
||||||
|
if isinstance(wrapped, string_types):
|
||||||
|
return wrapped
|
||||||
|
else:
|
||||||
|
fspath = getattr(wrapped, '__fspath__', None)
|
||||||
|
if fspath is None:
|
||||||
|
return wrapped
|
||||||
|
else:
|
||||||
|
return fspath()
|
||||||
|
|
||||||
|
def __reversed__(self):
|
||||||
|
return reversed(self.__wrapped__)
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
def __round__(self):
|
||||||
|
return round(self.__wrapped__)
|
||||||
|
|
||||||
|
def __lt__(self, other):
|
||||||
|
return self.__wrapped__ < other
|
||||||
|
|
||||||
|
def __le__(self, other):
|
||||||
|
return self.__wrapped__ <= other
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return self.__wrapped__ == other
|
||||||
|
|
||||||
|
def __ne__(self, other):
|
||||||
|
return self.__wrapped__ != other
|
||||||
|
|
||||||
|
def __gt__(self, other):
|
||||||
|
return self.__wrapped__ > other
|
||||||
|
|
||||||
|
def __ge__(self, other):
|
||||||
|
return self.__wrapped__ >= other
|
||||||
|
|
||||||
|
def __hash__(self):
|
||||||
|
return hash(self.__wrapped__)
|
||||||
|
|
||||||
|
def __nonzero__(self):
|
||||||
|
return bool(self.__wrapped__)
|
||||||
|
|
||||||
|
def __bool__(self):
|
||||||
|
return bool(self.__wrapped__)
|
||||||
|
|
||||||
|
def __setattr__(self, name, value, __setattr__=object.__setattr__):
|
||||||
|
if hasattr(type(self), name):
|
||||||
|
__setattr__(self, name, value)
|
||||||
|
else:
|
||||||
|
setattr(self.__wrapped__, name, value)
|
||||||
|
|
||||||
|
def __getattr__(self, name):
|
||||||
|
if name in ('__wrapped__', '__factory__'):
|
||||||
|
raise AttributeError(name)
|
||||||
|
else:
|
||||||
|
return getattr(self.__wrapped__, name)
|
||||||
|
|
||||||
|
def __delattr__(self, name, __delattr__=object.__delattr__):
|
||||||
|
if hasattr(type(self), name):
|
||||||
|
__delattr__(self, name)
|
||||||
|
else:
|
||||||
|
delattr(self.__wrapped__, name)
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return self.__wrapped__ + other
|
||||||
|
|
||||||
|
def __sub__(self, other):
|
||||||
|
return self.__wrapped__ - other
|
||||||
|
|
||||||
|
def __mul__(self, other):
|
||||||
|
return self.__wrapped__ * other
|
||||||
|
|
||||||
|
def __div__(self, other):
|
||||||
|
return operator.div(self.__wrapped__, other)
|
||||||
|
|
||||||
|
def __truediv__(self, other):
|
||||||
|
return operator.truediv(self.__wrapped__, other)
|
||||||
|
|
||||||
|
def __floordiv__(self, other):
|
||||||
|
return self.__wrapped__ // other
|
||||||
|
|
||||||
|
def __mod__(self, other):
|
||||||
|
return self.__wrapped__ % other
|
||||||
|
|
||||||
|
def __divmod__(self, other):
|
||||||
|
return divmod(self.__wrapped__, other)
|
||||||
|
|
||||||
|
def __pow__(self, other, *args):
|
||||||
|
return pow(self.__wrapped__, other, *args)
|
||||||
|
|
||||||
|
def __lshift__(self, other):
|
||||||
|
return self.__wrapped__ << other
|
||||||
|
|
||||||
|
def __rshift__(self, other):
|
||||||
|
return self.__wrapped__ >> other
|
||||||
|
|
||||||
|
def __and__(self, other):
|
||||||
|
return self.__wrapped__ & other
|
||||||
|
|
||||||
|
def __xor__(self, other):
|
||||||
|
return self.__wrapped__ ^ other
|
||||||
|
|
||||||
|
def __or__(self, other):
|
||||||
|
return self.__wrapped__ | other
|
||||||
|
|
||||||
|
def __radd__(self, other):
|
||||||
|
return other + self.__wrapped__
|
||||||
|
|
||||||
|
def __rsub__(self, other):
|
||||||
|
return other - self.__wrapped__
|
||||||
|
|
||||||
|
def __rmul__(self, other):
|
||||||
|
return other * self.__wrapped__
|
||||||
|
|
||||||
|
def __rdiv__(self, other):
|
||||||
|
return operator.div(other, self.__wrapped__)
|
||||||
|
|
||||||
|
def __rtruediv__(self, other):
|
||||||
|
return operator.truediv(other, self.__wrapped__)
|
||||||
|
|
||||||
|
def __rfloordiv__(self, other):
|
||||||
|
return other // self.__wrapped__
|
||||||
|
|
||||||
|
def __rmod__(self, other):
|
||||||
|
return other % self.__wrapped__
|
||||||
|
|
||||||
|
def __rdivmod__(self, other):
|
||||||
|
return divmod(other, self.__wrapped__)
|
||||||
|
|
||||||
|
def __rpow__(self, other, *args):
|
||||||
|
return pow(other, self.__wrapped__, *args)
|
||||||
|
|
||||||
|
def __rlshift__(self, other):
|
||||||
|
return other << self.__wrapped__
|
||||||
|
|
||||||
|
def __rrshift__(self, other):
|
||||||
|
return other >> self.__wrapped__
|
||||||
|
|
||||||
|
def __rand__(self, other):
|
||||||
|
return other & self.__wrapped__
|
||||||
|
|
||||||
|
def __rxor__(self, other):
|
||||||
|
return other ^ self.__wrapped__
|
||||||
|
|
||||||
|
def __ror__(self, other):
|
||||||
|
return other | self.__wrapped__
|
||||||
|
|
||||||
|
def __iadd__(self, other):
|
||||||
|
self.__wrapped__ += other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __isub__(self, other):
|
||||||
|
self.__wrapped__ -= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __imul__(self, other):
|
||||||
|
self.__wrapped__ *= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __idiv__(self, other):
|
||||||
|
self.__wrapped__ = operator.idiv(self.__wrapped__, other)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __itruediv__(self, other):
|
||||||
|
self.__wrapped__ = operator.itruediv(self.__wrapped__, other)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __ifloordiv__(self, other):
|
||||||
|
self.__wrapped__ //= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __imod__(self, other):
|
||||||
|
self.__wrapped__ %= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __ipow__(self, other):
|
||||||
|
self.__wrapped__ **= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __ilshift__(self, other):
|
||||||
|
self.__wrapped__ <<= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __irshift__(self, other):
|
||||||
|
self.__wrapped__ >>= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __iand__(self, other):
|
||||||
|
self.__wrapped__ &= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __ixor__(self, other):
|
||||||
|
self.__wrapped__ ^= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __ior__(self, other):
|
||||||
|
self.__wrapped__ |= other
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __neg__(self):
|
||||||
|
return -self.__wrapped__
|
||||||
|
|
||||||
|
def __pos__(self):
|
||||||
|
return +self.__wrapped__
|
||||||
|
|
||||||
|
def __abs__(self):
|
||||||
|
return abs(self.__wrapped__)
|
||||||
|
|
||||||
|
def __invert__(self):
|
||||||
|
return ~self.__wrapped__
|
||||||
|
|
||||||
|
def __int__(self):
|
||||||
|
return int(self.__wrapped__)
|
||||||
|
|
||||||
|
if PY2:
|
||||||
|
def __long__(self):
|
||||||
|
return long(self.__wrapped__) # noqa
|
||||||
|
|
||||||
|
def __float__(self):
|
||||||
|
return float(self.__wrapped__)
|
||||||
|
|
||||||
|
def __oct__(self):
|
||||||
|
return oct(self.__wrapped__)
|
||||||
|
|
||||||
|
def __hex__(self):
|
||||||
|
return hex(self.__wrapped__)
|
||||||
|
|
||||||
|
def __index__(self):
|
||||||
|
if hasattr(self.__wrapped__, '__index__'):
|
||||||
|
return operator.index(self.__wrapped__)
|
||||||
|
else:
|
||||||
|
return int(self.__wrapped__)
|
||||||
|
|
||||||
|
def __len__(self):
|
||||||
|
return len(self.__wrapped__)
|
||||||
|
|
||||||
|
def __contains__(self, value):
|
||||||
|
return value in self.__wrapped__
|
||||||
|
|
||||||
|
def __getitem__(self, key):
|
||||||
|
return self.__wrapped__[key]
|
||||||
|
|
||||||
|
def __setitem__(self, key, value):
|
||||||
|
self.__wrapped__[key] = value
|
||||||
|
|
||||||
|
def __delitem__(self, key):
|
||||||
|
del self.__wrapped__[key]
|
||||||
|
|
||||||
|
def __getslice__(self, i, j):
|
||||||
|
return self.__wrapped__[i:j]
|
||||||
|
|
||||||
|
def __setslice__(self, i, j, value):
|
||||||
|
self.__wrapped__[i:j] = value
|
||||||
|
|
||||||
|
def __delslice__(self, i, j):
|
||||||
|
del self.__wrapped__[i:j]
|
||||||
|
|
||||||
|
def __enter__(self):
|
||||||
|
return self.__wrapped__.__enter__()
|
||||||
|
|
||||||
|
def __exit__(self, *args, **kwargs):
|
||||||
|
return self.__wrapped__.__exit__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return iter(self.__wrapped__)
|
||||||
|
|
||||||
|
def __next__(self):
|
||||||
|
return next(self.__wrapped__)
|
||||||
|
|
||||||
|
def __call__(self, *args, **kwargs):
|
||||||
|
return self.__wrapped__(*args, **kwargs)
|
||||||
|
|
||||||
|
def __reduce__(self):
|
||||||
|
return identity, (self.__wrapped__,)
|
||||||
|
|
||||||
|
def __reduce_ex__(self, protocol):
|
||||||
|
return identity, (self.__wrapped__,)
|
||||||
|
|
||||||
|
if await_:
|
||||||
|
from .utils import __aenter__
|
||||||
|
from .utils import __aexit__
|
||||||
|
from .utils import __aiter__
|
||||||
|
from .utils import __anext__
|
||||||
|
from .utils import __await__
|
||||||
|
|
||||||
|
__aiter__, __anext__, __await__, __aenter__, __aexit__ # noqa
|
|
@ -0,0 +1,25 @@
|
||||||
|
# flake8: noqa
|
||||||
|
try:
|
||||||
|
from .utils_py3 import __aenter__
|
||||||
|
from .utils_py3 import __aexit__
|
||||||
|
from .utils_py3 import __aiter__
|
||||||
|
from .utils_py3 import __anext__
|
||||||
|
from .utils_py3 import __await__
|
||||||
|
from .utils_py3 import await_
|
||||||
|
except (ImportError, SyntaxError):
|
||||||
|
await_ = None
|
||||||
|
|
||||||
|
|
||||||
|
def identity(obj):
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
class cached_property(object):
|
||||||
|
def __init__(self, func):
|
||||||
|
self.func = func
|
||||||
|
|
||||||
|
def __get__(self, obj, cls):
|
||||||
|
if obj is None:
|
||||||
|
return self
|
||||||
|
value = obj.__dict__[self.func.__name__] = self.func(obj)
|
||||||
|
return value
|
|
@ -0,0 +1,44 @@
|
||||||
|
from collections.abc import Awaitable
|
||||||
|
from inspect import CO_ITERABLE_COROUTINE
|
||||||
|
from types import CoroutineType
|
||||||
|
from types import GeneratorType
|
||||||
|
|
||||||
|
|
||||||
|
async def do_await(obj):
|
||||||
|
return await obj
|
||||||
|
|
||||||
|
|
||||||
|
def do_yield_from(gen):
|
||||||
|
return (yield from gen)
|
||||||
|
|
||||||
|
|
||||||
|
def await_(obj):
|
||||||
|
obj_type = type(obj)
|
||||||
|
if (
|
||||||
|
obj_type is CoroutineType or
|
||||||
|
obj_type is GeneratorType and bool(obj.gi_code.co_flags & CO_ITERABLE_COROUTINE) or
|
||||||
|
isinstance(obj, Awaitable)
|
||||||
|
):
|
||||||
|
return do_await(obj).__await__()
|
||||||
|
else:
|
||||||
|
return do_yield_from(obj)
|
||||||
|
|
||||||
|
|
||||||
|
def __aiter__(self):
|
||||||
|
return self.__wrapped__.__aiter__()
|
||||||
|
|
||||||
|
|
||||||
|
async def __anext__(self):
|
||||||
|
return await self.__wrapped__.__anext__()
|
||||||
|
|
||||||
|
|
||||||
|
def __await__(self):
|
||||||
|
return await_(self.__wrapped__)
|
||||||
|
|
||||||
|
|
||||||
|
def __aenter__(self):
|
||||||
|
return self.__wrapped__.__aenter__()
|
||||||
|
|
||||||
|
|
||||||
|
def __aexit__(self, *args, **kwargs):
|
||||||
|
return self.__wrapped__.__aexit__(*args, **kwargs)
|
|
@ -0,0 +1,26 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
PY2 = sys.version_info[0] < 3
|
||||||
|
PY3 = sys.version_info[0] >= 3
|
||||||
|
|
||||||
|
if PY3:
|
||||||
|
import builtins
|
||||||
|
exec_ = getattr(builtins, "exec")
|
||||||
|
del builtins
|
||||||
|
|
||||||
|
else:
|
||||||
|
def exec_(_code_, _globs_=None, _locs_=None):
|
||||||
|
"""Execute code in a namespace."""
|
||||||
|
if _globs_ is None:
|
||||||
|
frame = sys._getframe(1)
|
||||||
|
_globs_ = frame.f_globals
|
||||||
|
if _locs_ is None:
|
||||||
|
_locs_ = frame.f_locals
|
||||||
|
del frame
|
||||||
|
elif _locs_ is None:
|
||||||
|
_locs_ = _globs_
|
||||||
|
exec("""exec _code_ in _globs_, _locs_""")
|
||||||
|
|
||||||
|
exec_("""def reraise(tp, value, tb=None):
|
||||||
|
raise tp, value, tb
|
||||||
|
""")
|
|
@ -0,0 +1,74 @@
|
||||||
|
import sys
|
||||||
|
|
||||||
|
import pytest
|
||||||
|
|
||||||
|
PYPY = '__pypy__' in sys.builtin_module_names
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session")
|
||||||
|
def lop_loader():
|
||||||
|
def load_implementation(name):
|
||||||
|
class FakeModule:
|
||||||
|
subclass = False
|
||||||
|
kind = name
|
||||||
|
if name == "slots":
|
||||||
|
from lazy_object_proxy.slots import Proxy
|
||||||
|
elif name == "simple":
|
||||||
|
from lazy_object_proxy.simple import Proxy
|
||||||
|
elif name == "cext":
|
||||||
|
try:
|
||||||
|
from lazy_object_proxy.cext import Proxy
|
||||||
|
except ImportError:
|
||||||
|
if PYPY:
|
||||||
|
pytest.skip(msg="C Extension not available.")
|
||||||
|
else:
|
||||||
|
raise
|
||||||
|
elif name == "objproxies":
|
||||||
|
Proxy = pytest.importorskip("objproxies").LazyProxy
|
||||||
|
elif name == "django":
|
||||||
|
Proxy = pytest.importorskip("django.utils.functional").SimpleLazyObject
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unsupported param: %r." % name)
|
||||||
|
|
||||||
|
Proxy
|
||||||
|
|
||||||
|
return FakeModule
|
||||||
|
|
||||||
|
return load_implementation
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session", params=[
|
||||||
|
"slots", "cext",
|
||||||
|
"simple",
|
||||||
|
# "external-django", "external-objproxies"
|
||||||
|
])
|
||||||
|
def lop_implementation(request, lop_loader):
|
||||||
|
return lop_loader(request.param)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="session", params=[True, False], ids=['subclassed', 'normal'])
|
||||||
|
def lop_subclass(request, lop_implementation):
|
||||||
|
if request.param:
|
||||||
|
class submod(lop_implementation):
|
||||||
|
subclass = True
|
||||||
|
Proxy = type("SubclassOf_" + lop_implementation.Proxy.__name__,
|
||||||
|
(lop_implementation.Proxy,), {})
|
||||||
|
|
||||||
|
return submod
|
||||||
|
else:
|
||||||
|
return lop_implementation
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(scope="function")
|
||||||
|
def lop(request, lop_subclass):
|
||||||
|
if request.node.get_closest_marker('xfail_subclass'):
|
||||||
|
request.applymarker(pytest.mark.xfail(
|
||||||
|
reason="This test can't work because subclassing disables certain "
|
||||||
|
"features like __doc__ and __module__ proxying."
|
||||||
|
))
|
||||||
|
if request.node.get_closest_marker('xfail_simple'):
|
||||||
|
request.applymarker(pytest.mark.xfail(
|
||||||
|
reason="The lazy_object_proxy.simple.Proxy has some limitations."
|
||||||
|
))
|
||||||
|
|
||||||
|
return lop_subclass
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,115 @@
|
||||||
|
[testenv:bootstrap]
|
||||||
|
deps =
|
||||||
|
jinja2
|
||||||
|
matrix
|
||||||
|
tox
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
python ci/bootstrap.py --no-env
|
||||||
|
passenv =
|
||||||
|
*
|
||||||
|
; a generative tox configuration, see: https://tox.readthedocs.io/en/latest/config.html#generative-envlist
|
||||||
|
|
||||||
|
[tox]
|
||||||
|
envlist =
|
||||||
|
clean,
|
||||||
|
check,
|
||||||
|
docs,
|
||||||
|
{py36,py37,py38,py39,py310,pypy37,pypy38}-{cover,nocov},
|
||||||
|
report
|
||||||
|
ignore_basepython_conflict = true
|
||||||
|
|
||||||
|
[testenv]
|
||||||
|
basepython =
|
||||||
|
pypy: {env:TOXPYTHON:pypy}
|
||||||
|
pypy37: {env:TOXPYTHON:pypy3.7}
|
||||||
|
pypy38: {env:TOXPYTHON:pypy3.8}
|
||||||
|
py27: {env:TOXPYTHON:python2.7}
|
||||||
|
py36: {env:TOXPYTHON:python3.6}
|
||||||
|
py37: {env:TOXPYTHON:python3.7}
|
||||||
|
py38: {env:TOXPYTHON:python3.8}
|
||||||
|
py39: {env:TOXPYTHON:python3.9}
|
||||||
|
py310: {env:TOXPYTHON:python3.10}
|
||||||
|
{bootstrap,clean,check,report,docs,codecov,coveralls,extension-coveralls}: {env:TOXPYTHON:python3}
|
||||||
|
setenv =
|
||||||
|
PYTHONPATH={toxinidir}/tests
|
||||||
|
PYTHONUNBUFFERED=yes
|
||||||
|
cover: SETUPPY_EXT_COVERAGE=yes
|
||||||
|
passenv =
|
||||||
|
*
|
||||||
|
usedevelop =
|
||||||
|
cover: true
|
||||||
|
nocov: false
|
||||||
|
wheel =
|
||||||
|
cover: false
|
||||||
|
nocov: true
|
||||||
|
deps =
|
||||||
|
pytest
|
||||||
|
pytest-benchmark
|
||||||
|
Django
|
||||||
|
objproxies==0.9.4
|
||||||
|
hunter
|
||||||
|
cover: pytest-cov
|
||||||
|
commands =
|
||||||
|
cover: python setup.py clean --all build_ext --force --inplace
|
||||||
|
nocov: {posargs:pytest -vv --ignore=src}
|
||||||
|
cover: {posargs:pytest --cov --cov-report=term-missing -vv}
|
||||||
|
|
||||||
|
[testenv:check]
|
||||||
|
deps =
|
||||||
|
docutils
|
||||||
|
flake8
|
||||||
|
readme-renderer
|
||||||
|
pygments
|
||||||
|
isort
|
||||||
|
setuptools-scm
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
python setup.py check --strict --metadata --restructuredtext
|
||||||
|
flake8
|
||||||
|
isort --verbose --check-only --diff --filter-files .
|
||||||
|
|
||||||
|
[testenv:docs]
|
||||||
|
usedevelop = true
|
||||||
|
install_command =
|
||||||
|
python -m pip install --no-use-pep517 {opts} {packages}
|
||||||
|
deps =
|
||||||
|
-r{toxinidir}/docs/requirements.txt
|
||||||
|
commands =
|
||||||
|
sphinx-build {posargs:-E} -b html docs dist/docs
|
||||||
|
sphinx-build -b linkcheck docs dist/docs
|
||||||
|
|
||||||
|
[testenv:coveralls]
|
||||||
|
deps =
|
||||||
|
coveralls
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
coveralls {env:COVERALLS_EXTRAS:--merge=extension-coveralls.json} []
|
||||||
|
|
||||||
|
[testenv:extension-coveralls]
|
||||||
|
deps =
|
||||||
|
cpp-coveralls
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
coveralls --build-root=. --include=src --dump=extension-coveralls.json []
|
||||||
|
|
||||||
|
[testenv:codecov]
|
||||||
|
deps =
|
||||||
|
codecov
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
codecov --gcov-root=. []
|
||||||
|
|
||||||
|
[testenv:report]
|
||||||
|
deps =
|
||||||
|
coverage
|
||||||
|
skip_install = true
|
||||||
|
commands =
|
||||||
|
coverage report
|
||||||
|
coverage html
|
||||||
|
|
||||||
|
[testenv:clean]
|
||||||
|
commands = coverage erase
|
||||||
|
skip_install = true
|
||||||
|
deps =
|
||||||
|
coverage
|
Loading…
Reference in New Issue