diff --git a/src/PIL/Image.py b/src/PIL/Image.py
index 4626497fb..1759c7790 100644
--- a/src/PIL/Image.py
+++ b/src/PIL/Image.py
@@ -247,7 +247,7 @@ _MODEINFO = {
     "L": ("L", "L", ("L",)),
     "I": ("L", "I", ("I",)),
     "F": ("L", "F", ("F",)),
-    "P": ("RGB", "L", ("P",)),
+    "P": ("P", "L", ("P",)),
     "RGB": ("RGB", "L", ("R", "G", "B")),
     "RGBX": ("RGB", "L", ("R", "G", "B", "X")),
     "RGBA": ("RGB", "L", ("R", "G", "B", "A")),
@@ -1559,7 +1559,7 @@ class Image(object):
 
         self._ensure_mutable()
 
-        if self.mode not in ("LA", "RGBA"):
+        if self.mode not in ("LA", "PA", "RGBA"):
             # attempt to promote self to a matching alpha mode
             try:
                 mode = getmodebase(self.mode) + "A"
@@ -1568,7 +1568,7 @@ class Image(object):
                 except (AttributeError, ValueError):
                     # do things the hard way
                     im = self.im.convert(mode)
-                    if im.mode not in ("LA", "RGBA"):
+                    if im.mode not in ("LA", "PA", "RGBA"):
                         raise ValueError  # sanity check
                     self.im = im
                 self.pyaccess = None
@@ -1576,7 +1576,7 @@ class Image(object):
             except (KeyError, ValueError):
                 raise ValueError("illegal image mode")
 
-        if self.mode == "LA":
+        if self.mode in ("LA", "PA"):
             band = 1
         else:
             band = 3
diff --git a/src/libImaging/Convert.c b/src/libImaging/Convert.c
index 39ddf8721..ff78555d2 100644
--- a/src/libImaging/Convert.c
+++ b/src/libImaging/Convert.c
@@ -1018,6 +1018,8 @@ frompalette(Imaging imOut, Imaging imIn, const char *mode)
         convert = p2l;
     else if (strcmp(mode, "LA") == 0)
         convert = (alpha) ? pa2la : p2la;
+    else if (strcmp(mode, "PA") == 0)
+        convert = l2la;
     else if (strcmp(mode, "I") == 0)
         convert = p2i;
     else if (strcmp(mode, "F") == 0)

Image.putalpha fails on P -> PA
Image.putalpha should handle the promotion of `P` to `PA` images similarly to `L` -> `LA`.


diff --git a/Tests/test_image_mode.py b/Tests/test_image_mode.py
index 26266611d..345c0dacb 100644
--- a/Tests/test_image_mode.py
+++ b/Tests/test_image_mode.py
@@ -42,7 +42,7 @@ class TestImageMode(PillowTestCase):
             self.assertEqual(signature, result)
         check("1", "L", "L", 1, ("1",))
         check("L", "L", "L", 1, ("L",))
-        check("P", "RGB", "L", 1, ("P",))
+        check("P", "P", "L", 1, ("P",))
         check("I", "L", "I", 1, ("I",))
         check("F", "L", "F", 1, ("F",))
         check("RGB", "RGB", "L", 3, ("R", "G", "B"))
diff --git a/Tests/test_image_putalpha.py b/Tests/test_image_putalpha.py
index 7b66b8833..702afb995 100644
--- a/Tests/test_image_putalpha.py
+++ b/Tests/test_image_putalpha.py
@@ -28,6 +28,13 @@ class TestImagePutAlpha(PillowTestCase):
         self.assertEqual(im.mode, 'LA')
         self.assertEqual(im.getpixel((0, 0)), (1, 2))
 
+        im = Image.new("P", (1, 1), 1)
+        self.assertEqual(im.getpixel((0, 0)), 1)
+
+        im.putalpha(2)
+        self.assertEqual(im.mode, 'PA')
+        self.assertEqual(im.getpixel((0, 0)), (1, 2))
+
         im = Image.new("RGB", (1, 1), (1, 2, 3))
         self.assertEqual(im.getpixel((0, 0)), (1, 2, 3))
 

pip install -e .[dev]
parse_log_pytest
requirements.txt
apt-get update apt-get install -y gcc libjpeg-dev zlib1g-dev libtiff5-dev libfreetype6-dev liblcms2-dev libwebp-dev tcl8.6-dev tk8.6-dev libharfbuzz-dev libfribidi-dev libxcb1-dev
3.9
requirements.txt
pytest --no-header -rA --tb=line --color=no -p no:cacheprovider -W ignore::DeprecationWarning
alabaster==0.7.16
babel==2.17.0
blessed==1.20.0
build==1.2.2.post1
certifi==2025.1.31
charset-normalizer==3.4.1
check-manifest==0.50
cov-core==1.15.0
coverage==7.8.0
coveralls==4.0.1
docopt==0.6.2
docutils==0.21.2
exceptiongroup==1.2.2
idna==3.10
imagesize==1.4.1
importlib_metadata==8.6.1
iniconfig==2.1.0
jarn.viewdoc==2.7
Jinja2==3.1.6
MarkupSafe==3.0.2
olefile==0.47
packaging==24.2
-e git+https://github.com/python-pillow/Pillow.git@63141a9c0cf1d08d58c63249dc785bba4295e86c#egg=Pillow
pluggy==1.5.0
pycodestyle==2.13.0
pyflakes==3.3.1
Pygments==2.19.1
pyproject_hooks==1.2.0
pyroma==4.2
pytest==8.3.5
pytest-cov==6.0.0
pytz==2025.2
requests==2.32.3
six==1.17.0
snowballstemmer==2.2.0
Sphinx==7.4.7
sphinx-rtd-theme==3.0.2
sphinxcontrib-applehelp==2.0.0
sphinxcontrib-devhelp==2.0.0
sphinxcontrib-htmlhelp==2.1.0
sphinxcontrib-jquery==4.1
sphinxcontrib-jsmath==1.0.1
sphinxcontrib-qthelp==2.0.0
sphinxcontrib-serializinghtml==2.0.0
tomli==2.2.1
trove-classifiers==2025.3.19.19
urllib3==2.3.0
wcwidth==0.2.13
zipp==3.21.0

name: Pillow
channels:
  - defaults
  - https://repo.anaconda.com/pkgs/main
  - https://repo.anaconda.com/pkgs/r
  - conda-forge
dependencies:
  - _libgcc_mutex=0.1=main
  - _openmp_mutex=5.1=1_gnu
  - ca-certificates=2025.2.25=h06a4308_0
  - ld_impl_linux-64=2.40=h12ee557_0
  - libffi=3.4.4=h6a678d5_1
  - libgcc-ng=11.2.0=h1234567_1
  - libgomp=11.2.0=h1234567_1
  - libstdcxx-ng=11.2.0=h1234567_1
  - ncurses=6.4=h6a678d5_0
  - openssl=3.0.16=h5eee18b_0
  - pip=25.0=py39h06a4308_0
  - python=3.9.21=he870216_1
  - readline=8.2=h5eee18b_0
  - setuptools=75.8.0=py39h06a4308_0
  - sqlite=3.45.3=h5eee18b_0
  - tk=8.6.14=h39e8969_0
  - tzdata=2025a=h04d1e81_0
  - wheel=0.45.1=py39h06a4308_0
  - xz=5.6.4=h5eee18b_1
  - zlib=1.2.13=h5eee18b_1
  - pip:
      - alabaster==0.7.16
      - babel==2.17.0
      - blessed==1.20.0
      - build==1.2.2.post1
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - check-manifest==0.50
      - cov-core==1.15.0
      - coverage==7.8.0
      - coveralls==4.0.1
      - docopt==0.6.2
      - docutils==0.21.2
      - exceptiongroup==1.2.2
      - idna==3.10
      - imagesize==1.4.1
      - importlib-metadata==8.6.1
      - iniconfig==2.1.0
      - jarn-viewdoc==2.7
      - jinja2==3.1.6
      - markupsafe==3.0.2
      - olefile==0.47
      - packaging==24.2
      - pluggy==1.5.0
      - pycodestyle==2.13.0
      - pyflakes==3.3.1
      - pygments==2.19.1
      - pyproject-hooks==1.2.0
      - pyroma==4.2
      - pytest==8.3.5
      - pytest-cov==6.0.0
      - pytz==2025.2
      - requests==2.32.3
      - six==1.17.0
      - snowballstemmer==2.2.0
      - sphinx==7.4.7
      - sphinx-rtd-theme==3.0.2
      - sphinxcontrib-applehelp==2.0.0
      - sphinxcontrib-devhelp==2.0.0
      - sphinxcontrib-htmlhelp==2.1.0
      - sphinxcontrib-jquery==4.1
      - sphinxcontrib-jsmath==1.0.1
      - sphinxcontrib-qthelp==2.0.0
      - sphinxcontrib-serializinghtml==2.0.0
      - tomli==2.2.1
      - trove-classifiers==2025.3.19.19
      - urllib3==2.3.0
      - wcwidth==0.2.13
      - zipp==3.21.0
prefix: /opt/conda/envs/Pillow

Tests/test_image_mode.py::TestImageMode::test_properties
Tests/test_image_putalpha.py::TestImagePutAlpha::test_promote
Tests/test_image_mode.py::TestImageMode::test_sanity Tests/test_image_putalpha.py::TestImagePutAlpha::test_interface Tests/test_image_putalpha.py::TestImagePutAlpha::test_readonly
src/PIL/Image.py src/libImaging/Convert.c
src/PIL/Image.py src/libImaging/Convert.c