46
46
import atexit
47
47
import base64
48
48
import builtins
49
- from collections import OrderedDict
50
49
import glob
51
50
import hashlib
52
51
import io
63
62
import tempfile
64
63
import textwrap
65
64
import time
66
- import types
67
65
import unittest
68
- import uuid
69
66
70
67
71
68
#
114
111
sections .append (section .strip ())
115
112
116
113
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
-
143
114
def sanitize_section (section ):
144
115
"""
145
116
Cleans up a section string, making it viable as a directory name.
@@ -252,10 +223,10 @@ def sortable_datetime():
252
223
253
224
254
225
def prompt (prompt ):
255
- return input (f ( "[{prompt}> " ) )
226
+ return input (f"[{ prompt } > " )
256
227
257
228
def require_ok (prompt ):
258
- prompt = f ( "[{prompt}> " )
229
+ prompt = f"[{ prompt } > "
259
230
while True :
260
231
s = input (prompt ).strip ()
261
232
if s == 'ok' :
@@ -485,7 +456,7 @@ def parse(self, text, *, metadata=None, filename="input"):
485
456
line_number = None
486
457
487
458
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 } " )
489
460
490
461
def finish_entry ():
491
462
nonlocal body
@@ -565,7 +536,7 @@ def __str__(self):
565
536
add_separator = True
566
537
if metadata :
567
538
for name , value in sorted (metadata .items ()):
568
- add (f ( ".. {name}: {value}\n " ) )
539
+ add (f".. { name } : { value } \n " )
569
540
add ("\n " )
570
541
add (textwrap_body (body ))
571
542
return "" .join (output )
@@ -587,10 +558,10 @@ def _parse_next_filename(filename):
587
558
components = filename .split (os .sep )
588
559
section , filename = components [- 2 :]
589
560
section = unsanitize_section (section )
590
- assert section in sections , f ( "Unknown section {section}" )
561
+ assert section in sections , f"Unknown section { section } "
591
562
592
563
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 } "
594
565
assert fields [- 1 ] == "rst"
595
566
596
567
metadata = {"date" : fields [0 ], "nonce" : fields [- 2 ], "section" : section }
@@ -779,7 +750,7 @@ def subcommand(fn):
779
750
def get_subcommand (subcommand ):
780
751
fn = subcommands .get (subcommand )
781
752
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." )
783
754
return fn
784
755
785
756
@@ -841,19 +812,19 @@ def help(subcommand=None):
841
812
for name , p in inspect .signature (fn ).parameters .items ():
842
813
if p .kind == inspect .Parameter .KEYWORD_ONLY :
843
814
short_option = name [0 ]
844
- options .append (f ( " [-{short_option}|--{name}]" ) )
815
+ options .append (f" [-{ short_option } |--{ name } ]" )
845
816
elif p .kind == inspect .Parameter .POSITIONAL_OR_KEYWORD :
846
817
positionals .append (" " )
847
818
has_default = (p .default != inspect ._empty )
848
819
if has_default :
849
820
positionals .append ("[" )
850
821
nesting += 1
851
- positionals .append (f ( "<{name}>" ) )
822
+ positionals .append (f"<{ name } >" )
852
823
positionals .append ("]" * nesting )
853
824
854
825
855
826
parameters = "" .join (options + positionals )
856
- print (f ( "blurb {subcommand}{parameters}" ) )
827
+ print (f"blurb { subcommand } { parameters } " )
857
828
print ()
858
829
print (doc )
859
830
sys .exit (0 )
@@ -944,7 +915,7 @@ def init_tmp_with_template():
944
915
else :
945
916
args = list (shlex .split (editor ))
946
917
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 } " )
948
919
args .append (tmp_path )
949
920
950
921
while True :
@@ -964,7 +935,7 @@ def init_tmp_with_template():
964
935
965
936
if failure :
966
937
print ()
967
- print (f ( "Error: {failure}" ) )
938
+ print (f"Error: { failure } " )
968
939
print ()
969
940
try :
970
941
prompt ("Hit return to retry (or Ctrl-C to abort)" )
@@ -998,20 +969,20 @@ def release(version):
998
969
if existing_filenames :
999
970
error ("Sorry, can't handle appending 'next' files to an existing version (yet)." )
1000
971
1001
- output = f ( "Misc/NEWS.d/{version}.rst" )
972
+ output = f"Misc/NEWS.d/{ version } .rst"
1002
973
filenames = glob_blurbs ("next" )
1003
974
blurbs = Blurbs ()
1004
975
date = current_date ()
1005
976
1006
977
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 "
1009
980
metadata = {"no changes" : "True" , "bpo" : "0" , "section" : "Library" , "date" : date , "nonce" : nonceify (body )}
1010
981
blurbs .append ((metadata , body ))
1011
982
else :
1012
983
no_changes = None
1013
984
count = len (filenames )
1014
- print (f ( 'Merging {count} blurbs to "{output}".' ) )
985
+ print (f'Merging { count } blurbs to "{ output } ".' )
1015
986
1016
987
for filename in filenames :
1017
988
if not filename .endswith (".rst" ):
@@ -1028,14 +999,14 @@ def release(version):
1028
999
flush_git_add_files ()
1029
1000
1030
1001
how_many = len (filenames )
1031
- print (f ( "Removing {how_many} 'next' files from git." ) )
1002
+ print (f"Removing { how_many } 'next' files from git." )
1032
1003
git_rm_files .extend (filenames )
1033
1004
flush_git_rm_files ()
1034
1005
1035
1006
# sanity check: ensuring that saving/reloading the merged blurb file works.
1036
1007
blurbs2 = Blurbs ()
1037
1008
blurbs2 .load (output )
1038
- assert blurbs2 == blurbs , f ( "Reloading {output} isn't reproducible?!" )
1009
+ assert blurbs2 == blurbs , f"Reloading { output } isn't reproducible?!"
1039
1010
1040
1011
print ()
1041
1012
print ("Ready for commit." )
@@ -1110,7 +1081,7 @@ def print(*a, sep=" "):
1110
1081
metadata , body = blurbs [0 ]
1111
1082
release_date = metadata ["release date" ]
1112
1083
1113
- print (f ( "*Release date: {release_date}*" ) )
1084
+ print (f"*Release date: { release_date } *" )
1114
1085
print ()
1115
1086
1116
1087
if "no changes" in metadata :
@@ -1191,11 +1162,11 @@ def populate():
1191
1162
1192
1163
for section in sections :
1193
1164
dir_name = sanitize_section (section )
1194
- dir_path = f ( "NEWS.d/next/{dir_name}" )
1165
+ dir_path = f"NEWS.d/next/{ dir_name } "
1195
1166
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"
1197
1168
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 " )
1199
1170
git_add_files .append (dir_path )
1200
1171
git_add_files .append (readme_path )
1201
1172
flush_git_add_files ()
@@ -1216,7 +1187,7 @@ def export():
1216
1187
# """
1217
1188
# Test function for blurb command-line processing.
1218
1189
# """
1219
- # print(f( "arg: boolean {boolean} option {option}") )
1190
+ # print(f"arg: boolean {boolean} option {option}")
1220
1191
1221
1192
1222
1193
@subcommand
@@ -1301,7 +1272,7 @@ def flush_blurb():
1301
1272
fields .append (field )
1302
1273
see_also = ", " .join (fields )
1303
1274
# print("see_also: ", repr(see_also))
1304
- accumulator .append (f ( "(See also: {see_also})" ) )
1275
+ accumulator .append (f"(See also: { see_also } )" )
1305
1276
see_also = None
1306
1277
if not accumulator :
1307
1278
return
@@ -1347,8 +1318,8 @@ def flush_version():
1347
1318
if version is None :
1348
1319
assert not blurbs , "version should only be None initially, we shouldn't have blurbs yet"
1349
1320
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"
1352
1323
1353
1324
if released :
1354
1325
# saving merged blurb file for version, e.g. Misc/NEWS.d/3.7.0a1.rst
@@ -1466,11 +1437,11 @@ def flush_version():
1466
1437
elif line .startswith ("- Issue #9516: Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET" ):
1467
1438
line = "- Issue #9516 and Issue #9516: avoid errors in sysconfig when MACOSX_DEPLOYMENT_TARGET"
1468
1439
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}")
1470
1441
line = "- Issue #" + line .partition ('#' )[2 ]
1471
- # print(f( "FIXED LINE {line_number}: {line!r}") )
1442
+ # print(f"FIXED LINE {line_number}: {line!r}")
1472
1443
# else:
1473
- # print(f( "NOT FIXING LINE {line_number}: {line!r}") )
1444
+ # print(f"NOT FIXING LINE {line_number}: {line!r}")
1474
1445
1475
1446
1476
1447
# 4. determine the actual content of the line
@@ -1535,7 +1506,7 @@ def flush_version():
1535
1506
line = line [4 :]
1536
1507
parse_bpo = True
1537
1508
else :
1538
- # print(f( "[[{line_number:8} no bpo]] {line}") )
1509
+ # print(f"[[{line_number:8} no bpo]] {line}")
1539
1510
parse_bpo = False
1540
1511
if parse_bpo :
1541
1512
# GAAAH
@@ -1575,9 +1546,9 @@ def flush_version():
1575
1546
try :
1576
1547
int (bpo ) # this will throw if it's not a legal int
1577
1548
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} " )
1579
1550
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} " )
1581
1552
1582
1553
# 4.6.1 continuation of blurb
1583
1554
elif line .startswith (" " ):
@@ -1586,7 +1557,7 @@ def flush_version():
1586
1557
elif line .startswith (" * " ):
1587
1558
line = line [3 :]
1588
1559
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} " )
1590
1561
# only add blank lines if we have an initial line in the accumulator
1591
1562
if line or accumulator :
1592
1563
accumulator .append (line )
@@ -1598,7 +1569,7 @@ def flush_version():
1598
1569
git_rm_files .append ("NEWS" )
1599
1570
flush_git_rm_files ()
1600
1571
1601
- print (f ( "Wrote {blurb_count} news items across {version_count} versions." ) )
1572
+ print (f"Wrote { blurb_count } news items across { version_count } versions." )
1602
1573
print ()
1603
1574
print ("Ready for commit." )
1604
1575
@@ -1647,10 +1618,10 @@ def main():
1647
1618
def handle_option (s , dict ):
1648
1619
name = dict .get (s , None )
1649
1620
if not name :
1650
- sys .exit (f ( 'blurb: Unknown option for {subcommand}: "{s}"' ) )
1621
+ sys .exit (f'blurb: Unknown option for { subcommand } : "{ s } "' )
1651
1622
kwargs [name ] = not kwargs [name ]
1652
1623
1653
- # print(f( "short_options {short_options} long_options {long_options}") )
1624
+ # print(f"short_options {short_options} long_options {long_options}")
1654
1625
for a in args :
1655
1626
if done_with_options :
1656
1627
filtered_args .append (a )
@@ -1684,7 +1655,7 @@ def handle_option(s, dict):
1684
1655
# whoops, must be a real type error, reraise
1685
1656
raise e
1686
1657
1687
- how_many = f ( "{specified} argument" )
1658
+ how_many = f"{ specified } argument"
1688
1659
if specified != 1 :
1689
1660
how_many += "s"
1690
1661
@@ -1695,12 +1666,12 @@ def handle_option(s, dict):
1695
1666
middle = "requires"
1696
1667
else :
1697
1668
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"
1700
1671
if total != 1 :
1701
1672
middle += "s"
1702
1673
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 } .' )
1704
1675
print ()
1705
1676
print ("usage: " , end = "" )
1706
1677
help (subcommand )
0 commit comments