diff --git a/docs/reference/plugins.rst b/docs/reference/plugins.rst
index 46f657fce..cc0742fde 100644
--- a/docs/reference/plugins.rst
+++ b/docs/reference/plugins.rst
@@ -229,7 +229,7 @@ Plugin reference
 ----------------------------
 
 .. automodule:: PIL.PngImagePlugin
-    :members: ChunkStream, PngImageFile, PngStream, getchunks, is_cid, putchunk
+    :members: ChunkStream, PngStream, getchunks, is_cid, putchunk
     :show-inheritance:
 .. autoclass:: PIL.PngImagePlugin.ChunkStream
     :members:
diff --git a/src/PIL/PngImagePlugin.py b/src/PIL/PngImagePlugin.py
index 0291df4b0..ee9d52b4c 100644
--- a/src/PIL/PngImagePlugin.py
+++ b/src/PIL/PngImagePlugin.py
@@ -673,7 +673,7 @@ class PngImageFile(ImageFile.ImageFile):
         self._text = None
         self.tile = self.png.im_tile
         self.custom_mimetype = self.png.im_custom_mimetype
-        self._n_frames = self.png.im_n_frames
+        self.n_frames = self.png.im_n_frames or 1
         self.default_image = self.info.get("default_image", False)
 
         if self.png.im_palette:
@@ -685,15 +685,16 @@ class PngImageFile(ImageFile.ImageFile):
         else:
             self.__prepare_idat = length  # used by load_prepare()
 
-        if self._n_frames is not None:
+        if self.png.im_n_frames is not None:
             self._close_exclusive_fp_after_loading = False
             self.png.save_rewind()
             self.__rewind_idat = self.__prepare_idat
             self.__rewind = self.__fp.tell()
             if self.default_image:
                 # IDAT chunk contains default image and not first animation frame
-                self._n_frames += 1
+                self.n_frames += 1
             self._seek(0)
+        self.is_animated = self.n_frames > 1
 
     @property
     def text(self):
@@ -710,16 +711,6 @@ class PngImageFile(ImageFile.ImageFile):
                 self.seek(frame)
         return self._text
 
-    @property
-    def n_frames(self):
-        if self._n_frames is None:
-            return 1
-        return self._n_frames
-
-    @property
-    def is_animated(self):
-        return self._n_frames is not None and self._n_frames > 1
-
     def verify(self):
         """Verify PNG file"""
 

AttributeError: 'NoneType' object has no attribute 'read' 
<!--
Thank you for reporting an issue.

Follow these guidelines to ensure your issue is handled properly.

If you have a ...

1.  General question: consider asking the question on Stack Overflow
    with the python-imaging-library tag:

    * https://stackoverflow.com/questions/tagged/python-imaging-library

    Do not ask a question in both places.

    If you think you have found a bug or have an unexplained exception
    then file a bug report here.

2.  Bug report: include a self-contained, copy-pastable example that
    generates the issue if possible. Be concise with code posted.
    Guidelines on how to provide a good bug report:

    * https://stackoverflow.com/help/mcve

    Bug reports which follow these guidelines are easier to diagnose,
    and are often handled much more quickly.

3.  Feature request: do a quick search of existing issues
    to make sure this has not been asked before.

We know asking good questions takes effort, and we appreciate your time.
Thank you.
-->

### What did you do?

Following on from #4509 after the 7.1.0 release, we have a new issue that cropped up opening a png from scikit-image.

### What did you expect to happen?

Not error.

### What actually happened?

It errored.

### What are your OS, Python and Pillow versions?

* OS: Linux
* Python: 3.8.2
* Pillow: 7.1.0

<!--
Please include **code** that reproduces the issue and whenever possible, an **image** that demonstrates the issue. Please upload images to GitHub, not to third-party file hosting sites. If necessary, add the image to a zip or tar archive.

The best reproductions are self-contained scripts with minimal dependencies. If you are using a framework such as Plone, Django, or Buildout, try to replicate the issue just using Pillow.
-->
The code should just be loading a scikit-image PNG data:

```python
from skimage import data
original = data.camera().astype('float')
```
The error message is:
```python
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/skimage/data/__init__.py", line 109, in camera
    return _load("camera.png")
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/skimage/data/__init__.py", line 96, in _load
    return imread(_os.path.join(data_dir, f), plugin='pil', as_gray=as_gray)
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/skimage/io/_io.py", line 48, in imread
    img = call_plugin('imread', fname, plugin=plugin, **plugin_args)
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/skimage/io/manage_plugins.py", line 210, in call_plugin
    return func(*args, **kwargs)
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/skimage/io/_plugins/pil_plugin.py", line 36, in imread
    return pil_to_ndarray(im, dtype=dtype, img_num=img_num)
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/skimage/io/_plugins/pil_plugin.py", line 66, in pil_to_ndarray
    image.seek(i)
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/PIL/PngImagePlugin.py", line 748, in seek
    self._seek(f)
  File "/opt/miniconda/envs/sunpy/lib/python3.8/site-packages/PIL/PngImagePlugin.py", line 791, in _seek
    cid, pos, length = self.png.read()
AttributeError: 'NoneType' object has no attribute 'read'
```

Since this is scikit image loading one of their PNGs, I wonder if it's actually a bug there. 
diff --git a/Tests/test_file_png.py b/Tests/test_file_png.py
index 469d186e8..476995dd7 100644
--- a/Tests/test_file_png.py
+++ b/Tests/test_file_png.py
@@ -637,6 +637,9 @@ class TestFilePng:
         with Image.open(TEST_PNG_FILE) as im:
             im.seek(0)
 
+            with pytest.raises(EOFError):
+                im.seek(1)
+
 
 @pytest.mark.skipif(is_win32(), reason="Requires Unix or macOS")
 @skip_unless_feature("zlib")

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
black==25.1.0
blessed==1.20.0
build==1.2.2.post1
certifi==2025.1.31
charset-normalizer==3.4.1
check-manifest==0.50
click==8.1.8
coverage==7.8.0
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
mypy-extensions==1.0.0
olefile==0.47
packaging==24.2
pathspec==0.12.1
-e git+https://github.com/python-pillow/Pillow.git@4dcd194333126a9163ab8482ac84783ee1b2d3df#egg=Pillow
platformdirs==4.3.7
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
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
typing_extensions==4.13.0
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
      - black==25.1.0
      - blessed==1.20.0
      - build==1.2.2.post1
      - certifi==2025.1.31
      - charset-normalizer==3.4.1
      - check-manifest==0.50
      - click==8.1.8
      - coverage==7.8.0
      - 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
      - mypy-extensions==1.0.0
      - olefile==0.47
      - packaging==24.2
      - pathspec==0.12.1
      - platformdirs==4.3.7
      - 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
      - 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
      - typing-extensions==4.13.0
      - urllib3==2.3.0
      - wcwidth==0.2.13
      - zipp==3.21.0
prefix: /opt/conda/envs/Pillow

Tests/test_file_png.py::TestFilePng::test_seek
Tests/test_file_png.py::TestFilePng::test_load_verify
Tests/test_file_png.py::TestFilePng::test_sanity Tests/test_file_png.py::TestFilePng::test_invalid_file Tests/test_file_png.py::TestFilePng::test_broken Tests/test_file_png.py::TestFilePng::test_bad_text Tests/test_file_png.py::TestFilePng::test_bad_ztxt Tests/test_file_png.py::TestFilePng::test_bad_itxt Tests/test_file_png.py::TestFilePng::test_interlace Tests/test_file_png.py::TestFilePng::test_load_transparent_p Tests/test_file_png.py::TestFilePng::test_load_transparent_rgb Tests/test_file_png.py::TestFilePng::test_save_p_transparent_palette Tests/test_file_png.py::TestFilePng::test_save_p_single_transparency Tests/test_file_png.py::TestFilePng::test_save_p_transparent_black Tests/test_file_png.py::TestFilePng::test_save_greyscale_transparency Tests/test_file_png.py::TestFilePng::test_save_rgb_single_transparency Tests/test_file_png.py::TestFilePng::test_verify_struct_error Tests/test_file_png.py::TestFilePng::test_verify_ignores_crc_error Tests/test_file_png.py::TestFilePng::test_verify_not_ignores_crc_error_in_required_chunk Tests/test_file_png.py::TestFilePng::test_roundtrip_dpi Tests/test_file_png.py::TestFilePng::test_load_dpi_rounding Tests/test_file_png.py::TestFilePng::test_save_dpi_rounding Tests/test_file_png.py::TestFilePng::test_roundtrip_text Tests/test_file_png.py::TestFilePng::test_roundtrip_itxt Tests/test_file_png.py::TestFilePng::test_nonunicode_text Tests/test_file_png.py::TestFilePng::test_unicode_text Tests/test_file_png.py::TestFilePng::test_scary Tests/test_file_png.py::TestFilePng::test_trns_rgb Tests/test_file_png.py::TestFilePng::test_trns_p Tests/test_file_png.py::TestFilePng::test_trns_null Tests/test_file_png.py::TestFilePng::test_save_icc_profile Tests/test_file_png.py::TestFilePng::test_discard_icc_profile Tests/test_file_png.py::TestFilePng::test_roundtrip_icc_profile Tests/test_file_png.py::TestFilePng::test_roundtrip_no_icc_profile Tests/test_file_png.py::TestFilePng::test_repr_png Tests/test_file_png.py::TestFilePng::test_chunk_order Tests/test_file_png.py::TestFilePng::test_getchunks Tests/test_file_png.py::TestFilePng::test_textual_chunks_after_idat Tests/test_file_png.py::TestFilePng::test_exif[Tests/images/exif.png] Tests/test_file_png.py::TestFilePng::test_exif[Tests/images/exif_imagemagick.png] Tests/test_file_png.py::TestFilePng::test_exif_save Tests/test_file_png.py::TestFilePng::test_exif_from_jpg Tests/test_file_png.py::TestFilePng::test_exif_argument Tests/test_file_png.py::TestFilePng::test_tell Tests/test_file_png.py::TestTruncatedPngPLeaks::test_leak_load
docs/reference/plugins.rst src/PIL/PngImagePlugin.py
docs/reference/plugins.rst src/PIL/PngImagePlugin.py