mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-06-30 09:53:39 +03:00
Remove constants deprecated in 9.1.0
This commit is contained in:
parent
8d83d5e66a
commit
c8ec15980b
|
@ -655,13 +655,3 @@ def test_different_modes_in_later_frames(mode, tmp_path):
|
||||||
im.save(test_file, save_all=True, append_images=[Image.new(mode, (1, 1))])
|
im.save(test_file, save_all=True, append_images=[Image.new(mode, (1, 1))])
|
||||||
with Image.open(test_file) as reloaded:
|
with Image.open(test_file) as reloaded:
|
||||||
assert reloaded.mode == mode
|
assert reloaded.mode == mode
|
||||||
|
|
||||||
|
|
||||||
def test_constants_deprecation():
|
|
||||||
for enum, prefix in {
|
|
||||||
PngImagePlugin.Disposal: "APNG_DISPOSE_",
|
|
||||||
PngImagePlugin.Blend: "APNG_BLEND_",
|
|
||||||
}.items():
|
|
||||||
for name in enum.__members__:
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert getattr(PngImagePlugin, prefix + name) == enum[name]
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from PIL import BlpImagePlugin, Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import (
|
from .helper import (
|
||||||
assert_image_equal,
|
assert_image_equal,
|
||||||
|
@ -72,14 +72,3 @@ def test_crashes(test_file):
|
||||||
with Image.open(f) as im:
|
with Image.open(f) as im:
|
||||||
with pytest.raises(OSError):
|
with pytest.raises(OSError):
|
||||||
im.load()
|
im.load()
|
||||||
|
|
||||||
|
|
||||||
def test_constants_deprecation():
|
|
||||||
for enum, prefix in {
|
|
||||||
BlpImagePlugin.Format: "BLP_FORMAT_",
|
|
||||||
BlpImagePlugin.Encoding: "BLP_ENCODING_",
|
|
||||||
BlpImagePlugin.AlphaEncoding: "BLP_ALPHA_ENCODING_",
|
|
||||||
}.items():
|
|
||||||
for name in enum.__members__:
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert getattr(BlpImagePlugin, prefix + name) == enum[name]
|
|
||||||
|
|
|
@ -21,12 +21,3 @@ def test_invalid_file():
|
||||||
|
|
||||||
with pytest.raises(SyntaxError):
|
with pytest.raises(SyntaxError):
|
||||||
FtexImagePlugin.FtexImageFile(invalid_file)
|
FtexImagePlugin.FtexImageFile(invalid_file)
|
||||||
|
|
||||||
|
|
||||||
def test_constants_deprecation():
|
|
||||||
for enum, prefix in {
|
|
||||||
FtexImagePlugin.Format: "FORMAT_",
|
|
||||||
}.items():
|
|
||||||
for name in enum.__members__:
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert getattr(FtexImagePlugin, prefix + name) == enum[name]
|
|
||||||
|
|
|
@ -930,13 +930,6 @@ class TestImage:
|
||||||
assert im.palette.colors[(27, 35, 6, 214)] == 24
|
assert im.palette.colors[(27, 35, 6, 214)] == 24
|
||||||
|
|
||||||
def test_constants(self):
|
def test_constants(self):
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert Image.LINEAR == Image.Resampling.BILINEAR
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert Image.CUBIC == Image.Resampling.BICUBIC
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert Image.ANTIALIAS == Image.Resampling.LANCZOS
|
|
||||||
|
|
||||||
for enum in (
|
for enum in (
|
||||||
Image.Transpose,
|
Image.Transpose,
|
||||||
Image.Transform,
|
Image.Transform,
|
||||||
|
|
|
@ -617,16 +617,6 @@ def test_auxiliary_channels_isolated():
|
||||||
assert_image_equal(test_image.convert(dst_format[2]), reference_image)
|
assert_image_equal(test_image.convert(dst_format[2]), reference_image)
|
||||||
|
|
||||||
|
|
||||||
def test_constants_deprecation():
|
|
||||||
for enum, prefix in {
|
|
||||||
ImageCms.Intent: "INTENT_",
|
|
||||||
ImageCms.Direction: "DIRECTION_",
|
|
||||||
}.items():
|
|
||||||
for name in enum.__members__:
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert getattr(ImageCms, prefix + name) == enum[name]
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize("mode", ("RGB", "RGBA", "RGBX"))
|
@pytest.mark.parametrize("mode", ("RGB", "RGBA", "RGBX"))
|
||||||
def test_rgb_lab(mode):
|
def test_rgb_lab(mode):
|
||||||
im = Image.new(mode, (1, 1))
|
im = Image.new(mode, (1, 1))
|
||||||
|
|
|
@ -1130,12 +1130,3 @@ def test_raqm_missing_warning(monkeypatch):
|
||||||
"Raqm layout was requested, but Raqm is not available. "
|
"Raqm layout was requested, but Raqm is not available. "
|
||||||
"Falling back to basic layout."
|
"Falling back to basic layout."
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
def test_constants_deprecation():
|
|
||||||
for enum, prefix in {
|
|
||||||
ImageFont.Layout: "LAYOUT_",
|
|
||||||
}.items():
|
|
||||||
for name in enum.__members__:
|
|
||||||
with pytest.warns(DeprecationWarning):
|
|
||||||
assert getattr(ImageFont, prefix + name) == enum[name]
|
|
||||||
|
|
|
@ -12,51 +12,6 @@ Deprecated features
|
||||||
Below are features which are considered deprecated. Where appropriate,
|
Below are features which are considered deprecated. Where appropriate,
|
||||||
a ``DeprecationWarning`` is issued.
|
a ``DeprecationWarning`` is issued.
|
||||||
|
|
||||||
Constants
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
.. deprecated:: 9.1.0
|
|
||||||
|
|
||||||
A number of constants have been deprecated and will be removed in Pillow 10.0.0
|
|
||||||
(2023-07-01). Instead, ``enum.IntEnum`` classes have been added.
|
|
||||||
|
|
||||||
.. note::
|
|
||||||
|
|
||||||
Additional ``Image`` constants were deprecated in Pillow 9.1.0, but that
|
|
||||||
was reversed in Pillow 9.4.0 and those constants will now remain available.
|
|
||||||
See :ref:`restored-image-constants`
|
|
||||||
|
|
||||||
===================================================== ============================================================
|
|
||||||
Deprecated Use instead
|
|
||||||
===================================================== ============================================================
|
|
||||||
``Image.LINEAR`` ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
|
|
||||||
``Image.CUBIC`` ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
|
|
||||||
``Image.ANTIALIAS`` ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
|
|
||||||
``ImageCms.INTENT_PERCEPTUAL`` ``ImageCms.Intent.PERCEPTUAL``
|
|
||||||
``ImageCms.INTENT_RELATIVE_COLORMETRIC`` ``ImageCms.Intent.RELATIVE_COLORMETRIC``
|
|
||||||
``ImageCms.INTENT_SATURATION`` ``ImageCms.Intent.SATURATION``
|
|
||||||
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC`` ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
|
|
||||||
``ImageCms.DIRECTION_INPUT`` ``ImageCms.Direction.INPUT``
|
|
||||||
``ImageCms.DIRECTION_OUTPUT`` ``ImageCms.Direction.OUTPUT``
|
|
||||||
``ImageCms.DIRECTION_PROOF`` ``ImageCms.Direction.PROOF``
|
|
||||||
``ImageFont.LAYOUT_BASIC`` ``ImageFont.Layout.BASIC``
|
|
||||||
``ImageFont.LAYOUT_RAQM`` ``ImageFont.Layout.RAQM``
|
|
||||||
``BlpImagePlugin.BLP_FORMAT_JPEG`` ``BlpImagePlugin.Format.JPEG``
|
|
||||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED`` ``BlpImagePlugin.Encoding.UNCOMPRESSED``
|
|
||||||
``BlpImagePlugin.BLP_ENCODING_DXT`` ``BlpImagePlugin.Encoding.DXT``
|
|
||||||
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA`` ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
|
|
||||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1`` ``BlpImagePlugin.AlphaEncoding.DXT1``
|
|
||||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3`` ``BlpImagePlugin.AlphaEncoding.DXT3``
|
|
||||||
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5`` ``BlpImagePlugin.AlphaEncoding.DXT5``
|
|
||||||
``FtexImagePlugin.FORMAT_DXT1`` ``FtexImagePlugin.Format.DXT1``
|
|
||||||
``FtexImagePlugin.FORMAT_UNCOMPRESSED`` ``FtexImagePlugin.Format.UNCOMPRESSED``
|
|
||||||
``PngImagePlugin.APNG_DISPOSE_OP_NONE`` ``PngImagePlugin.Disposal.OP_NONE``
|
|
||||||
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND`` ``PngImagePlugin.Disposal.OP_BACKGROUND``
|
|
||||||
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS`` ``PngImagePlugin.Disposal.OP_PREVIOUS``
|
|
||||||
``PngImagePlugin.APNG_BLEND_OP_SOURCE`` ``PngImagePlugin.Blend.OP_SOURCE``
|
|
||||||
``PngImagePlugin.APNG_BLEND_OP_OVER`` ``PngImagePlugin.Blend.OP_OVER``
|
|
||||||
===================================================== ============================================================
|
|
||||||
|
|
||||||
FitsStubImagePlugin
|
FitsStubImagePlugin
|
||||||
~~~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
@ -206,6 +161,52 @@ removed and replaced by ``path``.
|
||||||
|
|
||||||
In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.
|
In effect, ``viewer.show_file("test.jpg")`` will continue to work unchanged.
|
||||||
|
|
||||||
|
Constants
|
||||||
|
~~~~~~~~~
|
||||||
|
|
||||||
|
.. deprecated:: 9.1.0
|
||||||
|
.. versionremoved:: 10.0.0
|
||||||
|
|
||||||
|
A number of constants have been removed.
|
||||||
|
Instead, ``enum.IntEnum`` classes have been added.
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
|
||||||
|
Additional ``Image`` constants were deprecated in Pillow 9.1.0, but that
|
||||||
|
was reversed in Pillow 9.4.0 and those constants will now remain available.
|
||||||
|
See :ref:`restored-image-constants`
|
||||||
|
|
||||||
|
===================================================== ============================================================
|
||||||
|
Removed Use instead
|
||||||
|
===================================================== ============================================================
|
||||||
|
``Image.LINEAR`` ``Image.BILINEAR`` or ``Image.Resampling.BILINEAR``
|
||||||
|
``Image.CUBIC`` ``Image.BICUBIC`` or ``Image.Resampling.BICUBIC``
|
||||||
|
``Image.ANTIALIAS`` ``Image.LANCZOS`` or ``Image.Resampling.LANCZOS``
|
||||||
|
``ImageCms.INTENT_PERCEPTUAL`` ``ImageCms.Intent.PERCEPTUAL``
|
||||||
|
``ImageCms.INTENT_RELATIVE_COLORMETRIC`` ``ImageCms.Intent.RELATIVE_COLORMETRIC``
|
||||||
|
``ImageCms.INTENT_SATURATION`` ``ImageCms.Intent.SATURATION``
|
||||||
|
``ImageCms.INTENT_ABSOLUTE_COLORIMETRIC`` ``ImageCms.Intent.ABSOLUTE_COLORIMETRIC``
|
||||||
|
``ImageCms.DIRECTION_INPUT`` ``ImageCms.Direction.INPUT``
|
||||||
|
``ImageCms.DIRECTION_OUTPUT`` ``ImageCms.Direction.OUTPUT``
|
||||||
|
``ImageCms.DIRECTION_PROOF`` ``ImageCms.Direction.PROOF``
|
||||||
|
``ImageFont.LAYOUT_BASIC`` ``ImageFont.Layout.BASIC``
|
||||||
|
``ImageFont.LAYOUT_RAQM`` ``ImageFont.Layout.RAQM``
|
||||||
|
``BlpImagePlugin.BLP_FORMAT_JPEG`` ``BlpImagePlugin.Format.JPEG``
|
||||||
|
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED`` ``BlpImagePlugin.Encoding.UNCOMPRESSED``
|
||||||
|
``BlpImagePlugin.BLP_ENCODING_DXT`` ``BlpImagePlugin.Encoding.DXT``
|
||||||
|
``BlpImagePlugin.BLP_ENCODING_UNCOMPRESSED_RAW_RGBA`` ``BlpImagePlugin.Encoding.UNCOMPRESSED_RAW_RGBA``
|
||||||
|
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT1`` ``BlpImagePlugin.AlphaEncoding.DXT1``
|
||||||
|
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT3`` ``BlpImagePlugin.AlphaEncoding.DXT3``
|
||||||
|
``BlpImagePlugin.BLP_ALPHA_ENCODING_DXT5`` ``BlpImagePlugin.AlphaEncoding.DXT5``
|
||||||
|
``FtexImagePlugin.FORMAT_DXT1`` ``FtexImagePlugin.Format.DXT1``
|
||||||
|
``FtexImagePlugin.FORMAT_UNCOMPRESSED`` ``FtexImagePlugin.Format.UNCOMPRESSED``
|
||||||
|
``PngImagePlugin.APNG_DISPOSE_OP_NONE`` ``PngImagePlugin.Disposal.OP_NONE``
|
||||||
|
``PngImagePlugin.APNG_DISPOSE_OP_BACKGROUND`` ``PngImagePlugin.Disposal.OP_BACKGROUND``
|
||||||
|
``PngImagePlugin.APNG_DISPOSE_OP_PREVIOUS`` ``PngImagePlugin.Disposal.OP_PREVIOUS``
|
||||||
|
``PngImagePlugin.APNG_BLEND_OP_SOURCE`` ``PngImagePlugin.Blend.OP_SOURCE``
|
||||||
|
``PngImagePlugin.APNG_BLEND_OP_OVER`` ``PngImagePlugin.Blend.OP_OVER``
|
||||||
|
===================================================== ============================================================
|
||||||
|
|
||||||
PyQt5 and PySide2
|
PyQt5 and PySide2
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,6 @@ from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
from ._deprecate import deprecate
|
|
||||||
|
|
||||||
|
|
||||||
class Format(IntEnum):
|
class Format(IntEnum):
|
||||||
|
@ -54,21 +53,6 @@ class AlphaEncoding(IntEnum):
|
||||||
DXT5 = 7
|
DXT5 = 7
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
for enum, prefix in {
|
|
||||||
Format: "BLP_FORMAT_",
|
|
||||||
Encoding: "BLP_ENCODING_",
|
|
||||||
AlphaEncoding: "BLP_ALPHA_ENCODING_",
|
|
||||||
}.items():
|
|
||||||
if name.startswith(prefix):
|
|
||||||
name = name[len(prefix) :]
|
|
||||||
if name in enum.__members__:
|
|
||||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
|
||||||
return enum[name]
|
|
||||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
|
||||||
raise AttributeError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def unpack_565(i):
|
def unpack_565(i):
|
||||||
return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3
|
return ((i >> 11) & 0x1F) << 3, ((i >> 5) & 0x3F) << 2, (i & 0x1F) << 3
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,6 @@ from enum import IntEnum
|
||||||
from io import BytesIO
|
from io import BytesIO
|
||||||
|
|
||||||
from . import Image, ImageFile
|
from . import Image, ImageFile
|
||||||
from ._deprecate import deprecate
|
|
||||||
|
|
||||||
MAGIC = b"FTEX"
|
MAGIC = b"FTEX"
|
||||||
|
|
||||||
|
@ -66,17 +65,6 @@ class Format(IntEnum):
|
||||||
UNCOMPRESSED = 1
|
UNCOMPRESSED = 1
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
for enum, prefix in {Format: "FORMAT_"}.items():
|
|
||||||
if name.startswith(prefix):
|
|
||||||
name = name[len(prefix) :]
|
|
||||||
if name in enum.__members__:
|
|
||||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
|
||||||
return enum[name]
|
|
||||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
|
||||||
raise AttributeError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
class FtexImageFile(ImageFile.ImageFile):
|
class FtexImageFile(ImageFile.ImageFile):
|
||||||
format = "FTEX"
|
format = "FTEX"
|
||||||
format_description = "Texture File Format (IW2:EOC)"
|
format_description = "Texture File Format (IW2:EOC)"
|
||||||
|
|
|
@ -59,22 +59,6 @@ from ._binary import i32le, o32be, o32le
|
||||||
from ._deprecate import deprecate
|
from ._deprecate import deprecate
|
||||||
from ._util import DeferredError, is_path
|
from ._util import DeferredError, is_path
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
old_resampling = {
|
|
||||||
"LINEAR": "BILINEAR",
|
|
||||||
"CUBIC": "BICUBIC",
|
|
||||||
"ANTIALIAS": "LANCZOS",
|
|
||||||
}
|
|
||||||
if name in old_resampling:
|
|
||||||
deprecate(
|
|
||||||
name, 10, f"{old_resampling[name]} or Resampling.{old_resampling[name]}"
|
|
||||||
)
|
|
||||||
return Resampling[old_resampling[name]]
|
|
||||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
|
||||||
raise AttributeError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -20,8 +20,6 @@ from enum import IntEnum
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from ._deprecate import deprecate
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from PIL import _imagingcms
|
from PIL import _imagingcms
|
||||||
except ImportError as ex:
|
except ImportError as ex:
|
||||||
|
@ -117,17 +115,6 @@ class Direction(IntEnum):
|
||||||
PROOF = 2
|
PROOF = 2
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
for enum, prefix in {Intent: "INTENT_", Direction: "DIRECTION_"}.items():
|
|
||||||
if name.startswith(prefix):
|
|
||||||
name = name[len(prefix) :]
|
|
||||||
if name in enum.__members__:
|
|
||||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
|
||||||
return enum[name]
|
|
||||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
|
||||||
raise AttributeError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# flags
|
# flags
|
||||||
|
|
||||||
|
|
|
@ -43,17 +43,6 @@ class Layout(IntEnum):
|
||||||
RAQM = 1
|
RAQM = 1
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
for enum, prefix in {Layout: "LAYOUT_"}.items():
|
|
||||||
if name.startswith(prefix):
|
|
||||||
name = name[len(prefix) :]
|
|
||||||
if name in enum.__members__:
|
|
||||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
|
||||||
return enum[name]
|
|
||||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
|
||||||
raise AttributeError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from . import _imagingft as core
|
from . import _imagingft as core
|
||||||
except ImportError as ex:
|
except ImportError as ex:
|
||||||
|
|
|
@ -45,7 +45,6 @@ from ._binary import i32be as i32
|
||||||
from ._binary import o8
|
from ._binary import o8
|
||||||
from ._binary import o16be as o16
|
from ._binary import o16be as o16
|
||||||
from ._binary import o32be as o32
|
from ._binary import o32be as o32
|
||||||
from ._deprecate import deprecate
|
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
@ -131,17 +130,6 @@ class Blend(IntEnum):
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
|
||||||
def __getattr__(name):
|
|
||||||
for enum, prefix in {Disposal: "APNG_DISPOSE_", Blend: "APNG_BLEND_"}.items():
|
|
||||||
if name.startswith(prefix):
|
|
||||||
name = name[len(prefix) :]
|
|
||||||
if name in enum.__members__:
|
|
||||||
deprecate(f"{prefix}{name}", 10, f"{enum.__name__}.{name}")
|
|
||||||
return enum[name]
|
|
||||||
msg = f"module '{__name__}' has no attribute '{name}'"
|
|
||||||
raise AttributeError(msg)
|
|
||||||
|
|
||||||
|
|
||||||
def _safe_zlib_decompress(s):
|
def _safe_zlib_decompress(s):
|
||||||
dobj = zlib.decompressobj()
|
dobj = zlib.decompressobj()
|
||||||
plaintext = dobj.decompress(s, MAX_TEXT_CHUNK)
|
plaintext = dobj.decompress(s, MAX_TEXT_CHUNK)
|
||||||
|
|
Loading…
Reference in New Issue
Block a user