Skip to content

Commit 78c06c6

Browse files
authored
REF: Use f-strings. Min Python3.6+ (#278)
* MNT: Bumped Python version reqs to 3.6+ * ENH: Updated string formatting to use f-strings * ENH: Resolved individual code comments in #278 * ENH: __init__.py refactored to use f-strings * ENH: cli.py refactored to use f-strings * ENH: pdoc/test/__init__.py refactored to use f-strings * ENH: pdoc/templates/html.mako refactored to use f-strings * ENH: pdoc/html_helpers.py refactored to use f-strings * ENH: pdoc/templates/pdf.mako refactored to use f-strings * Update pdoc/html_helpers.py Reworded variable name to be more meaningful
1 parent 0658ff0 commit 78c06c6

File tree

7 files changed

+99
-99
lines changed

7 files changed

+99
-99
lines changed

pdoc/__init__.py

Lines changed: 22 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ def _get_config(**kwargs):
128128
| {'module', 'modules', 'http_server', 'external_links', 'search_query'})
129129
invalid_keys = {k: v for k, v in kwargs.items() if k not in known_keys}
130130
if invalid_keys:
131-
warn('Unknown configuration variables (not in config.mako): {}'.format(invalid_keys))
131+
warn(f'Unknown configuration variables (not in config.mako): {invalid_keys}')
132132
config.update(kwargs)
133133

134134
if 'search_query' in config:
@@ -150,10 +150,9 @@ def _render_template(template_name, **kwargs):
150150
try:
151151
t = tpl_lookup.get_template(template_name)
152152
except TopLevelLookupException:
153-
raise OSError(
154-
"No template found at any of: {}".format(
155-
', '.join(path.join(p, template_name.lstrip("/"))
156-
for p in tpl_lookup.directories)))
153+
paths = [path.join(p, template_name.lstrip('/')) for p in tpl_lookup.directories]
154+
raise OSError(f"No template found at any of: {', '.join(paths)}")
155+
157156
try:
158157
return t.render(**config).strip()
159158
except Exception:
@@ -224,8 +223,7 @@ def _module_path(module):
224223
try:
225224
module = importlib.import_module(module_path)
226225
except Exception as e:
227-
raise ImportError('Error importing {!r}: {}: {}'
228-
.format(module, e.__class__.__name__, e))
226+
raise ImportError(f'Error importing {module!r}: {e.__class__.__name__}: {e}')
229227

230228
assert inspect.ismodule(module)
231229
# If this is pdoc itself, return without reloading. Otherwise later
@@ -272,7 +270,7 @@ def _pep224_docstrings(doc_obj: Union['Module', 'Class'], *,
272270
# Don't emit a warning for builtins that don't have source available
273271
is_builtin = getattr(doc_obj.obj, '__module__', None) == 'builtins'
274272
if not is_builtin:
275-
warn("Couldn't read PEP-224 variable docstrings from {!r}: {}".format(doc_obj, exc),
273+
warn(f"Couldn't read PEP-224 variable docstrings from {doc_obj!r}: {exc}",
276274
stacklevel=3 + int(isinstance(doc_obj, Class)))
277275
return {}, {}
278276

@@ -409,7 +407,7 @@ def _toposort(graph: Mapping[T, Set[T]]) -> Generator[T, None, None]:
409407
yield from ordered
410408
if not ordered:
411409
break
412-
assert not graph, "A cyclic dependency exists amongst %r" % graph
410+
assert not graph, f"A cyclic dependency exists amongst {graph!r}"
413411

414412

415413
def link_inheritance(context: Context = None):
@@ -492,7 +490,7 @@ def __init__(self, name, module, obj, docstring=None):
492490
"""
493491

494492
def __repr__(self):
495-
return '<{} {!r}>'.format(self.__class__.__name__, self.refname)
493+
return f'<{self.__class__.__name__} {self.refname!r}>'
496494

497495
@property # type: ignore
498496
@lru_cache()
@@ -640,8 +638,8 @@ def __init__(self, module: Union[ModuleType, str], *, docfilter: Callable[[Doc],
640638
try:
641639
obj = getattr(self.obj, name)
642640
except AttributeError:
643-
warn("Module {!r} doesn't contain identifier `{}` "
644-
"exported in `__all__`".format(self.module, name))
641+
warn(f"Module {self.module!r} doesn't contain identifier `{name}` "
642+
"exported in `__all__`")
645643
if not _is_blacklisted(name, self):
646644
obj = inspect.unwrap(obj)
647645
public_objs.append((name, obj))
@@ -703,7 +701,7 @@ def iter_modules(paths):
703701
continue
704702

705703
assert self.refname == self.name
706-
fullname = "%s.%s" % (self.name, root)
704+
fullname = f"{self.name}.{root}"
707705
try:
708706
m = Module(import_module(fullname),
709707
docfilter=docfilter, supermodule=self,
@@ -767,20 +765,20 @@ def _link_inheritance(self):
767765
if docstring is True:
768766
continue
769767

770-
refname = "%s.%s" % (self.refname, name)
768+
refname = f"{self.refname}.{name}"
771769
if docstring in (False, None):
772770
if docstring is None:
773771
warn('Setting `__pdoc__[key] = None` is deprecated; '
774772
'use `__pdoc__[key] = False` '
775-
'(key: {!r}, module: {!r}).'.format(name, self.name))
773+
f'(key: {name!r}, module: {self.name!r}).')
776774

777775
if name in self._skipped_submodules:
778776
continue
779777

780778
if (not name.endswith('.__init__') and
781779
name not in self.doc and refname not in self._context):
782-
warn('__pdoc__-overriden key {!r} does not exist '
783-
'in module {!r}'.format(name, self.name))
780+
warn(f'__pdoc__-overriden key {name!r} does not exist '
781+
f'in module {self.name!r}')
784782

785783
obj = self.find_ident(name)
786784
cls = getattr(obj, 'cls', None)
@@ -800,8 +798,8 @@ def _link_inheritance(self):
800798
if isinstance(dobj, External):
801799
continue
802800
if not isinstance(docstring, str):
803-
raise ValueError('__pdoc__ dict values must be strings;'
804-
'__pdoc__[{!r}] is of type {}'.format(name, type(docstring)))
801+
raise ValueError('__pdoc__ dict values must be strings; '
802+
f'__pdoc__[{name!r}] is of type {type(docstring)}')
805803
dobj.docstring = inspect.cleandoc(docstring)
806804

807805
# Now after docstrings are set correctly, continue the
@@ -1044,7 +1042,7 @@ def _method_type(cls: type, name: str):
10441042
if isinstance(c.__dict__[name], staticmethod):
10451043
return staticmethod
10461044
return None
1047-
raise RuntimeError("{}.{} not found".format(cls, name))
1045+
raise RuntimeError(f"{cls}.{name} not found")
10481046

10491047
@property
10501048
def refname(self) -> str:
@@ -1307,7 +1305,7 @@ def return_annotation(self, *, link=None) -> str:
13071305
else:
13081306
# Don't warn on variables. The annotation just isn't available.
13091307
if not isinstance(self, Variable):
1310-
warn("Error handling return annotation for {!r}".format(self), stacklevel=3)
1308+
warn(f"Error handling return annotation for {self!r}", stacklevel=3)
13111309

13121310
if annot is inspect.Parameter.empty or not annot:
13131311
return ''
@@ -1469,10 +1467,10 @@ def _signature_from_string(self):
14691467
# See: https://github.com/pdoc3/pdoc/pull/148#discussion_r407114141
14701468
module_basename = self.module.name.rsplit('.', maxsplit=1)[-1]
14711469
if module_basename in string and module_basename not in _globals:
1472-
string = re.sub(r'(?<!\.)\b{}\.\b'.format(module_basename), '', string)
1470+
string = re.sub(fr'(?<!\.)\b{module_basename}\.\b', '', string)
14731471

14741472
try:
1475-
exec('def {}: pass'.format(string), _globals, _locals)
1473+
exec(f'def {string}: pass', _globals, _locals)
14761474
except SyntaxError:
14771475
continue
14781476
signature = inspect.signature(_locals[self.name])
@@ -1565,4 +1563,4 @@ def url(self, *args, **kwargs):
15651563
"""
15661564
`External` objects return absolute urls matching `/{name}.ext`.
15671565
"""
1568-
return '/%s.ext' % self.name
1566+
return f'/{self.name}.ext'

pdoc/cli.py

Lines changed: 22 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@
129129
def _check_host_port(s):
130130
if s and ':' not in s:
131131
raise argparse.ArgumentTypeError(
132-
"'{}' doesn't match '[HOST]:[PORT]'. "
133-
"Specify `--http :` to use default hostname and port.".format(s))
132+
f"'{s}' doesn't match '[HOST]:[PORT]'. "
133+
"Specify `--http :` to use default hostname and port.")
134134
return s
135135

136136

@@ -141,7 +141,7 @@ def _check_host_port(s):
141141
metavar='HOST:PORT',
142142
help="When set, pdoc will run as an HTTP server providing documentation "
143143
"for specified modules. If you just want to use the default hostname "
144-
"and port ({}:{}), set the parameter to :.".format(DEFAULT_HOST, DEFAULT_PORT),
144+
f"and port ({DEFAULT_HOST}:{DEFAULT_PORT}), set the parameter to :.",
145145
)
146146
aa(
147147
"--skip-errors",
@@ -212,14 +212,14 @@ def do_GET(self):
212212
import_path = self.path[:-4].lstrip("/")
213213
resolved = self.resolve_ext(import_path)
214214
if resolved is None: # Try to generate the HTML...
215-
print("Generating HTML for %s on the fly..." % import_path, file=sys.stderr)
215+
print(f"Generating HTML for {import_path} on the fly...", file=sys.stderr)
216216
try:
217217
out = pdoc.html(import_path.split(".")[0], **self.template_config)
218218
except Exception as e:
219-
print('Error generating docs: {}'.format(e), file=sys.stderr)
219+
print(f'Error generating docs: {e}', file=sys.stderr)
220220
# All hope is lost.
221221
code = 404
222-
out = "External identifier <code>%s</code> not found." % import_path
222+
out = f"External identifier <code>{import_path}</code> not found."
223223
else:
224224
return self.redirect(resolved)
225225
# Redirect '/pdoc' to '/pdoc/' so that relative links work
@@ -236,8 +236,11 @@ def do_GET(self):
236236
import traceback
237237
from html import escape
238238
code = 404
239-
out = "Error importing module <code>{}</code>:\n\n<pre>{}</pre>".format(
240-
self.import_path_from_req_url, escape(traceback.format_exc()))
239+
out = (
240+
"Error importing module "
241+
f"<code>{self.import_path_from_req_url}</code>:\n\n"
242+
f"<pre>{escape(traceback.format_exc())}</pre>"
243+
)
241244
out = out.replace('\n', '<br>')
242245

243246
self.send_response(code)
@@ -282,7 +285,7 @@ def exists(p):
282285
p = path.join(*parts[0:i])
283286
realp = exists(p)
284287
if realp is not None:
285-
return "/%s#%s" % (realp.lstrip("/"), import_path)
288+
return f"/{realp.lstrip('/')}#{import_path}"
286289
return None
287290

288291
@property
@@ -312,8 +315,7 @@ def _quit_if_exists(m: pdoc.Module, ext: str):
312315

313316
for pth in paths:
314317
if path.lexists(pth):
315-
print("File '%s' already exists. Delete it, or run with --force" % pth,
316-
file=sys.stderr)
318+
print(f"File '{pth}' already exists. Delete it, or run with --force", file=sys.stderr)
317319
sys.exit(1)
318320

319321

@@ -362,7 +364,7 @@ def _print_pdf(modules, **kwargs):
362364

363365

364366
def _warn_deprecated(option, alternative='', use_config_mako=False):
365-
msg = 'Program option `{}` is deprecated.'.format(option)
367+
msg = f'Program option `{option}` is deprecated.'
366368
if alternative:
367369
msg += ' Use `' + alternative + '`'
368370
if use_config_mako:
@@ -453,9 +455,8 @@ def main(_args=None):
453455
template_config[key] = value
454456
except Exception:
455457
raise ValueError(
456-
'Error evaluating --config statement "{}". '
458+
f'Error evaluating --config statement "{config_str}". '
457459
'Make sure string values are quoted?'
458-
.format(config_str)
459460
)
460461

461462
if args.html_no_source:
@@ -470,8 +471,7 @@ def main(_args=None):
470471

471472
if args.template_dir is not None:
472473
if not path.isdir(args.template_dir):
473-
print('Error: Template dir {!r} is not a directory'.format(args.template_dir),
474-
file=sys.stderr)
474+
print(f'Error: Template dir {args.template_dir!r} is not a directory', file=sys.stderr)
475475
sys.exit(1)
476476
pdoc.tpl_lookup.directories.insert(0, args.template_dir)
477477

@@ -495,7 +495,7 @@ def main(_args=None):
495495
with open(pth) as f:
496496
sys.path.append(path.join(libdir, f.readline().rstrip()))
497497
except IOError:
498-
warn('Invalid egg-link in venv: {!r}'.format(pth))
498+
warn(f'Invalid egg-link in venv: {pth!r}')
499499

500500
if args.http:
501501
template_config['link_prefix'] = "/"
@@ -508,9 +508,9 @@ def main(_args=None):
508508
host = host or DEFAULT_HOST
509509
port = int(port or DEFAULT_PORT)
510510

511-
print('Starting pdoc server on {}:{}'.format(host, port), file=sys.stderr)
511+
print(f'Starting pdoc server on {host}:{port}', file=sys.stderr)
512512
httpd = HTTPServer((host, port), _WebDoc)
513-
print("pdoc server ready at http://%s:%d" % (host, port), file=sys.stderr)
513+
print(f"pdoc server ready at http://{host}:{port}", file=sys.stderr)
514514

515515
# Allow tests to perform `pdoc.cli._httpd.shutdown()`
516516
global _httpd
@@ -537,7 +537,8 @@ def docfilter(obj, _filters=args.filter.strip().split(',')):
537537
if args.pdf:
538538
_print_pdf(modules, **template_config)
539539
import textwrap
540-
print("""
540+
PANDOC_CMD = textwrap.indent(_PANDOC_COMMAND, ' ')
541+
print(f"""
541542
PDF-ready markdown written to standard output.
542543
^^^^^^^^^^^^^^^
543544
Convert this file to PDF using e.g. Pandoc:
@@ -562,7 +563,7 @@ def docfilter(obj, _filters=args.filter.strip().split(',')):
562563
563564
wkhtmltopdf --encoding utf8 -s A4 --print-media-type pdf.html pdf.pdf
564565
565-
or similar, at your own discretion.""".format(PANDOC_CMD=textwrap.indent(_PANDOC_COMMAND, ' ')),
566+
or similar, at your own discretion.""",
566567
file=sys.stderr)
567568
sys.exit(0)
568569

0 commit comments

Comments
 (0)