Merge branch 'main' into main
6
.git-blame-ignore-revs
Normal file
|
@ -0,0 +1,6 @@
|
|||
# Flake8
|
||||
8de95676e0fd89f2326b3953488ab66ff29cd2d0
|
||||
# Format with Black
|
||||
53a7e3500437a9fd5826bc04758f7116bd7e52dc
|
||||
# Format the C code with ClangFormat
|
||||
46b7e86bab79450ec0a2866c6c0c679afb659d17
|
4
.github/workflows/cifuzz.yml
vendored
|
@ -42,13 +42,13 @@ jobs:
|
|||
language: python
|
||||
dry-run: false
|
||||
- name: Upload New Crash
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure() && steps.build.outcome == 'success'
|
||||
with:
|
||||
name: artifacts
|
||||
path: ./out/artifacts
|
||||
- name: Upload Legacy Crash
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: steps.run.outcome == 'success'
|
||||
with:
|
||||
name: crash
|
||||
|
|
6
.github/workflows/lint.yml
vendored
|
@ -2,6 +2,9 @@ name: Lint
|
|||
|
||||
on: [push, pull_request, workflow_dispatch]
|
||||
|
||||
env:
|
||||
FORCE_COLOR: 1
|
||||
|
||||
permissions:
|
||||
contents: read
|
||||
|
||||
|
@ -46,3 +49,6 @@ jobs:
|
|||
run: tox -e lint
|
||||
env:
|
||||
PRE_COMMIT_COLOR: always
|
||||
|
||||
- name: Mypy
|
||||
run: tox -e mypy
|
||||
|
|
2
.github/workflows/system-info.py
vendored
|
@ -6,6 +6,8 @@ This sort of info is missing from GitHub Actions.
|
|||
Requested here:
|
||||
https://github.com/actions/virtual-environments/issues/79
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import platform
|
||||
import sys
|
||||
|
|
2
.github/workflows/test-cygwin.yml
vendored
|
@ -132,7 +132,7 @@ jobs:
|
|||
dash.exe -c "mkdir -p Tests/errors"
|
||||
|
||||
- name: Upload errors
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: errors
|
||||
|
|
2
.github/workflows/test-windows.yml
vendored
|
@ -190,7 +190,7 @@ jobs:
|
|||
shell: bash
|
||||
|
||||
- name: Upload errors
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: errors
|
||||
|
|
2
.github/workflows/test.yml
vendored
|
@ -112,7 +112,7 @@ jobs:
|
|||
mkdir -p Tests/errors
|
||||
|
||||
- name: Upload errors
|
||||
uses: actions/upload-artifact@v3
|
||||
uses: actions/upload-artifact@v4
|
||||
if: failure()
|
||||
with:
|
||||
name: errors
|
||||
|
|
|
@ -1,17 +1,17 @@
|
|||
repos:
|
||||
- repo: https://github.com/astral-sh/ruff-pre-commit
|
||||
rev: v0.1.6
|
||||
rev: v0.1.7
|
||||
hooks:
|
||||
- id: ruff
|
||||
args: [--fix, --exit-non-zero-on-fix]
|
||||
|
||||
- repo: https://github.com/psf/black-pre-commit-mirror
|
||||
rev: 23.11.0
|
||||
rev: 23.12.0
|
||||
hooks:
|
||||
- id: black
|
||||
|
||||
- repo: https://github.com/PyCQA/bandit
|
||||
rev: 1.7.5
|
||||
rev: 1.7.6
|
||||
hooks:
|
||||
- id: bandit
|
||||
args: [--severity-level=high]
|
||||
|
@ -42,7 +42,7 @@ repos:
|
|||
exclude: ^.github/.*TEMPLATE|^Tests/(fonts|images)/
|
||||
|
||||
- repo: https://github.com/sphinx-contrib/sphinx-lint
|
||||
rev: v0.9.0
|
||||
rev: v0.9.1
|
||||
hooks:
|
||||
- id: sphinx-lint
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ formats: [pdf]
|
|||
build:
|
||||
os: ubuntu-22.04
|
||||
tools:
|
||||
python: "3.11"
|
||||
python: "3"
|
||||
|
||||
python:
|
||||
install:
|
||||
|
|
24
CHANGES.rst
|
@ -5,6 +5,30 @@ Changelog (Pillow)
|
|||
10.2.0 (unreleased)
|
||||
-------------------
|
||||
|
||||
- Fix incorrect color blending for overlapping glyphs #7497
|
||||
[ZachNagengast, nulano, radarhere]
|
||||
|
||||
- Attempt memory mapping when tile args is a string #7565
|
||||
[radarhere]
|
||||
|
||||
- Fill identical pixels with transparency in subsequent frames when saving GIF #7568
|
||||
[radarhere]
|
||||
|
||||
- Corrected duration when combining multiple GIF frames into single frame #7521
|
||||
[radarhere]
|
||||
|
||||
- Handle disposing GIF background from outside palette #7515
|
||||
[radarhere]
|
||||
|
||||
- Seek past the data when skipping a PSD layer #7483
|
||||
[radarhere]
|
||||
|
||||
- Import plugins relative to the module #7576
|
||||
[deliangyang, jaxx0n]
|
||||
|
||||
- Translate encoder error codes to strings; deprecate ``ImageFile.raise_oserror()`` #7609
|
||||
[bgilbert, radarhere]
|
||||
|
||||
- Support reading BC4U and DX10 BC1 images #6486
|
||||
[REDxEYE, radarhere, hugovk]
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import sys
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import time
|
||||
|
||||
from PIL import PyAccess
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
from PIL import Image
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from PIL import Image
|
||||
|
||||
TEST_FILE = "Tests/images/fli_overflow.fli"
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Tests potential DOS of IcnsImagePlugin with 0 length block.
|
||||
# Run from anywhere that PIL is importable.
|
||||
from __future__ import annotations
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# Tests potential DOS of Jpeg2kImagePlugin with 0 length block.
|
||||
# Run from anywhere that PIL is importable.
|
||||
from __future__ import annotations
|
||||
|
||||
from io import BytesIO
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -12,6 +12,7 @@
|
|||
# the output should be empty. There may be python issues
|
||||
# in the valgrind especially if run in a debug python
|
||||
# version.
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import zlib
|
||||
from io import BytesIO
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
|
||||
from PIL import features
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
import base64
|
||||
import os
|
||||
|
||||
|
|
BIN
Tests/fonts/CBDTTestFont.ttf
Normal file
BIN
Tests/fonts/EBDTTestFont.ttf
Normal file
|
@ -2,7 +2,6 @@
|
|||
NotoNastaliqUrdu-Regular.ttf and NotoSansSymbols-Regular.ttf, from https://github.com/googlei18n/noto-fonts
|
||||
NotoSans-Regular.ttf, from https://www.google.com/get/noto/
|
||||
NotoSansJP-Thin.otf, from https://www.google.com/get/noto/help/cjk/
|
||||
NotoColorEmoji.ttf, from https://github.com/googlefonts/noto-emoji
|
||||
AdobeVFPrototype.ttf, from https://github.com/adobe-fonts/adobe-variable-font-prototype
|
||||
TINY5x3GX.ttf, from http://velvetyne.fr/fonts/tiny
|
||||
ArefRuqaa-Regular.ttf, from https://github.com/google/fonts/tree/master/ofl/arefruqaa
|
||||
|
@ -25,3 +24,5 @@ FreeMono.ttf is licensed under GPLv3.
|
|||
10x20-ISO8859-1.pcf, from https://packages.ubuntu.com/xenial/xfonts-base
|
||||
|
||||
"Public domain font. Share and enjoy."
|
||||
|
||||
CBDTTestFont.ttf and EBDTTestFont.ttf from https://github.com/nulano/font-tests are public domain.
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
"""
|
||||
Helper functions.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
import os
|
||||
|
|
BIN
Tests/images/background_outside_palette.gif
Normal file
After Width: | Height: | Size: 82 B |
BIN
Tests/images/bitmap_font_blend.png
Normal file
After Width: | Height: | Size: 387 B |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.7 KiB |
Before Width: | Height: | Size: 2.6 KiB After Width: | Height: | Size: 2.7 KiB |
BIN
Tests/images/cbdt.png
Normal file
After Width: | Height: | Size: 348 B |
BIN
Tests/images/cbdt_mask.png
Normal file
After Width: | Height: | Size: 367 B |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
BIN
Tests/images/five_channels.psd
Normal file
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.1 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 4.9 KiB |
|
@ -13,6 +13,7 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
import atheris
|
||||
|
|
|
@ -13,6 +13,7 @@
|
|||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
import atheris
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
import warnings
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from PIL import Image
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from PIL import _binary
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import os
|
||||
import warnings
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImageFilter
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from array import array
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import _deprecate
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
import re
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImageSequence, PngImagePlugin
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import BufrStubImagePlugin, Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import ContainerIO, Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import warnings
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
"""Test DdsImagePlugin"""
|
||||
from __future__ import annotations
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from io import BytesIO
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import warnings
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import FtexImagePlugin, Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import GbrImagePlugin, Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import GdImageFile, UnidentifiedImageError
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import warnings
|
||||
from io import BytesIO
|
||||
|
||||
|
@ -217,6 +218,27 @@ def test_optimize_if_palette_can_be_reduced_by_half():
|
|||
assert len(reloaded.palette.palette) // 3 == colors
|
||||
|
||||
|
||||
def test_full_palette_second_frame(tmp_path):
|
||||
out = str(tmp_path / "temp.gif")
|
||||
im = Image.new("P", (1, 256))
|
||||
|
||||
full_palette_im = Image.new("P", (1, 256))
|
||||
for i in range(256):
|
||||
full_palette_im.putpixel((0, i), i)
|
||||
full_palette_im.palette = ImagePalette.ImagePalette(
|
||||
"RGB", bytearray(i // 3 for i in range(768))
|
||||
)
|
||||
full_palette_im.palette.dirty = 1
|
||||
|
||||
im.save(out, save_all=True, append_images=[full_palette_im])
|
||||
|
||||
with Image.open(out) as reloaded:
|
||||
reloaded.seek(1)
|
||||
|
||||
for i in range(256):
|
||||
reloaded.getpixel((0, i)) == i
|
||||
|
||||
|
||||
def test_roundtrip(tmp_path):
|
||||
out = str(tmp_path / "temp.gif")
|
||||
im = hopper()
|
||||
|
@ -856,7 +878,14 @@ def test_identical_frames(tmp_path):
|
|||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"duration", ([1000, 1500, 2000, 4000], (1000, 1500, 2000, 4000), 8500)
|
||||
"duration",
|
||||
(
|
||||
[1000, 1500, 2000],
|
||||
(1000, 1500, 2000),
|
||||
# One more duration than the number of frames
|
||||
[1000, 1500, 2000, 4000],
|
||||
1500,
|
||||
),
|
||||
)
|
||||
def test_identical_frames_to_single_frame(duration, tmp_path):
|
||||
out = str(tmp_path / "temp.gif")
|
||||
|
@ -872,7 +901,7 @@ def test_identical_frames_to_single_frame(duration, tmp_path):
|
|||
assert reread.n_frames == 1
|
||||
|
||||
# Assert that the new duration is the total of the identical frames
|
||||
assert reread.info["duration"] == 8500
|
||||
assert reread.info["duration"] == 4500
|
||||
|
||||
|
||||
def test_loop_none(tmp_path):
|
||||
|
@ -1142,6 +1171,12 @@ def test_rgba_transparency(tmp_path):
|
|||
assert_image_equal(hopper("P").convert("RGB"), reloaded)
|
||||
|
||||
|
||||
def test_background_outside_palettte(tmp_path):
|
||||
with Image.open("Tests/images/background_outside_palette.gif") as im:
|
||||
im.seek(1)
|
||||
assert im.info["background"] == 255
|
||||
|
||||
|
||||
def test_bbox(tmp_path):
|
||||
out = str(tmp_path / "temp.gif")
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from PIL import GimpGradientFile, ImagePalette
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL.GimpPaletteFile import GimpPaletteFile
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import GribStubImagePlugin, Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Hdf5StubImagePlugin, Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
import os
|
||||
import warnings
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
import os
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import filecmp
|
||||
import warnings
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import sys
|
||||
from io import BytesIO, StringIO
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import os
|
||||
import re
|
||||
import warnings
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import os
|
||||
import re
|
||||
from io import BytesIO
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import base64
|
||||
import io
|
||||
import itertools
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from io import BytesIO
|
||||
|
||||
from PIL import Image
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image, McIdasImagePlugin
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImagePalette
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import warnings
|
||||
from io import BytesIO
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import os
|
||||
|
||||
import pytest
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import os.path
|
||||
import subprocess
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
from PIL import Image
|
||||
|
||||
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image, ImageFile, PcxImagePlugin
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import io
|
||||
import os
|
||||
import os.path
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import pytest
|
||||
|
||||
from PIL import Image, PixarImagePlugin
|
||||
|
|
|
@ -1,3 +1,4 @@
|
|||
from __future__ import annotations
|
||||
import re
|
||||
import sys
|
||||
import warnings
|
||||
|
|