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