Skip to content

Commit 3cd9b08

Browse files
authored
Fix livereload when using serve from stdin (#56)
We must not attempt to get the file name of stdin (the current error) and we also must not try to re-read it. Now that this case is handled specifically at `serve`, we don't need to generally expect closed files in `load_config` - it was a workaround and an insufficient one at that.
1 parent 6e14798 commit 3cd9b08

File tree

3 files changed

+19
-21
lines changed

3 files changed

+19
-21
lines changed

properdocs/commands/serve.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from __future__ import annotations
22

3+
import io
34
import logging
45
import shutil
6+
import sys
57
import tempfile
68
from os.path import isdir, isfile, join
7-
from typing import TYPE_CHECKING
9+
from typing import TYPE_CHECKING, BinaryIO, Callable
810
from urllib.parse import urlsplit
911

1012
from properdocs.commands.build import build
@@ -18,7 +20,7 @@
1820

1921

2022
def serve(
21-
config_file: str | None = None,
23+
config_file: str | BinaryIO | None = None,
2224
livereload: bool = True,
2325
build_type: str | None = None,
2426
watch_theme: bool = False,
@@ -37,9 +39,22 @@ def serve(
3739
# Create a temporary build directory, and set some options to serve it
3840
site_dir = tempfile.mkdtemp(prefix='properdocs_')
3941

42+
get_config_file: Callable[[], str | BinaryIO | None]
43+
if config_file is None or isinstance(config_file, str):
44+
get_config_file = lambda: config_file
45+
elif sys.stdin and config_file is sys.stdin.buffer:
46+
# Stdin must be read only once, can't be reopened later.
47+
config_file_content = sys.stdin.buffer.read()
48+
get_config_file = lambda: io.BytesIO(config_file_content)
49+
else:
50+
# If closed file descriptor, reopen it through the file path instead.
51+
get_config_file = lambda: (
52+
config_file.name if getattr(config_file, 'closed', False) else config_file
53+
)
54+
4055
def get_config():
4156
config = load_config(
42-
config_file=config_file,
57+
config_file=get_config_file(),
4358
site_dir=site_dir,
4459
**kwargs,
4560
)

properdocs/config/base.py

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -290,9 +290,6 @@ def _open_config_file(config_file: str | IO | None) -> Iterator[IO]:
290290
# If it is a string, we can assume it is a path and attempt to open it.
291291
elif isinstance(config_file, str):
292292
paths_to_try = [config_file]
293-
# If closed file descriptor, get file path to reopen later.
294-
elif getattr(config_file, 'closed', False):
295-
paths_to_try = [config_file.name]
296293
else:
297294
result_config_file = config_file
298295
paths_to_try = None

properdocs/tests/config/base_tests.py

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -118,20 +118,6 @@ def test_load_from_open_file(self, temp_path):
118118
# load_config will always close the file
119119
self.assertTrue(config_file.closed)
120120

121-
@tempdir()
122-
def test_load_from_closed_file(self, temp_dir):
123-
"""
124-
The `serve` command with auto-reload may pass in a closed file descriptor.
125-
Ensure `load_config` reloads the closed file.
126-
"""
127-
with open(os.path.join(temp_dir, 'properdocs.yml'), 'w') as config_file:
128-
config_file.write("site_name: ProperDocs Test\ntheme: mkdocs\n")
129-
os.mkdir(os.path.join(temp_dir, 'docs'))
130-
131-
cfg = base.load_config(config_file=config_file)
132-
self.assertTrue(isinstance(cfg, defaults.ProperDocsConfig))
133-
self.assertEqual(cfg.site_name, 'ProperDocs Test')
134-
135121
@tempdir()
136122
def test_load_missing_required(self, temp_dir):
137123
"""`site_name` is a required setting."""
@@ -260,7 +246,7 @@ def test_load_from_file_with_relative_paths(self, config_dir):
260246
docs_dir = os.path.join(config_dir, 'src')
261247
os.mkdir(docs_dir)
262248

263-
cfg = base.load_config(config_file=config_file)
249+
cfg = base.load_config(config_file=config_fname)
264250
self.assertTrue(isinstance(cfg, defaults.ProperDocsConfig))
265251
self.assertEqual(cfg.site_name, 'ProperDocs Test')
266252
self.assertEqual(cfg.docs_dir, docs_dir)

0 commit comments

Comments
 (0)