4646import atexit
4747import base64
4848import builtins
49- from collections import OrderedDict
5049import glob
5150import hashlib
5251import io
6362import tempfile
6463import textwrap
6564import time
66- import types
6765import unittest
68- import uuid
6966
7067
7168#
114111 sections .append (section .strip ())
115112
116113
117- def f (s ):
118- """
119- Basic support for 3.6's f-strings, in 3.5!
120-
121- Formats "s" using appropriate globals and locals
122- dictionaries. This f-string:
123- f"hello a is {a}"
124- simply becomes
125- f("hello a is {a}")
126- In other words, just throw parentheses around the
127- string, and you're done!
128-
129- Implemented internally using str.format_map().
130- This means it doesn't support expressions:
131- f("two minus three is {2-3}")
132- And it doesn't support function calls:
133- f("how many elements? {len(my_list)}")
134- But most other f-string features work.
135- """
136- frame = sys ._getframe (1 )
137- d = dict (builtins .__dict__ )
138- d .update (frame .f_globals )
139- d .update (frame .f_locals )
140- return s .format_map (d )
141-
142-
143114def sanitize_section (section ):
144115 """
145116Cleans up a section string, making it viable as a directory name.
@@ -252,10 +223,10 @@ def sortable_datetime():
252223
253224
254225def prompt (prompt ):
255- return input (f ( "[{prompt}> " ) )
226+ return input (f"[{ prompt } > " )
256227
257228def require_ok (prompt ):
258- prompt = f ( "[{prompt}> " )
229+ prompt = f"[{ prompt } > "
259230 while True :
260231 s = input (prompt ).strip ()
261232 if s == 'ok' :
@@ -485,7 +456,7 @@ def parse(self, text, *, metadata=None, filename="input"):
485456 line_number = None
486457
487458 def throw (s ):
488- raise BlurbError (f ( "Error in {filename}:{line_number}:\n {s}" ) )
459+ raise BlurbError (f"Error in { filename } :{ line_number } :\n { s } " )
489460
490461 def finish_entry ():
491462 nonlocal body
@@ -565,7 +536,7 @@ def __str__(self):
565536 add_separator = True
566537 if metadata :
567538 for name , value in sorted (metadata .items ()):
568- add (f ( ".. {name}: {value}\n " ) )
539+ add (f".. { name } : { value } \n " )
569540 add ("\n " )
570541 add (textwrap_body (body ))
571542 return "" .join (output )
@@ -587,10 +558,10 @@ def _parse_next_filename(filename):
587558 components = filename .split (os .sep )
588559 section , filename = components [- 2 :]
589560 section = unsanitize_section (section )
590- assert section in sections , f ( "Unknown section {section}" )
561+ assert section in sections , f"Unknown section { section } "
591562
592563 fields = [x .strip () for x in filename .split ("." )]
593- assert len (fields ) >= 4 , f ( "Can't parse 'next' filename! filename {filename!r} fields {fields}" )
564+ assert len (fields ) >= 4 , f"Can't parse 'next' filename! filename { filename !r} fields { fields } "
594565 assert fields [- 1 ] == "rst"
595566
596567 metadata = {"date" : fields [0 ], "nonce" : fields [- 2 ], "section" : section }
@@ -779,7 +750,7 @@ def subcommand(fn):
779750def get_subcommand (subcommand ):
780751 fn = subcommands .get (subcommand )
781752 if not fn :
782- error (f ( "Unknown subcommand: {subcommand}\n Run 'blurb help' for help." ) )
753+ error (f"Unknown subcommand: { subcommand } \n Run 'blurb help' for help." )
783754 return fn
784755
785756
@@ -841,19 +812,19 @@ def help(subcommand=None):
841812 for name , p in inspect .signature (fn ).parameters .items ():
842813 if p .kind == inspect .Parameter .KEYWORD_ONLY :
843814 short_option = name [0 ]
844- options .append (f ( " [-{short_option}|--{name}]" ) )
815+ options .append (f" [-{ short_option } |--{ name } ]" )
845816 elif p .kind == inspect .Parameter .POSITIONAL_OR_KEYWORD :
846817 positionals .append (" " )
847818 has_default = (p .default != inspect ._empty )
848819 if has_default :
849820 positionals .append ("[" )
850821 nesting += 1
851- positionals .append (f ( "<{name}>" ) )
822+ positionals .append (f"<{ name } >" )
852823 positionals .append ("]" * nesting )
853824
854825
855826 parameters = "" .join (options + positionals )
856- print (f ( "blurb {subcommand}{parameters}" ) )
827+ print (f"blurb { subcommand } { parameters } " )
857828 print ()
858829 print (doc )
859830 sys .exit (0 )
@@ -944,7 +915,7 @@ def init_tmp_with_template():
944915 else :
945916 args = list (shlex .split (editor ))
946917 if not shutil .which (args [0 ]):
947- sys .exit (f ( "Invalid GIT_EDITOR / EDITOR value: {editor}" ) )
918+ sys .exit (f"Invalid GIT_EDITOR / EDITOR value: { editor } " )
948919 args .append (tmp_path )
949920
950921 while True :
@@ -964,7 +935,7 @@ def init_tmp_with_template():
964935
965936 if failure :
966937 print ()
967- print (f ( "Error: {failure}" ) )
938+ print (f"Error: { failure } " )
968939 print ()
969940 try :
970941 prompt ("Hit return to retry (or Ctrl-C to abort)" )
@@ -998,20 +969,20 @@ def release(version):
998969 if existing_filenames :
999970 error ("Sorry, can't handle appending 'next' files to an existing version (yet)." )
1000971
1001- output = f ( "Misc/NEWS.d/{version}.rst" )
972+ output = f"Misc/NEWS.d/{ version } .rst"
1002973 filenames = glob_blurbs ("next" )
1003974 blurbs = Blurbs ()
1004975 date = current_date ()
1005976
1006977 if not filenames :
1007- print (f ( "No blurbs found. Setting {version} as having no changes." ) )
1008- body = f ( "There were no new changes in version {version}.\n " )
978+ print (f"No blurbs found. Setting { version } as having no changes." )
979+ body = f"There were no new changes in version { version } .\n "
1009980 metadata = {"no changes" : "True" , "bpo" : "0" , "section" : "Library" , "date" : date , "nonce" : nonceify (body )}
1010981 blurbs .append ((metadata , body ))
1011982 else :
1012983 no_changes = None
1013984 count = len (filenames )
1014- print (f ( 'Merging {count} blurbs to "{output}".' ) )
985+ print (f'Merging { count } blurbs to "{ output } ".' )
1015986
1016987 for filename in filenames :
1017988 if not filename .endswith (".rst" ):
@@ -1028,14 +999,14 @@ def release(version):
1028999 flush_git_add_files ()
10291000
10301001 how_many = len (filenames )
1031- print (f ( "Removing {how_many} 'next' files from git." ) )
1002+ print (f"Removing { how_many } 'next' files from git." )
10321003 git_rm_files .extend (filenames )
10331004 flush_git_rm_files ()
10341005
10351006 # sanity check: ensuring that saving/reloading the merged blurb file works.
10361007 blurbs2 = Blurbs ()
10371008 blurbs2 .load (output )
1038- assert blurbs2 == blurbs , f ( "Reloading {output} isn't reproducible?!" )
1009+ assert blurbs2 == blurbs , f"Reloading { output } isn't reproducible?!"
10391010
10401011 print ()
10411012 print ("Ready for commit." )
@@ -1110,7 +1081,7 @@ def print(*a, sep=" "):
11101081 metadata , body = blurbs [0 ]
11111082 release_date = metadata ["release date" ]
11121083
1113- print (f ( "*Release date: {release_date}*" ) )
1084+ print (f"*Release date: { release_date } *" )
11141085 print ()
11151086
11161087 if "no changes" in metadata :
@@ -1191,11 +1162,11 @@ def populate():
11911162
11921163 for section in sections :
11931164 dir_name = sanitize_section (section )
1194- dir_path = f ( "NEWS.d/next/{dir_name}" )
1165+ dir_path = f"NEWS.d/next/{ dir_name } "
11951166 safe_mkdir (dir_path )
1196- readme_path = f ( "NEWS.d/next/{dir_name}/README.rst" )
1167+ readme_path = f"NEWS.d/next/{ dir_name } /README.rst"
11971168 with open (readme_path , "wt" , encoding = "utf-8" ) as readme :
1198- readme .write (f ( "Put news entry ``blurb`` files for the *{section}* section in this directory.\n " ) )
1169+ readme .write (f"Put news entry ``blurb`` files for the *{ section } * section in this directory.\n " )
11991170 git_add_files .append (dir_path )
12001171 git_add_files .append (readme_path )
12011172 flush_git_add_files ()
@@ -1216,7 +1187,7 @@ def export():
12161187# """
12171188# Test function for blurb command-line processing.
12181189# """
1219- # print(f( "arg: boolean {boolean} option {option}") )
1190+ # print(f"arg: boolean {boolean} option {option}")
12201191
12211192
12221193@subcommand
@@ -1301,7 +1272,7 @@ def flush_blurb():
13011272 fields .append (field )
13021273 see_also = ", " .join (fields )
13031274 # print("see_also: ", repr(see_also))
1304- accumulator .append (f ( "(See also: {see_also})" ) )
1275+ accumulator .append (f"(See also: { see_also } )" )
13051276 see_also = None
13061277 if not accumulator :
13071278 return
@@ -1347,8 +1318,8 @@ def flush_version():
13471318 if version is None :
13481319 assert not blurbs , "version should only be None initially, we shouldn't have blurbs yet"
13491320 return
1350- assert blurbs , f ( "No blurbs defined when flushing version {version}!" )
1351- output = f ( "NEWS.d/{version}.rst" )
1321+ assert blurbs , f"No blurbs defined when flushing version { version } !"
1322+ output = f"NEWS.d/{ version } .rst"
13521323
13531324 if released :
13541325 # saving merged blurb file for version, e.g. Misc/NEWS.d/3.7.0a1.rst
@@ -1466,11 +1437,11 @@ def flush_version():
14661437 elif line .startswith ("- Issue #9516: Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET" ):
14671438 line = "- Issue #9516 and Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET"
14681439 elif line .title ().startswith (("- Request #" , "- Bug #" , "- Patch #" , "- Patches #" )):
1469- # print(f( "FIXING LINE {line_number}: {line!r}") )
1440+ # print(f"FIXING LINE {line_number}: {line!r}")
14701441 line = "- Issue #" + line .partition ('#' )[2 ]
1471- # print(f( "FIXED LINE {line_number}: {line!r}") )
1442+ # print(f"FIXED LINE {line_number}: {line!r}")
14721443 # else:
1473- # print(f( "NOT FIXING LINE {line_number}: {line!r}") )
1444+ # print(f"NOT FIXING LINE {line_number}: {line!r}")
14741445
14751446
14761447 # 4. determine the actual content of the line
@@ -1535,7 +1506,7 @@ def flush_version():
15351506 line = line [4 :]
15361507 parse_bpo = True
15371508 else :
1538- # print(f( "[[{line_number:8} no bpo]] {line}") )
1509+ # print(f"[[{line_number:8} no bpo]] {line}")
15391510 parse_bpo = False
15401511 if parse_bpo :
15411512 # GAAAH
@@ -1575,9 +1546,9 @@ def flush_version():
15751546 try :
15761547 int (bpo ) # this will throw if it's not a legal int
15771548 except ValueError :
1578- sys .exit (f ( "Couldn't convert bpo number to int on line {line_number}! {bpo!r}" ) )
1549+ sys .exit (f"Couldn't convert bpo number to int on line { line_number } ! { bpo !r} " )
15791550 if see_also == "partially" :
1580- sys .exit (f ( "What the hell on line {line_number}! {bpo!r}" ) )
1551+ sys .exit (f"What the hell on line { line_number } ! { bpo !r} " )
15811552
15821553 # 4.6.1 continuation of blurb
15831554 elif line .startswith (" " ):
@@ -1586,7 +1557,7 @@ def flush_version():
15861557 elif line .startswith (" * " ):
15871558 line = line [3 :]
15881559 elif line :
1589- sys .exit (f ( "Didn't recognize line {line_number}! {line!r}" ) )
1560+ sys .exit (f"Didn't recognize line { line_number } ! { line !r} " )
15901561 # only add blank lines if we have an initial line in the accumulator
15911562 if line or accumulator :
15921563 accumulator .append (line )
@@ -1598,7 +1569,7 @@ def flush_version():
15981569 git_rm_files .append ("NEWS" )
15991570 flush_git_rm_files ()
16001571
1601- print (f ( "Wrote {blurb_count} news items across {version_count} versions." ) )
1572+ print (f"Wrote { blurb_count } news items across { version_count } versions." )
16021573 print ()
16031574 print ("Ready for commit." )
16041575
@@ -1647,10 +1618,10 @@ def main():
16471618 def handle_option (s , dict ):
16481619 name = dict .get (s , None )
16491620 if not name :
1650- sys .exit (f ( 'blurb: Unknown option for {subcommand}: "{s}"' ) )
1621+ sys .exit (f'blurb: Unknown option for { subcommand } : "{ s } "' )
16511622 kwargs [name ] = not kwargs [name ]
16521623
1653- # print(f( "short_options {short_options} long_options {long_options}") )
1624+ # print(f"short_options {short_options} long_options {long_options}")
16541625 for a in args :
16551626 if done_with_options :
16561627 filtered_args .append (a )
@@ -1684,7 +1655,7 @@ def handle_option(s, dict):
16841655 # whoops, must be a real type error, reraise
16851656 raise e
16861657
1687- how_many = f ( "{specified} argument" )
1658+ how_many = f"{ specified } argument"
16881659 if specified != 1 :
16891660 how_many += "s"
16901661
@@ -1695,12 +1666,12 @@ def handle_option(s, dict):
16951666 middle = "requires"
16961667 else :
16971668 plural = "" if required == 1 else "s"
1698- middle = f ( "requires at least {required} argument{plural} and at most" )
1699- middle += f ( " {total} argument" )
1669+ middle = f"requires at least { required } argument{ plural } and at most"
1670+ middle += f" { total } argument"
17001671 if total != 1 :
17011672 middle += "s"
17021673
1703- print (f ( 'Error: Wrong number of arguments!\n \n blurb {subcommand} {middle},\n and you specified {how_many}.' ) )
1674+ print (f'Error: Wrong number of arguments!\n \n blurb { subcommand } { middle } ,\n and you specified { how_many } .' )
17041675 print ()
17051676 print ("usage: " , end = "" )
17061677 help (subcommand )
0 commit comments