22# License, v. 2.0. If a copy of the MPL was not distributed with this
33# file, You can obtain one at http://mozilla.org/MPL/2.0/.
44
5- from __future__ import absolute_import
6-
75from base64 import b64encode , b64decode
86from collections import OrderedDict
97from os .path import isfile
108import datetime
119import json
1210import os
1311import pkg_resources
14- import sys
1512import time
1613import bisect
1714import warnings
1815import re
1916
17+ from html import escape
18+
2019try :
2120 from ansi2html import Ansi2HTMLConverter , style
2221
3029from . import extras
3130from . import __version__ , __pypi_url__
3231
33- PY3 = sys .version_info [0 ] == 3
34-
35- # Python 2.X and 3.X compatibility
36- if PY3 :
37- basestring = str
38- from html import escape
39- else :
40- from codecs import open
41- from cgi import escape
42-
4332
4433def pytest_addhooks (pluginmanager ):
4534 from . import hooks
@@ -95,10 +84,10 @@ def pytest_unconfigure(config):
9584
9685def data_uri (content , mime_type = "text/plain" , charset = "utf-8" ):
9786 data = b64encode (content .encode (charset )).decode ("ascii" )
98- return "data:{0 };charset={1 };base64,{2}" . format ( mime_type , charset , data )
87+ return f "data:{ mime_type } ;charset={ charset } ;base64,{ data } "
9988
10089
101- class HTMLReport ( object ) :
90+ class HTMLReport :
10291 def __init__ (self , logfile , config ):
10392 logfile = os .path .expanduser (os .path .expandvars (logfile ))
10493 self .logfile = os .path .abspath (logfile )
@@ -136,7 +125,7 @@ def __init__(self, outcome, report, logfile, config):
136125 cells = [
137126 html .td (self .outcome , class_ = "col-result" ),
138127 html .td (self .test_id , class_ = "col-name" ),
139- html .td ("{0 :.2f}". format ( self . time ) , class_ = "col-duration" ),
128+ html .td (f" { self . time :.2f} " , class_ = "col-duration" ),
140129 html .td (self .links_html , class_ = "col-links" ),
141130 ]
142131
@@ -181,7 +170,7 @@ def create_asset(
181170 if not os .path .exists (os .path .dirname (asset_path )):
182171 os .makedirs (os .path .dirname (asset_path ))
183172
184- relative_path = "{0}/{1}" . format ( "assets" , asset_file_name )
173+ relative_path = f"assets/ { asset_file_name } "
185174
186175 kwargs = {"encoding" : "utf-8" } if "b" not in mode else {}
187176 with open (asset_path , mode , ** kwargs ) as f :
@@ -209,13 +198,10 @@ def append_extra_html(self, extra, extra_index, test_index):
209198 )
210199 html_div = html .a (html .img (src = content ), href = content )
211200 elif self .self_contained :
212- src = "data:{0 };base64,{1 }" .format (extra .get ("mime_type" ), content )
201+ src = "data:{};base64,{}" .format (extra .get ("mime_type" ), content )
213202 html_div = html .img (src = src )
214203 else :
215- if PY3 :
216- content = content .encode ("utf-8" )
217-
218- content = b64decode (content )
204+ content = b64decode (content .encode ("utf-8" ))
219205 href = src = self .create_asset (
220206 content , extra_index , test_index , extra .get ("extension" ), "wb"
221207 )
@@ -276,7 +262,7 @@ def append_log_html(self, report, additional_html):
276262
277263 for section in report .sections :
278264 header , content = map (escape , section )
279- log .append (" {0} " . format ( header ). center ( 80 , "-" ) )
265+ log .append (f " { header :-^80 } " )
280266 log .append (html .br ())
281267 if ANSI :
282268 converter = Ansi2HTMLConverter (inline = False , escaped = False )
@@ -296,7 +282,7 @@ def _appendrow(self, outcome, report):
296282 self .results .insert (index , result )
297283 tbody = html .tbody (
298284 result .row_table ,
299- class_ = "{0 } results-table-row" .format (result .outcome .lower ()),
285+ class_ = "{} results-table-row" .format (result .outcome .lower ()),
300286 )
301287 if result .row_extra is not None :
302288 tbody .append (result .row_extra )
@@ -345,9 +331,7 @@ def _generate_report(self, session):
345331
346332 self .style_css = pkg_resources .resource_string (
347333 __name__ , os .path .join ("resources" , "style.css" )
348- )
349- if PY3 :
350- self .style_css = self .style_css .decode ("utf-8" )
334+ ).decode ("utf-8" )
351335
352336 if ANSI :
353337 ansi_css = [
@@ -362,12 +346,12 @@ def _generate_report(self, session):
362346 for path in self .config .getoption ("css" ):
363347 self .style_css += "\n /******************************"
364348 self .style_css += "\n * CUSTOM CSS"
365- self .style_css += "\n * {}" . format ( path )
349+ self .style_css += f "\n * { path } "
366350 self .style_css += "\n ******************************/\n \n "
367351 with open (path , "r" ) as f :
368352 self .style_css += f .read ()
369353
370- css_href = "{0}/{1}" . format ( " assets" , " style.css")
354+ css_href = "assets/ style.css"
371355 html_css = html .link (href = css_href , rel = "stylesheet" , type = "text/css" )
372356 if self .self_contained :
373357 html_css = html .style (raw (self .style_css ))
@@ -401,12 +385,12 @@ def generate_checkbox(self):
401385 name = "filter_checkbox" ,
402386 class_ = "filter" ,
403387 hidden = "true" ,
404- ** checkbox_kwargs
388+ ** checkbox_kwargs ,
405389 )
406390
407391 def generate_summary_item (self ):
408392 self .summary_item = html .span (
409- "{0} {1}" . format ( self .total , self .label ) , class_ = self .class_html
393+ f" { self .total } { self .label } " , class_ = self .class_html
410394 )
411395
412396 outcomes = [
@@ -422,9 +406,7 @@ def generate_summary_item(self):
422406 outcomes .append (Outcome ("rerun" , self .rerun ))
423407
424408 summary = [
425- html .p (
426- "{0} tests ran in {1:.2f} seconds. " .format (numtests , suite_time_delta )
427- ),
409+ html .p (f"{ numtests } tests ran in { suite_time_delta :.2f} seconds. " ),
428410 html .p (
429411 "(Un)check the boxes to filter the results." ,
430412 class_ = "filter" ,
@@ -472,19 +454,17 @@ def generate_summary_item(self):
472454
473455 main_js = pkg_resources .resource_string (
474456 __name__ , os .path .join ("resources" , "main.js" )
475- )
476- if PY3 :
477- main_js = main_js .decode ("utf-8" )
457+ ).decode ("utf-8" )
478458
479459 body = html .body (
480460 html .script (raw (main_js )),
481461 html .h1 (os .path .basename (self .logfile )),
482462 html .p (
483- "Report generated on {0 } at {1 } by " .format (
463+ "Report generated on {} at {} by " .format (
484464 generated .strftime ("%d-%b-%Y" ), generated .strftime ("%H:%M:%S" )
485465 ),
486466 html .a ("pytest-html" , href = __pypi_url__ ),
487- " v{0}" . format ( __version__ ) ,
467+ f " v{ __version__ } " ,
488468 ),
489469 onLoad = "init()" ,
490470 )
@@ -501,12 +481,11 @@ def generate_summary_item(self):
501481
502482 doc = html .html (head , body )
503483
504- unicode_doc = u"<!DOCTYPE html>\n {0}" .format (doc .unicode (indent = 2 ))
505- if PY3 :
506- # Fix encoding issues, e.g. with surrogates
507- unicode_doc = unicode_doc .encode ("utf-8" , errors = "xmlcharrefreplace" )
508- unicode_doc = unicode_doc .decode ("utf-8" )
509- return unicode_doc
484+ unicode_doc = "<!DOCTYPE html>\n {}" .format (doc .unicode (indent = 2 ))
485+
486+ # Fix encoding issues, e.g. with surrogates
487+ unicode_doc = unicode_doc .encode ("utf-8" , errors = "xmlcharrefreplace" )
488+ return unicode_doc .decode ("utf-8" )
510489
511490 def _generate_environment (self , config ):
512491 if not hasattr (config , "_metadata" ) or config ._metadata is None :
@@ -522,10 +501,10 @@ def _generate_environment(self, config):
522501
523502 for key in keys :
524503 value = metadata [key ]
525- if isinstance (value , basestring ) and value .startswith ("http" ):
504+ if isinstance (value , str ) and value .startswith ("http" ):
526505 value = html .a (value , href = value , target = "_blank" )
527506 elif isinstance (value , (list , tuple , set )):
528- value = ", " .join (( str (i ) for i in value ) )
507+ value = ", " .join (str (i ) for i in value )
529508 rows .append (html .tr (html .td (key ), html .td (value )))
530509
531510 environment .append (html .table (rows , id = "environment" ))
@@ -569,6 +548,4 @@ def pytest_sessionfinish(self, session):
569548 self ._save_report (report_content )
570549
571550 def pytest_terminal_summary (self , terminalreporter ):
572- terminalreporter .write_sep (
573- "-" , "generated html file: file://{0}" .format (self .logfile )
574- )
551+ terminalreporter .write_sep ("-" , f"generated html file: file://{ self .logfile } " )
0 commit comments